renet 0.1.14 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+