diff options
author | unknown <diego.nehab@gmail.com> | 2013-05-28 17:27:06 +0800 |
---|---|---|
committer | unknown <diego.nehab@gmail.com> | 2013-05-28 17:27:06 +0800 |
commit | 2d51d6168874cdb2b72ee4f56f414d9a9a9d92e5 (patch) | |
tree | 788c50ccb42bd982531c62e6ede21f57655889f9 /src | |
parent | 27fd725c6d697b2e284b830ba989be2431147485 (diff) | |
download | luasocket-2d51d6168874cdb2b72ee4f56f414d9a9a9d92e5.tar.gz luasocket-2d51d6168874cdb2b72ee4f56f414d9a9a9d92e5.tar.bz2 luasocket-2d51d6168874cdb2b72ee4f56f414d9a9a9d92e5.zip |
Fix "final" bug in pton and TCP connreset handling
Diffstat (limited to 'src')
-rw-r--r-- | src/inet.c | 9 | ||||
-rw-r--r-- | src/wsocket.c | 37 |
2 files changed, 27 insertions, 19 deletions
@@ -559,12 +559,11 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) | |||
559 | int inet_pton(int af, const char *src, void *dst) | 559 | int inet_pton(int af, const char *src, void *dst) |
560 | { | 560 | { |
561 | struct addrinfo hints, *res; | 561 | struct addrinfo hints, *res; |
562 | int ret = 1; | ||
562 | memset(&hints, 0, sizeof(struct addrinfo)); | 563 | memset(&hints, 0, sizeof(struct addrinfo)); |
563 | hints.ai_family = af; | 564 | hints.ai_family = af; |
564 | hints.ai_flags = AI_NUMERICHOST; | 565 | hints.ai_flags = AI_NUMERICHOST; |
565 | if (getaddrinfo(src, NULL, &hints, &res) != 0) { | 566 | if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1; |
566 | return -1; | ||
567 | } | ||
568 | if (af == AF_INET) { | 567 | if (af == AF_INET) { |
569 | struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; | 568 | struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; |
570 | memcpy(dst, &in->sin_addr, sizeof(in->sin_addr)); | 569 | memcpy(dst, &in->sin_addr, sizeof(in->sin_addr)); |
@@ -572,10 +571,10 @@ int inet_pton(int af, const char *src, void *dst) | |||
572 | struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; | 571 | struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; |
573 | memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr)); | 572 | memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr)); |
574 | } else { | 573 | } else { |
575 | return -1; | 574 | ret = -1; |
576 | } | 575 | } |
577 | freeaddrinfo(res); | 576 | freeaddrinfo(res); |
578 | return 0; | 577 | return ret; |
579 | } | 578 | } |
580 | 579 | ||
581 | #endif | 580 | #endif |
diff --git a/src/wsocket.c b/src/wsocket.c index d34724b..b4a4384 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
@@ -238,8 +238,10 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, | |||
238 | /*-------------------------------------------------------------------------*\ | 238 | /*-------------------------------------------------------------------------*\ |
239 | * Receive with timeout | 239 | * Receive with timeout |
240 | \*-------------------------------------------------------------------------*/ | 240 | \*-------------------------------------------------------------------------*/ |
241 | int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { | 241 | int socket_recv(p_socket ps, char *data, size_t count, size_t *got, |
242 | int err; | 242 | p_timeout tm) |
243 | { | ||
244 | int err, prev = IO_DONE; | ||
243 | *got = 0; | 245 | *got = 0; |
244 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | 246 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
245 | for ( ;; ) { | 247 | for ( ;; ) { |
@@ -250,11 +252,14 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm | |||
250 | } | 252 | } |
251 | if (taken == 0) return IO_CLOSED; | 253 | if (taken == 0) return IO_CLOSED; |
252 | err = WSAGetLastError(); | 254 | err = WSAGetLastError(); |
253 | /* On Windows, and on UDP, a connreset simply means the | 255 | /* On UDP, a connreset simply means the previous send failed. |
254 | * previous send failed. On TCP, it means our socket | 256 | * So we try again. |
255 | * is now useless, so the error must pass. I am | 257 | * On TCP, it means our socket is now useless, so the error passes. |
256 | * hoping waitfd will still get the error. */ | 258 | * (We will loop again, exiting because the same error will happen) */ |
257 | if (err != WSAEWOULDBLOCK && err != WSAECONNRESET) return err; | 259 | if (err != WSAEWOULDBLOCK) { |
260 | if (err != WSAECONNRESET || prev == WSAECONNRESET) return err; | ||
261 | prev = err; | ||
262 | } | ||
258 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; | 263 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; |
259 | } | 264 | } |
260 | } | 265 | } |
@@ -263,8 +268,9 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm | |||
263 | * Recvfrom with timeout | 268 | * Recvfrom with timeout |
264 | \*-------------------------------------------------------------------------*/ | 269 | \*-------------------------------------------------------------------------*/ |
265 | int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | 270 | int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, |
266 | SA *addr, socklen_t *len, p_timeout tm) { | 271 | SA *addr, socklen_t *len, p_timeout tm) |
267 | int err; | 272 | { |
273 | int err, prev = IO_DONE; | ||
268 | *got = 0; | 274 | *got = 0; |
269 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | 275 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
270 | for ( ;; ) { | 276 | for ( ;; ) { |
@@ -275,11 +281,14 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | |||
275 | } | 281 | } |
276 | if (taken == 0) return IO_CLOSED; | 282 | if (taken == 0) return IO_CLOSED; |
277 | err = WSAGetLastError(); | 283 | err = WSAGetLastError(); |
278 | /* On Windows, and on UDP, a connreset simply means the | 284 | /* On UDP, a connreset simply means the previous send failed. |
279 | * previous send failed. On TCP, it means our socket | 285 | * So we try again. |
280 | * is now useless, so the error must pass. I am | 286 | * On TCP, it means our socket is now useless, so the error passes. |
281 | * hoping waitfd will still get the error. */ | 287 | * (We will loop again, exiting because the same error will happen) */ |
282 | if (err != WSAEWOULDBLOCK && err != WSAECONNRESET) return err; | 288 | if (err != WSAEWOULDBLOCK) { |
289 | if (err != WSAECONNRESET || prev == WSAECONNRESET) return err; | ||
290 | prev = err; | ||
291 | } | ||
283 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; | 292 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; |
284 | } | 293 | } |
285 | } | 294 | } |