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