aboutsummaryrefslogtreecommitdiff
path: root/src/wsocket.c
diff options
context:
space:
mode:
authorDiego Nehab <diego.nehab@gmail.com>2015-08-21 15:39:34 -0300
committerDiego Nehab <diego.nehab@gmail.com>2015-08-21 15:39:34 -0300
commite75444ccd1f30a3b5fbc7cec4a85e831bd0560ed (patch)
tree71475c18fee070c770fc0fe25d0859b7d54c8fbb /src/wsocket.c
parent321c0c9b1f7b6b83cd83b58e7e259f53eca69373 (diff)
downloadluasocket-e75444ccd1f30a3b5fbc7cec4a85e831bd0560ed.tar.gz
luasocket-e75444ccd1f30a3b5fbc7cec4a85e831bd0560ed.tar.bz2
luasocket-e75444ccd1f30a3b5fbc7cec4a85e831bd0560ed.zip
New compat.h module implements luaL_setfuncs.
Makes initialization code simpler everywhere.
Diffstat (limited to 'src/wsocket.c')
-rw-r--r--src/wsocket.c82
1 files changed, 41 insertions, 41 deletions
diff --git a/src/wsocket.c b/src/wsocket.c
index 10800e3..8ecb0fc 100644
--- a/src/wsocket.c
+++ b/src/wsocket.c
@@ -3,7 +3,7 @@
3* LuaSocket toolkit 3* LuaSocket toolkit
4* 4*
5* The penalty of calling select to avoid busy-wait is only paid when 5* The penalty of calling select to avoid busy-wait is only paid when
6* the I/O call fail in the first place. 6* the I/O call fail in the first place.
7\*=========================================================================*/ 7\*=========================================================================*/
8#include <string.h> 8#include <string.h>
9 9
@@ -14,23 +14,23 @@
14static const char *wstrerror(int err); 14static const char *wstrerror(int err);
15 15
16/*-------------------------------------------------------------------------*\ 16/*-------------------------------------------------------------------------*\
17* Initializes module 17* Initializes module
18\*-------------------------------------------------------------------------*/ 18\*-------------------------------------------------------------------------*/
19int socket_open(void) { 19int socket_open(void) {
20 WSADATA wsaData; 20 WSADATA wsaData;
21 WORD wVersionRequested = MAKEWORD(2, 0); 21 WORD wVersionRequested = MAKEWORD(2, 0);
22 int err = WSAStartup(wVersionRequested, &wsaData ); 22 int err = WSAStartup(wVersionRequested, &wsaData );
23 if (err != 0) return 0; 23 if (err != 0) return 0;
24 if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) && 24 if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) &&
25 (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) { 25 (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) {
26 WSACleanup(); 26 WSACleanup();
27 return 0; 27 return 0;
28 } 28 }
29 return 1; 29 return 1;
30} 30}
31 31
32/*-------------------------------------------------------------------------*\ 32/*-------------------------------------------------------------------------*\
33* Close module 33* Close module
34\*-------------------------------------------------------------------------*/ 34\*-------------------------------------------------------------------------*/
35int socket_close(void) { 35int socket_close(void) {
36 WSACleanup(); 36 WSACleanup();
@@ -51,10 +51,10 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
51 struct timeval tv, *tp = NULL; 51 struct timeval tv, *tp = NULL;
52 double t; 52 double t;
53 if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ 53 if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
54 if (sw & WAITFD_R) { 54 if (sw & WAITFD_R) {
55 FD_ZERO(&rfds); 55 FD_ZERO(&rfds);
56 FD_SET(*ps, &rfds); 56 FD_SET(*ps, &rfds);
57 rp = &rfds; 57 rp = &rfds;
58 } 58 }
59 if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } 59 if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
60 if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; } 60 if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
@@ -73,9 +73,9 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
73/*-------------------------------------------------------------------------*\ 73/*-------------------------------------------------------------------------*\
74* Select with int timeout in ms 74* Select with int timeout in ms
75\*-------------------------------------------------------------------------*/ 75\*-------------------------------------------------------------------------*/
76int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, 76int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
77 p_timeout tm) { 77 p_timeout tm) {
78 struct timeval tv; 78 struct timeval tv;
79 double t = timeout_get(tm); 79 double t = timeout_get(tm);
80 tv.tv_sec = (int) t; 80 tv.tv_sec = (int) t;
81 tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); 81 tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
@@ -97,7 +97,7 @@ void socket_destroy(p_socket ps) {
97} 97}
98 98
99/*-------------------------------------------------------------------------*\ 99/*-------------------------------------------------------------------------*\
100* 100*
101\*-------------------------------------------------------------------------*/ 101\*-------------------------------------------------------------------------*/
102void socket_shutdown(p_socket ps, int how) { 102void socket_shutdown(p_socket ps, int how) {
103 socket_setblocking(ps); 103 socket_setblocking(ps);
@@ -135,10 +135,10 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
135 /* give windows time to set the error (yes, disgusting) */ 135 /* give windows time to set the error (yes, disgusting) */
136 Sleep(10); 136 Sleep(10);
137 /* find out why we failed */ 137 /* find out why we failed */
138 getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); 138 getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
139 /* we KNOW there was an error. if 'why' is 0, we will return 139 /* we KNOW there was an error. if 'why' is 0, we will return
140 * "unknown error", but it's not really our fault */ 140 * "unknown error", but it's not really our fault */
141 return err > 0? err: IO_UNKNOWN; 141 return err > 0? err: IO_UNKNOWN;
142 } else return err; 142 } else return err;
143 143
144} 144}
@@ -155,7 +155,7 @@ int socket_bind(p_socket ps, SA *addr, socklen_t len) {
155} 155}
156 156
157/*-------------------------------------------------------------------------*\ 157/*-------------------------------------------------------------------------*\
158* 158*
159\*-------------------------------------------------------------------------*/ 159\*-------------------------------------------------------------------------*/
160int socket_listen(p_socket ps, int backlog) { 160int socket_listen(p_socket ps, int backlog) {
161 int err = IO_DONE; 161 int err = IO_DONE;
@@ -168,7 +168,7 @@ int socket_listen(p_socket ps, int backlog) {
168/*-------------------------------------------------------------------------*\ 168/*-------------------------------------------------------------------------*\
169* Accept with timeout 169* Accept with timeout
170\*-------------------------------------------------------------------------*/ 170\*-------------------------------------------------------------------------*/
171int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, 171int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
172 p_timeout tm) { 172 p_timeout tm) {
173 if (*ps == SOCKET_INVALID) return IO_CLOSED; 173 if (*ps == SOCKET_INVALID) return IO_CLOSED;
174 for ( ;; ) { 174 for ( ;; ) {
@@ -176,21 +176,21 @@ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
176 /* try to get client socket */ 176 /* try to get client socket */
177 if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; 177 if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
178 /* find out why we failed */ 178 /* find out why we failed */
179 err = WSAGetLastError(); 179 err = WSAGetLastError();
180 /* if we failed because there was no connectoin, keep trying */ 180 /* if we failed because there was no connectoin, keep trying */
181 if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err; 181 if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err;
182 /* call select to avoid busy wait */ 182 /* call select to avoid busy wait */
183 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; 183 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
184 } 184 }
185} 185}
186 186
187/*-------------------------------------------------------------------------*\ 187/*-------------------------------------------------------------------------*\
188* Send with timeout 188* Send with timeout
189* On windows, if you try to send 10MB, the OS will buffer EVERYTHING 189* On windows, if you try to send 10MB, the OS will buffer EVERYTHING
190* this can take an awful lot of time and we will end up blocked. 190* this can take an awful lot of time and we will end up blocked.
191* Therefore, whoever calls this function should not pass a huge buffer. 191* Therefore, whoever calls this function should not pass a huge buffer.
192\*-------------------------------------------------------------------------*/ 192\*-------------------------------------------------------------------------*/
193int socket_send(p_socket ps, const char *data, size_t count, 193int socket_send(p_socket ps, const char *data, size_t count,
194 size_t *sent, p_timeout tm) 194 size_t *sent, p_timeout tm)
195{ 195{
196 int err; 196 int err;
@@ -207,18 +207,18 @@ int socket_send(p_socket ps, const char *data, size_t count,
207 return IO_DONE; 207 return IO_DONE;
208 } 208 }
209 /* deal with failure */ 209 /* deal with failure */
210 err = WSAGetLastError(); 210 err = WSAGetLastError();
211 /* we can only proceed if there was no serious error */ 211 /* we can only proceed if there was no serious error */
212 if (err != WSAEWOULDBLOCK) return err; 212 if (err != WSAEWOULDBLOCK) return err;
213 /* avoid busy wait */ 213 /* avoid busy wait */
214 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; 214 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
215 } 215 }
216} 216}
217 217
218/*-------------------------------------------------------------------------*\ 218/*-------------------------------------------------------------------------*\
219* Sendto with timeout 219* Sendto with timeout
220\*-------------------------------------------------------------------------*/ 220\*-------------------------------------------------------------------------*/
221int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, 221int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
222 SA *addr, socklen_t len, p_timeout tm) 222 SA *addr, socklen_t len, p_timeout tm)
223{ 223{
224 int err; 224 int err;
@@ -230,17 +230,17 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
230 *sent = put; 230 *sent = put;
231 return IO_DONE; 231 return IO_DONE;
232 } 232 }
233 err = WSAGetLastError(); 233 err = WSAGetLastError();
234 if (err != WSAEWOULDBLOCK) return err; 234 if (err != WSAEWOULDBLOCK) return err;
235 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; 235 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
236 } 236 }
237} 237}
238 238
239/*-------------------------------------------------------------------------*\ 239/*-------------------------------------------------------------------------*\
240* Receive with timeout 240* Receive with timeout
241\*-------------------------------------------------------------------------*/ 241\*-------------------------------------------------------------------------*/
242int socket_recv(p_socket ps, char *data, size_t count, size_t *got, 242int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
243 p_timeout tm) 243 p_timeout tm)
244{ 244{
245 int err, prev = IO_DONE; 245 int err, prev = IO_DONE;
246 *got = 0; 246 *got = 0;
@@ -253,9 +253,9 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
253 } 253 }
254 if (taken == 0) return IO_CLOSED; 254 if (taken == 0) return IO_CLOSED;
255 err = WSAGetLastError(); 255 err = WSAGetLastError();
256 /* On UDP, a connreset simply means the previous send failed. 256 /* On UDP, a connreset simply means the previous send failed.
257 * So we try again. 257 * So we try again.
258 * On TCP, it means our socket is now useless, so the error passes. 258 * On TCP, it means our socket is now useless, so the error passes.
259 * (We will loop again, exiting because the same error will happen) */ 259 * (We will loop again, exiting because the same error will happen) */
260 if (err != WSAEWOULDBLOCK) { 260 if (err != WSAEWOULDBLOCK) {
261 if (err != WSAECONNRESET || prev == WSAECONNRESET) return err; 261 if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
@@ -268,8 +268,8 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
268/*-------------------------------------------------------------------------*\ 268/*-------------------------------------------------------------------------*\
269* Recvfrom with timeout 269* Recvfrom with timeout
270\*-------------------------------------------------------------------------*/ 270\*-------------------------------------------------------------------------*/
271int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, 271int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
272 SA *addr, socklen_t *len, p_timeout tm) 272 SA *addr, socklen_t *len, p_timeout tm)
273{ 273{
274 int err, prev = IO_DONE; 274 int err, prev = IO_DONE;
275 *got = 0; 275 *got = 0;
@@ -282,8 +282,8 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
282 } 282 }
283 if (taken == 0) return IO_CLOSED; 283 if (taken == 0) return IO_CLOSED;
284 err = WSAGetLastError(); 284 err = WSAGetLastError();
285 /* On UDP, a connreset simply means the previous send failed. 285 /* On UDP, a connreset simply means the previous send failed.
286 * So we try again. 286 * So we try again.
287 * On TCP, it means our socket is now useless, so the error passes. 287 * On TCP, it means our socket is now useless, so the error passes.
288 * (We will loop again, exiting because the same error will happen) */ 288 * (We will loop again, exiting because the same error will happen) */
289 if (err != WSAEWOULDBLOCK) { 289 if (err != WSAEWOULDBLOCK) {
@@ -311,7 +311,7 @@ void socket_setnonblocking(p_socket ps) {
311} 311}
312 312
313/*-------------------------------------------------------------------------*\ 313/*-------------------------------------------------------------------------*\
314* DNS helpers 314* DNS helpers
315\*-------------------------------------------------------------------------*/ 315\*-------------------------------------------------------------------------*/
316int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { 316int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
317 *hp = gethostbyaddr(addr, len, AF_INET); 317 *hp = gethostbyaddr(addr, len, AF_INET);
@@ -332,7 +332,7 @@ const char *socket_hoststrerror(int err) {
332 if (err <= 0) return io_strerror(err); 332 if (err <= 0) return io_strerror(err);
333 switch (err) { 333 switch (err) {
334 case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; 334 case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND;
335 default: return wstrerror(err); 335 default: return wstrerror(err);
336 } 336 }
337} 337}
338 338
@@ -374,7 +374,7 @@ static const char *wstrerror(int err) {
374 case WSAESOCKTNOSUPPORT: return PIE_SOCKTYPE; // "Socket type not supported"; 374 case WSAESOCKTNOSUPPORT: return PIE_SOCKTYPE; // "Socket type not supported";
375 case WSAEOPNOTSUPP: return "Operation not supported"; 375 case WSAEOPNOTSUPP: return "Operation not supported";
376 case WSAEPFNOSUPPORT: return "Protocol family not supported"; 376 case WSAEPFNOSUPPORT: return "Protocol family not supported";
377 case WSAEAFNOSUPPORT: return PIE_FAMILY; // "Address family not supported by protocol family"; 377 case WSAEAFNOSUPPORT: return PIE_FAMILY; // "Address family not supported by protocol family";
378 case WSAEADDRINUSE: return PIE_ADDRINUSE; // "Address already in use"; 378 case WSAEADDRINUSE: return PIE_ADDRINUSE; // "Address already in use";
379 case WSAEADDRNOTAVAIL: return "Cannot assign requested address"; 379 case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
380 case WSAENETDOWN: return "Network is down"; 380 case WSAENETDOWN: return "Network is down";
@@ -393,19 +393,19 @@ static const char *wstrerror(int err) {
393 case WSAEPROCLIM: return "Too many processes"; 393 case WSAEPROCLIM: return "Too many processes";
394 case WSASYSNOTREADY: return "Network subsystem is unavailable"; 394 case WSASYSNOTREADY: return "Network subsystem is unavailable";
395 case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range"; 395 case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range";
396 case WSANOTINITIALISED: 396 case WSANOTINITIALISED:
397 return "Successful WSAStartup not yet performed"; 397 return "Successful WSAStartup not yet performed";
398 case WSAEDISCON: return "Graceful shutdown in progress"; 398 case WSAEDISCON: return "Graceful shutdown in progress";
399 case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; // "Host not found"; 399 case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; // "Host not found";
400 case WSATRY_AGAIN: return "Nonauthoritative host not found"; 400 case WSATRY_AGAIN: return "Nonauthoritative host not found";
401 case WSANO_RECOVERY: return PIE_FAIL; // "Nonrecoverable name lookup error"; 401 case WSANO_RECOVERY: return PIE_FAIL; // "Nonrecoverable name lookup error";
402 case WSANO_DATA: return "Valid name, no data record of requested type"; 402 case WSANO_DATA: return "Valid name, no data record of requested type";
403 default: return "Unknown error"; 403 default: return "Unknown error";
404 } 404 }
405} 405}
406 406
407const char *socket_gaistrerror(int err) { 407const char *socket_gaistrerror(int err) {
408 if (err == 0) return NULL; 408 if (err == 0) return NULL;
409 switch (err) { 409 switch (err) {
410 case EAI_AGAIN: return PIE_AGAIN; 410 case EAI_AGAIN: return PIE_AGAIN;
411 case EAI_BADFLAGS: return PIE_BADFLAGS; 411 case EAI_BADFLAGS: return PIE_BADFLAGS;
@@ -425,7 +425,7 @@ const char *socket_gaistrerror(int err) {
425 case EAI_SERVICE: return PIE_SERVICE; 425 case EAI_SERVICE: return PIE_SERVICE;
426 case EAI_SOCKTYPE: return PIE_SOCKTYPE; 426 case EAI_SOCKTYPE: return PIE_SOCKTYPE;
427#ifdef EAI_SYSTEM 427#ifdef EAI_SYSTEM
428 case EAI_SYSTEM: return strerror(errno); 428 case EAI_SYSTEM: return strerror(errno);
429#endif 429#endif
430 default: return gai_strerror(err); 430 default: return gai_strerror(err);
431 } 431 }