1 /**
2  @file  win32.c
3  @brief ENet Win32 system specific functions
4 */
5 #ifdef WIN32
6 
7 #include <time.h>
8 #define ENET_BUILDING_LIB 1
9 #include "enet/enet.h"
10 
11 static enet_uint32 timeBase = 0;
12 
13 int
enet_initialize(void)14 enet_initialize (void)
15 {
16     WORD versionRequested = MAKEWORD (1, 1);
17     WSADATA wsaData;
18 
19     if (WSAStartup (versionRequested, & wsaData))
20        return -1;
21 
22     if (LOBYTE (wsaData.wVersion) != 1||
23         HIBYTE (wsaData.wVersion) != 1)
24     {
25        WSACleanup ();
26 
27        return -1;
28     }
29 
30     timeBeginPeriod (1);
31 
32     return 0;
33 }
34 
35 void
enet_deinitialize(void)36 enet_deinitialize (void)
37 {
38     timeEndPeriod (1);
39 
40     WSACleanup ();
41 }
42 
43 enet_uint32
enet_time_get(void)44 enet_time_get (void)
45 {
46     return (enet_uint32) timeGetTime () - timeBase;
47 }
48 
49 void
enet_time_set(enet_uint32 newTimeBase)50 enet_time_set (enet_uint32 newTimeBase)
51 {
52     timeBase = (enet_uint32) timeGetTime () - newTimeBase;
53 }
54 
55 int
enet_address_set_host(ENetAddress * address,const char * name)56 enet_address_set_host (ENetAddress * address, const char * name)
57 {
58     struct hostent * hostEntry;
59 
60     hostEntry = gethostbyname (name);
61     if (hostEntry == NULL ||
62         hostEntry -> h_addrtype != AF_INET)
63     {
64         unsigned long host = inet_addr (name);
65         if (host == INADDR_NONE)
66             return -1;
67         address -> host = host;
68         return 0;
69     }
70 
71     address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
72 
73     return 0;
74 }
75 
76 int
enet_address_get_host_ip(const ENetAddress * address,char * name,size_t nameLength)77 enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
78 {
79     char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
80     if (addr == NULL)
81         return -1;
82     strncpy (name, addr, nameLength);
83     return 0;
84 }
85 
86 int
enet_address_get_host(const ENetAddress * address,char * name,size_t nameLength)87 enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
88 {
89     struct in_addr in;
90     struct hostent * hostEntry;
91 
92     in.s_addr = address -> host;
93 
94     hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
95     if (hostEntry == NULL)
96       return enet_address_get_host_ip (address, name, nameLength);
97 
98     strncpy (name, hostEntry -> h_name, nameLength);
99 
100     return 0;
101 }
102 
103 int
enet_socket_bind(ENetSocket socket,const ENetAddress * address)104 enet_socket_bind (ENetSocket socket, const ENetAddress * address)
105 {
106     struct sockaddr_in sin;
107 
108     memset (& sin, 0, sizeof (struct sockaddr_in));
109 
110     sin.sin_family = AF_INET;
111 
112     if (address != NULL)
113     {
114        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
115        sin.sin_addr.s_addr = address -> host;
116     }
117     else
118     {
119        sin.sin_port = 0;
120        sin.sin_addr.s_addr = INADDR_ANY;
121     }
122 
123     return bind (socket,
124                  (struct sockaddr *) & sin,
125                  sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
126 }
127 
128 int
enet_socket_listen(ENetSocket socket,int backlog)129 enet_socket_listen (ENetSocket socket, int backlog)
130 {
131     return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
132 }
133 
134 ENetSocket
enet_socket_create(ENetSocketType type)135 enet_socket_create (ENetSocketType type)
136 {
137     return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
138 }
139 
140 int
enet_socket_set_option(ENetSocket socket,ENetSocketOption option,int value)141 enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
142 {
143     int result = SOCKET_ERROR;
144     switch (option)
145     {
146         case ENET_SOCKOPT_NONBLOCK:
147         {
148             u_long nonBlocking = (u_long) value;
149             result = ioctlsocket (socket, FIONBIO, & nonBlocking);
150             break;
151         }
152 
153         case ENET_SOCKOPT_BROADCAST:
154             result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
155             break;
156 
157         case ENET_SOCKOPT_REUSEADDR:
158             result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
159             break;
160 
161         case ENET_SOCKOPT_RCVBUF:
162             result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
163             break;
164 
165         case ENET_SOCKOPT_SNDBUF:
166             result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
167             break;
168 
169         default:
170             break;
171     }
172     return result == SOCKET_ERROR ? -1 : 0;
173 }
174 
175 int
enet_socket_connect(ENetSocket socket,const ENetAddress * address)176 enet_socket_connect (ENetSocket socket, const ENetAddress * address)
177 {
178     struct sockaddr_in sin;
179 
180     memset (& sin, 0, sizeof (struct sockaddr_in));
181 
182     sin.sin_family = AF_INET;
183     sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
184     sin.sin_addr.s_addr = address -> host;
185 
186     return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
187 }
188 
189 ENetSocket
enet_socket_accept(ENetSocket socket,ENetAddress * address)190 enet_socket_accept (ENetSocket socket, ENetAddress * address)
191 {
192     SOCKET result;
193     struct sockaddr_in sin;
194     int sinLength = sizeof (struct sockaddr_in);
195 
196     result = accept (socket,
197                      address != NULL ? (struct sockaddr *) & sin : NULL,
198                      address != NULL ? & sinLength : NULL);
199 
200     if (result == INVALID_SOCKET)
201       return ENET_SOCKET_NULL;
202 
203     if (address != NULL)
204     {
205         address -> host = (enet_uint32) sin.sin_addr.s_addr;
206         address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
207     }
208 
209     return result;
210 }
211 
212 void
enet_socket_destroy(ENetSocket socket)213 enet_socket_destroy (ENetSocket socket)
214 {
215     closesocket (socket);
216 }
217 
218 int
enet_socket_send(ENetSocket socket,const ENetAddress * address,const ENetBuffer * buffers,size_t bufferCount)219 enet_socket_send (ENetSocket socket,
220                   const ENetAddress * address,
221                   const ENetBuffer * buffers,
222                   size_t bufferCount)
223 {
224     struct sockaddr_in sin;
225     DWORD sentLength;
226 
227     if (address != NULL)
228     {
229         memset (& sin, 0, sizeof (struct sockaddr_in));
230 
231         sin.sin_family = AF_INET;
232         sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
233         sin.sin_addr.s_addr = address -> host;
234     }
235 
236     if (WSASendTo (socket,
237                    (LPWSABUF) buffers,
238                    (DWORD) bufferCount,
239                    & sentLength,
240                    0,
241                    address != NULL ? (struct sockaddr *) & sin : 0,
242                    address != NULL ? sizeof (struct sockaddr_in) : 0,
243                    NULL,
244                    NULL) == SOCKET_ERROR)
245     {
246        if (WSAGetLastError () == WSAEWOULDBLOCK)
247          return 0;
248 
249        return -1;
250     }
251 
252     return (int) sentLength;
253 }
254 
255 int
enet_socket_receive(ENetSocket socket,ENetAddress * address,ENetBuffer * buffers,size_t bufferCount)256 enet_socket_receive (ENetSocket socket,
257                      ENetAddress * address,
258                      ENetBuffer * buffers,
259                      size_t bufferCount)
260 {
261     INT sinLength = sizeof (struct sockaddr_in);
262     DWORD flags = 0,
263           recvLength;
264     struct sockaddr_in sin;
265 
266     if (WSARecvFrom (socket,
267                      (LPWSABUF) buffers,
268                      (DWORD) bufferCount,
269                      & recvLength,
270                      & flags,
271                      address != NULL ? (struct sockaddr *) & sin : NULL,
272                      address != NULL ? & sinLength : NULL,
273                      NULL,
274                      NULL) == SOCKET_ERROR)
275     {
276        switch (WSAGetLastError ())
277        {
278        case WSAEWOULDBLOCK:
279        case WSAECONNRESET:
280           return 0;
281        }
282 
283        return -1;
284     }
285 
286     if (flags & MSG_PARTIAL)
287       return -1;
288 
289     if (address != NULL)
290     {
291         address -> host = (enet_uint32) sin.sin_addr.s_addr;
292         address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
293     }
294 
295     return (int) recvLength;
296 }
297 
298 int
enet_socketset_select(ENetSocket maxSocket,ENetSocketSet * readSet,ENetSocketSet * writeSet,enet_uint32 timeout)299 enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
300 {
301     struct timeval timeVal;
302 
303     timeVal.tv_sec = timeout / 1000;
304     timeVal.tv_usec = (timeout % 1000) * 1000;
305 
306     return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
307 }
308 
309 int
enet_socket_wait(ENetSocket socket,enet_uint32 * condition,enet_uint32 timeout)310 enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
311 {
312     fd_set readSet, writeSet;
313     struct timeval timeVal;
314     int selectCount;
315 
316     timeVal.tv_sec = timeout / 1000;
317     timeVal.tv_usec = (timeout % 1000) * 1000;
318 
319     FD_ZERO (& readSet);
320     FD_ZERO (& writeSet);
321 
322     if (* condition & ENET_SOCKET_WAIT_SEND)
323       FD_SET (socket, & writeSet);
324 
325     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
326       FD_SET (socket, & readSet);
327 
328     selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
329 
330     if (selectCount < 0)
331       return -1;
332 
333     * condition = ENET_SOCKET_WAIT_NONE;
334 
335     if (selectCount == 0)
336       return 0;
337 
338     if (FD_ISSET (socket, & writeSet))
339       * condition |= ENET_SOCKET_WAIT_SEND;
340 
341     if (FD_ISSET (socket, & readSet))
342       * condition |= ENET_SOCKET_WAIT_RECEIVE;
343 
344     return 0;
345 }
346 
347 #endif
348 
349