diff options
author | unknown <diego.nehab@gmail.com> | 2013-05-28 00:09:30 +0800 |
---|---|---|
committer | unknown <diego.nehab@gmail.com> | 2013-05-28 00:09:30 +0800 |
commit | 734cc23e1f03372314ebad07ffd35117c152afcd (patch) | |
tree | 808531d9c0c84aae57657aff353b08d466a3dcfb /src/inet.c | |
parent | 66cd8cfcee1f14b59450147c16a6bc44ef298edc (diff) | |
download | luasocket-734cc23e1f03372314ebad07ffd35117c152afcd.tar.gz luasocket-734cc23e1f03372314ebad07ffd35117c152afcd.tar.bz2 luasocket-734cc23e1f03372314ebad07ffd35117c152afcd.zip |
Fixed inet_pton and a new Winsock UDP bug.
inet_pton was copying the entire sockaddr_in struct,
rather than just the sin_addr field...
I am a bit unsure about the UDP fix, because it may affect
TCP as well. On UDP sockets, when a sendto fails, the next
receive/receivefrom fails with CONNRESET. I changed
sock_recv/sock_recvfrom in wsocket.c to skip the CONNRESET
from the recv/recvfrom, hoping that if the socket is TCP,
sock_waitfd will get the CONNRESET again. The tests pass,
but this should be tested more thoroughly.
Diffstat (limited to 'src/inet.c')
-rw-r--r-- | src/inet.c | 17 |
1 files changed, 11 insertions, 6 deletions
@@ -558,18 +558,23 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) | |||
558 | 558 | ||
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, *ressave; | 561 | struct addrinfo hints, *res; |
562 | memset(&hints, 0, sizeof(struct addrinfo)); | 562 | memset(&hints, 0, sizeof(struct addrinfo)); |
563 | hints.ai_family = af; | 563 | hints.ai_family = af; |
564 | hints.ai_flags = AI_NUMERICHOST; | ||
564 | if (getaddrinfo(src, NULL, &hints, &res) != 0) { | 565 | if (getaddrinfo(src, NULL, &hints, &res) != 0) { |
565 | return -1; | 566 | return -1; |
566 | } | 567 | } |
567 | ressave = res; | 568 | if (af == AF_INET) { |
568 | while (res) { | 569 | struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; |
569 | memcpy(dst, res->ai_addr, res->ai_addrlen); | 570 | memcpy(dst, &in->sin_addr, sizeof(in->sin_addr)); |
570 | res = res->ai_next; | 571 | } else if (af == AF_INET6) { |
572 | struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; | ||
573 | memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr)); | ||
574 | } else { | ||
575 | return -1; | ||
571 | } | 576 | } |
572 | freeaddrinfo(ressave); | 577 | freeaddrinfo(res); |
573 | return 0; | 578 | return 0; |
574 | } | 579 | } |
575 | 580 | ||