renet 0.1.14 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,478 @@
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
+
12
+ static enet_uint32 timeBase = 0;
13
+ static LPFN_BIND bind_ptr;
14
+ static LPFN_GETSOCKNAME getsockname_ptr;
15
+ static LPFN_LISTEN listen_ptr;
16
+ static LPFN_SOCKET socket_ptr;
17
+ static LPFN_IOCTLSOCKET ioctlsocket_ptr;
18
+ static LPFN_SETSOCKOPT setsockopt_ptr;
19
+ static LPFN_GETSOCKOPT getsockopt_ptr;
20
+ static LPFN_CONNECT connect_ptr;
21
+ static LPFN_ACCEPT accept_ptr;
22
+ static LPFN_SHUTDOWN shutdown_ptr;
23
+ static LPFN_CLOSESOCKET closesocket_ptr;
24
+ static LPFN_SELECT select_ptr;
25
+
26
+
27
+ int
28
+ enet_initialize (void)
29
+ {
30
+ WORD versionRequested = MAKEWORD (1, 1);
31
+ WSADATA wsaData;
32
+
33
+
34
+
35
+ // Internally ruby wraps the windows socket functions with it's own
36
+ // functions. These wrappers replace the socket handles that you'd
37
+ // normally work with, with a home made "file descriptor", which is
38
+ // managed internally by ruby. I'm assuming this is done to make
39
+ // the internal APIs more consistent across OSs. For an example of
40
+ // what I'm talking about, search for: "rb_w32_socket(" in
41
+ // http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_9_3/win32/win32.c
42
+ //
43
+ // Unfortunately, not only does ruby wrap the socket functions, it also
44
+ // replaces the symbols for the wrapped functions at the linker level so
45
+ // it is nearly impossible to actually use the native windows socket
46
+ // functions
47
+ // We basically have two options:
48
+ // 1. adapt enet to use the wrapped ruby socket functions
49
+ // 2. use an ugly hack to go around ruby and use the native functions
50
+ //
51
+ // I option 1 first, but ran into a couple weird bugs and
52
+ // decided this approach wasn't worth the trouble. None of these sockets
53
+ // will be touched outside of enet, so we don't need to make sure they'll
54
+ // interop nicely with other ruby code.
55
+ //
56
+ // Option 2 is super ugly, but I think will result in fewer surprises.
57
+
58
+ // Get the actual windows socket syscalls, instead of the wrapped ones provided by ruby:
59
+ bind_ptr = (LPFN_BIND) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "bind");
60
+ getsockname_ptr = (LPFN_GETSOCKNAME)GetProcAddress(GetModuleHandleA("ws2_32.dll"), "getsockname");
61
+ listen_ptr = (LPFN_LISTEN) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "listen");
62
+ socket_ptr = (LPFN_SOCKET) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "socket");
63
+ ioctlsocket_ptr = (LPFN_IOCTLSOCKET)GetProcAddress(GetModuleHandleA("ws2_32.dll"), "ioctlsocket");
64
+ setsockopt_ptr = (LPFN_SETSOCKOPT) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "setsockopt");
65
+ getsockopt_ptr = (LPFN_GETSOCKOPT) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "getsockopt");
66
+ connect_ptr = (LPFN_CONNECT) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "connect");
67
+ accept_ptr = (LPFN_ACCEPT) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "accept");
68
+ shutdown_ptr = (LPFN_SHUTDOWN) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "shutdown");
69
+ closesocket_ptr = (LPFN_CLOSESOCKET)GetProcAddress(GetModuleHandleA("ws2_32.dll"), "closesocket");
70
+ select_ptr = (LPFN_SELECT) GetProcAddress(GetModuleHandleA("ws2_32.dll"), "select");
71
+
72
+ // WSAStartup() can be called more than once in a given app, but
73
+ // must be paired with a WSACleanup()
74
+ if (WSAStartup (versionRequested, & wsaData))
75
+ return -1;
76
+
77
+ if (LOBYTE (wsaData.wVersion) != 1||
78
+ HIBYTE (wsaData.wVersion) != 1)
79
+ {
80
+ WSACleanup ();
81
+
82
+ return -1;
83
+ }
84
+
85
+ timeBeginPeriod (1);
86
+
87
+ return 0;
88
+ }
89
+
90
+ void
91
+ enet_deinitialize (void)
92
+ {
93
+ timeEndPeriod (1);
94
+
95
+ // There must be a WSACleanup() for every WSAStartup()
96
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms741549(v=vs.85).aspx
97
+ WSACleanup ();
98
+ }
99
+
100
+ enet_uint32
101
+ enet_host_random_seed (void)
102
+ {
103
+ return (enet_uint32) timeGetTime ();
104
+ }
105
+
106
+ enet_uint32
107
+ enet_time_get (void)
108
+ {
109
+ return (enet_uint32) timeGetTime () - timeBase;
110
+ }
111
+
112
+ void
113
+ enet_time_set (enet_uint32 newTimeBase)
114
+ {
115
+ timeBase = (enet_uint32) timeGetTime () - newTimeBase;
116
+ }
117
+
118
+ int
119
+ enet_address_set_host (ENetAddress * address, const char * name)
120
+ {
121
+ struct hostent * hostEntry;
122
+
123
+ hostEntry = gethostbyname (name);
124
+ if (hostEntry == NULL ||
125
+ hostEntry -> h_addrtype != AF_INET)
126
+ {
127
+ unsigned long host = inet_addr (name);
128
+ if (host == INADDR_NONE)
129
+ return -1;
130
+ address -> host = host;
131
+ return 0;
132
+ }
133
+
134
+ address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
135
+
136
+ return 0;
137
+ }
138
+
139
+ int
140
+ enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
141
+ {
142
+ char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
143
+ if (addr == NULL)
144
+ return -1;
145
+ else
146
+ {
147
+ size_t addrLen = strlen(addr);
148
+ if (addrLen >= nameLength)
149
+ return -1;
150
+ memcpy (name, addr, addrLen + 1);
151
+ }
152
+ return 0;
153
+ }
154
+
155
+ int
156
+ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
157
+ {
158
+ struct in_addr in;
159
+ struct hostent * hostEntry;
160
+
161
+ in.s_addr = address -> host;
162
+
163
+ hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
164
+ if (hostEntry == NULL)
165
+ return enet_address_get_host_ip (address, name, nameLength);
166
+ else
167
+ {
168
+ size_t hostLen = strlen (hostEntry -> h_name);
169
+ if (hostLen >= nameLength)
170
+ return -1;
171
+ memcpy (name, hostEntry -> h_name, hostLen + 1);
172
+ }
173
+
174
+ return 0;
175
+ }
176
+
177
+ int
178
+ enet_socket_bind (ENetSocket socket, const ENetAddress * address)
179
+ {
180
+ struct sockaddr_in sin;
181
+
182
+ memset (& sin, 0, sizeof (struct sockaddr_in));
183
+
184
+ sin.sin_family = AF_INET;
185
+
186
+ if (address != NULL)
187
+ {
188
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
189
+ sin.sin_addr.s_addr = address -> host;
190
+ }
191
+ else
192
+ {
193
+ sin.sin_port = 0;
194
+ sin.sin_addr.s_addr = INADDR_ANY;
195
+ }
196
+
197
+ return (*bind_ptr) (socket,
198
+ (struct sockaddr *) & sin,
199
+ sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
200
+ }
201
+
202
+ int
203
+ enet_socket_get_address (ENetSocket socket, ENetAddress * address)
204
+ {
205
+ struct sockaddr_in sin;
206
+ int sinLength = sizeof (struct sockaddr_in);
207
+
208
+ if ((*getsockname_ptr) (socket, (struct sockaddr *) & sin, & sinLength) == -1)
209
+ return -1;
210
+
211
+ address -> host = (enet_uint32) sin.sin_addr.s_addr;
212
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
213
+
214
+ return 0;
215
+ }
216
+
217
+ int
218
+ enet_socket_listen (ENetSocket socket, int backlog)
219
+ {
220
+ return (*listen_ptr) (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
221
+ }
222
+
223
+ ENetSocket
224
+ enet_socket_create (ENetSocketType type)
225
+ {
226
+ return (*socket_ptr) (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, IPPROTO_UDP);
227
+ }
228
+
229
+ int
230
+ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
231
+ {
232
+ int result = SOCKET_ERROR;
233
+ switch (option)
234
+ {
235
+ case ENET_SOCKOPT_NONBLOCK:
236
+ {
237
+ u_long nonBlocking = (u_long) value;
238
+ result = (*ioctlsocket_ptr) (socket, FIONBIO, & nonBlocking);
239
+ break;
240
+ }
241
+
242
+ case ENET_SOCKOPT_BROADCAST:
243
+ result = (*setsockopt_ptr) (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
244
+ break;
245
+
246
+ case ENET_SOCKOPT_REUSEADDR:
247
+ result = (*setsockopt_ptr) (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
248
+ break;
249
+
250
+ case ENET_SOCKOPT_RCVBUF:
251
+ result = (*setsockopt_ptr) (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
252
+ break;
253
+
254
+ case ENET_SOCKOPT_SNDBUF:
255
+ result = (*setsockopt_ptr) (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
256
+ break;
257
+
258
+ case ENET_SOCKOPT_RCVTIMEO:
259
+ result = (*setsockopt_ptr) (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int));
260
+ break;
261
+
262
+ case ENET_SOCKOPT_SNDTIMEO:
263
+ result = (*setsockopt_ptr) (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
264
+ break;
265
+
266
+ case ENET_SOCKOPT_NODELAY:
267
+ result = (*setsockopt_ptr) (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
268
+ break;
269
+
270
+ default:
271
+ break;
272
+ }
273
+ return result == SOCKET_ERROR ? -1 : 0;
274
+ }
275
+
276
+ int
277
+ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
278
+ {
279
+ int result = SOCKET_ERROR, len;
280
+ switch (option)
281
+ {
282
+ case ENET_SOCKOPT_ERROR:
283
+ len = sizeof(int);
284
+ result = (*getsockopt_ptr) (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
285
+ break;
286
+
287
+ default:
288
+ break;
289
+ }
290
+ return result == SOCKET_ERROR ? -1 : 0;
291
+ }
292
+
293
+ int
294
+ enet_socket_connect (ENetSocket socket, const ENetAddress * address)
295
+ {
296
+ struct sockaddr_in sin;
297
+ int result;
298
+
299
+ memset (& sin, 0, sizeof (struct sockaddr_in));
300
+
301
+ sin.sin_family = AF_INET;
302
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
303
+ sin.sin_addr.s_addr = address -> host;
304
+
305
+ result = (*connect_ptr) (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
306
+ if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)
307
+ return -1;
308
+
309
+ return 0;
310
+ }
311
+
312
+ ENetSocket
313
+ enet_socket_accept (ENetSocket socket, ENetAddress * address)
314
+ {
315
+ SOCKET result;
316
+ struct sockaddr_in sin;
317
+ int sinLength = sizeof (struct sockaddr_in);
318
+
319
+ result = (*accept_ptr) (socket,
320
+ address != NULL ? (struct sockaddr *) & sin : NULL,
321
+ address != NULL ? & sinLength : NULL);
322
+
323
+ if (result == INVALID_SOCKET)
324
+ return ENET_SOCKET_NULL;
325
+
326
+ if (address != NULL)
327
+ {
328
+ address -> host = (enet_uint32) sin.sin_addr.s_addr;
329
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
330
+ }
331
+
332
+ return result;
333
+ }
334
+
335
+ int
336
+ enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
337
+ {
338
+ return (*shutdown_ptr) (socket, (int) how) == SOCKET_ERROR ? -1 : 0;
339
+ }
340
+
341
+ void
342
+ enet_socket_destroy (ENetSocket socket)
343
+ {
344
+ if (socket != INVALID_SOCKET)
345
+ (*closesocket_ptr) (socket);
346
+ }
347
+
348
+ int
349
+ enet_socket_send (ENetSocket socket,
350
+ const ENetAddress * address,
351
+ const ENetBuffer * buffers,
352
+ size_t bufferCount)
353
+ {
354
+ struct sockaddr_in sin;
355
+ DWORD sentLength;
356
+
357
+ if (address != NULL)
358
+ {
359
+ memset (& sin, 0, sizeof (struct sockaddr_in));
360
+
361
+ sin.sin_family = AF_INET;
362
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
363
+ sin.sin_addr.s_addr = address -> host;
364
+ }
365
+
366
+ if (WSASendTo (socket,
367
+ (LPWSABUF) buffers,
368
+ (DWORD) bufferCount,
369
+ & sentLength,
370
+ 0,
371
+ address != NULL ? (struct sockaddr *) & sin : NULL,
372
+ address != NULL ? sizeof (struct sockaddr_in) : 0,
373
+ NULL,
374
+ NULL) == SOCKET_ERROR)
375
+ {
376
+ if (WSAGetLastError () == WSAEWOULDBLOCK)
377
+ return 0;
378
+
379
+ return -1;
380
+ }
381
+
382
+ return (int) sentLength;
383
+ }
384
+
385
+ int
386
+ enet_socket_receive (ENetSocket socket,
387
+ ENetAddress * address,
388
+ ENetBuffer * buffers,
389
+ size_t bufferCount)
390
+ {
391
+ INT sinLength = sizeof (struct sockaddr_in);
392
+ DWORD flags = 0,
393
+ recvLength;
394
+ struct sockaddr_in sin;
395
+
396
+ if (WSARecvFrom (socket,
397
+ (LPWSABUF) buffers,
398
+ (DWORD) bufferCount,
399
+ & recvLength,
400
+ & flags,
401
+ address != NULL ? (struct sockaddr *) & sin : NULL,
402
+ address != NULL ? & sinLength : NULL,
403
+ NULL,
404
+ NULL) == SOCKET_ERROR)
405
+ {
406
+ switch (WSAGetLastError ())
407
+ {
408
+ case WSAEWOULDBLOCK:
409
+ case WSAECONNRESET:
410
+ return 0;
411
+ }
412
+
413
+ return -1;
414
+ }
415
+
416
+ if (flags & MSG_PARTIAL)
417
+ return -1;
418
+
419
+ if (address != NULL)
420
+ {
421
+ address -> host = (enet_uint32) sin.sin_addr.s_addr;
422
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
423
+ }
424
+
425
+ return (int) recvLength;
426
+ }
427
+
428
+ int
429
+ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
430
+ {
431
+ struct timeval timeVal;
432
+
433
+ timeVal.tv_sec = timeout / 1000;
434
+ timeVal.tv_usec = (timeout % 1000) * 1000;
435
+
436
+ return (*select_ptr) (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
437
+ }
438
+
439
+ int
440
+ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
441
+ {
442
+ fd_set readSet, writeSet;
443
+ struct timeval timeVal;
444
+ int selectCount;
445
+
446
+ timeVal.tv_sec = timeout / 1000;
447
+ timeVal.tv_usec = (timeout % 1000) * 1000;
448
+
449
+ FD_ZERO (& readSet);
450
+ FD_ZERO (& writeSet);
451
+
452
+ if (* condition & ENET_SOCKET_WAIT_SEND)
453
+ FD_SET (socket, & writeSet);
454
+
455
+ if (* condition & ENET_SOCKET_WAIT_RECEIVE)
456
+ FD_SET (socket, & readSet);
457
+
458
+ selectCount = (*select_ptr) (socket + 1, & readSet, & writeSet, NULL, & timeVal);
459
+
460
+ if (selectCount < 0)
461
+ return -1;
462
+
463
+ * condition = ENET_SOCKET_WAIT_NONE;
464
+
465
+ if (selectCount == 0)
466
+ return 0;
467
+
468
+ if (FD_ISSET (socket, & writeSet))
469
+ * condition |= ENET_SOCKET_WAIT_SEND;
470
+
471
+ if (FD_ISSET (socket, & readSet))
472
+ * condition |= ENET_SOCKET_WAIT_RECEIVE;
473
+
474
+ return 0;
475
+ }
476
+
477
+ #endif
478
+