aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorunknown <diego.nehab@gmail.com>2013-05-28 17:27:06 +0800
committerunknown <diego.nehab@gmail.com>2013-05-28 17:27:06 +0800
commit2d51d6168874cdb2b72ee4f56f414d9a9a9d92e5 (patch)
tree788c50ccb42bd982531c62e6ede21f57655889f9 /src
parent27fd725c6d697b2e284b830ba989be2431147485 (diff)
downloadluasocket-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.c9
-rw-r--r--src/wsocket.c37
2 files changed, 27 insertions, 19 deletions
diff --git a/src/inet.c b/src/inet.c
index 1f55d2a..1c44464 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -559,12 +559,11 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
559int inet_pton(int af, const char *src, void *dst) 559int 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\*-------------------------------------------------------------------------*/
241int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { 241int 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\*-------------------------------------------------------------------------*/
265int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, 270int 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}