1 module async.net.tcpstream;
2 
3 import std.socket;
4 import std.datetime;
5 
6 abstract class TcpStream
7 {
8     this(Socket socket)
9     {
10         _socket = socket;
11         version (Windows) { } else _socket.blocking = false;
12 
13         setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, 60.seconds);
14         setOption(SocketOptionLevel.SOCKET, SocketOption.SNDTIMEO, 60.seconds);
15     }
16 
17     @property bool reusePort()
18     {
19         return _reusePort;
20     }
21 
22     @property bool reusePort(bool enabled)
23     {
24         _reusePort = enabled;
25 
26         _socket.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, _reusePort);
27 
28         version (Posix)
29         {
30             import core.sys.posix.sys.socket;
31             _socket.setOption(SocketOptionLevel.SOCKET, cast(SocketOption)SO_REUSEPORT, _reusePort);
32         }
33 
34         version (Windows)
35         {
36             if (!_reusePort)
37             {
38                 import core.sys.windows.winsock2;
39                 _socket.setOption(SocketOptionLevel.SOCKET, cast(SocketOption)SO_EXCLUSIVEADDRUSE, true);
40             }
41         }
42 
43         return _reusePort;
44     }
45 
46     @property bool blocking()
47     {
48         return _blocking;
49     }
50 
51     @property bool blocking(bool enabled)
52     {
53         _blocking        = enabled;
54         _socket.blocking = _blocking;
55 
56         return _blocking;
57     }
58 
59     @property int fd()
60     {
61         return cast(int) (_socket.handle());
62     }
63 
64     @property Address remoteAddress()
65     {
66         return _socket.remoteAddress();
67     }
68 
69     @property Address localAddress()
70     {
71         return _socket.localAddress();
72     }
73 
74     @property bool isAlive()
75     {
76         return _socket.isAlive();
77     }
78 
79     int getOption(SocketOptionLevel level, SocketOption option, void[] result) @trusted
80     {
81         return _socket.getOption(level, option, result);
82     }
83 
84     int getOption(SocketOptionLevel level, SocketOption option, out int result) @trusted
85     {
86         return _socket.getOption(level, option, result);
87     }
88 
89     int getOption(SocketOptionLevel level, SocketOption option, out Linger result) @trusted
90     {
91         return _socket.getOption(level, option, result);
92     }
93 
94     void getOption(SocketOptionLevel level, SocketOption option, out Duration result) @trusted
95     {
96         return _socket.getOption(level, option, result);
97     }
98 
99     void setOption(SocketOptionLevel level, SocketOption option, void[] value) @trusted
100     {
101         _socket.setOption(level, option, value);
102     }
103 
104     void setOption(SocketOptionLevel level, SocketOption option, int value) @trusted
105     {
106         _socket.setOption(level, option, value);
107     }
108 
109     void setOption(SocketOptionLevel level, SocketOption option, Linger value) @trusted
110     {
111         _socket.setOption(level, option, value);
112     }
113 
114     void setOption(SocketOptionLevel level, SocketOption option, Duration value) @trusted
115     {
116         _socket.setOption(level, option, value);
117     }
118 
119     void setKeepAlive(int time, int interval) @trusted
120     {
121         _socket.setKeepAlive(time, interval);
122     }
123 
124 protected:
125 
126     Socket _socket;
127 
128     bool _reusePort = false;
129     bool _blocking  = false;
130 }