mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 12:28:21 +01:00
Fix "final" bug in pton and TCP connreset handling
This commit is contained in:
parent
27fd725c6d
commit
2d51d61688
@ -559,12 +559,11 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
|
|||||||
int inet_pton(int af, const char *src, void *dst)
|
int inet_pton(int af, const char *src, void *dst)
|
||||||
{
|
{
|
||||||
struct addrinfo hints, *res;
|
struct addrinfo hints, *res;
|
||||||
|
int ret = 1;
|
||||||
memset(&hints, 0, sizeof(struct addrinfo));
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
hints.ai_family = af;
|
hints.ai_family = af;
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
if (getaddrinfo(src, NULL, &hints, &res) != 0) {
|
if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (af == AF_INET) {
|
if (af == AF_INET) {
|
||||||
struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr;
|
struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr;
|
||||||
memcpy(dst, &in->sin_addr, sizeof(in->sin_addr));
|
memcpy(dst, &in->sin_addr, sizeof(in->sin_addr));
|
||||||
@ -572,10 +571,10 @@ int inet_pton(int af, const char *src, void *dst)
|
|||||||
struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr;
|
struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr;
|
||||||
memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr));
|
memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr));
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,8 +238,10 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Receive with timeout
|
* Receive with timeout
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) {
|
int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
|
||||||
int err;
|
p_timeout tm)
|
||||||
|
{
|
||||||
|
int err, prev = IO_DONE;
|
||||||
*got = 0;
|
*got = 0;
|
||||||
if (*ps == SOCKET_INVALID) return IO_CLOSED;
|
if (*ps == SOCKET_INVALID) return IO_CLOSED;
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
@ -250,11 +252,14 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
|
|||||||
}
|
}
|
||||||
if (taken == 0) return IO_CLOSED;
|
if (taken == 0) return IO_CLOSED;
|
||||||
err = WSAGetLastError();
|
err = WSAGetLastError();
|
||||||
/* On Windows, and on UDP, a connreset simply means the
|
/* On UDP, a connreset simply means the previous send failed.
|
||||||
* previous send failed. On TCP, it means our socket
|
* So we try again.
|
||||||
* is now useless, so the error must pass. I am
|
* On TCP, it means our socket is now useless, so the error passes.
|
||||||
* hoping waitfd will still get the error. */
|
* (We will loop again, exiting because the same error will happen) */
|
||||||
if (err != WSAEWOULDBLOCK && err != WSAECONNRESET) return err;
|
if (err != WSAEWOULDBLOCK) {
|
||||||
|
if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
|
||||||
|
prev = err;
|
||||||
|
}
|
||||||
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
|
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,8 +268,9 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
|
|||||||
* Recvfrom with timeout
|
* Recvfrom with timeout
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
|
int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
|
||||||
SA *addr, socklen_t *len, p_timeout tm) {
|
SA *addr, socklen_t *len, p_timeout tm)
|
||||||
int err;
|
{
|
||||||
|
int err, prev = IO_DONE;
|
||||||
*got = 0;
|
*got = 0;
|
||||||
if (*ps == SOCKET_INVALID) return IO_CLOSED;
|
if (*ps == SOCKET_INVALID) return IO_CLOSED;
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
@ -275,11 +281,14 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
|
|||||||
}
|
}
|
||||||
if (taken == 0) return IO_CLOSED;
|
if (taken == 0) return IO_CLOSED;
|
||||||
err = WSAGetLastError();
|
err = WSAGetLastError();
|
||||||
/* On Windows, and on UDP, a connreset simply means the
|
/* On UDP, a connreset simply means the previous send failed.
|
||||||
* previous send failed. On TCP, it means our socket
|
* So we try again.
|
||||||
* is now useless, so the error must pass. I am
|
* On TCP, it means our socket is now useless, so the error passes.
|
||||||
* hoping waitfd will still get the error. */
|
* (We will loop again, exiting because the same error will happen) */
|
||||||
if (err != WSAEWOULDBLOCK && err != WSAECONNRESET) return err;
|
if (err != WSAEWOULDBLOCK) {
|
||||||
|
if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
|
||||||
|
prev = err;
|
||||||
|
}
|
||||||
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
|
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user