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