1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-25 17:48:48 -05:00

Revert "Revert "socketpair: fix potential hangs""

This reverts commit 3e70c3430a.

Thus brings back the change from #7144 as was originally landed in
c769d1eab4

Closes #7144 (again)
This commit is contained in:
Daniel Stenberg 2021-06-05 12:57:28 +02:00
parent 68d388061c
commit 0a51355556
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -48,6 +48,10 @@
#endif /* !INADDR_LOOPBACK */ #endif /* !INADDR_LOOPBACK */
#endif /* !WIN32 */ #endif /* !WIN32 */
#include "nonblock.h" /* for curlx_nonblock */
#include "timeval.h" /* needed before select.h */
#include "select.h" /* for Curl_poll */
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
#include "curl_printf.h" #include "curl_printf.h"
#include "curl_memory.h" #include "curl_memory.h"
@ -59,12 +63,11 @@ int Curl_socketpair(int domain, int type, int protocol,
union { union {
struct sockaddr_in inaddr; struct sockaddr_in inaddr;
struct sockaddr addr; struct sockaddr addr;
} a; } a, a2;
curl_socket_t listener; curl_socket_t listener;
curl_socklen_t addrlen = sizeof(a.inaddr); curl_socklen_t addrlen = sizeof(a.inaddr);
int reuse = 1; int reuse = 1;
char data[2][12]; struct pollfd pfd[1];
ssize_t dlen;
(void)domain; (void)domain;
(void)type; (void)type;
(void)protocol; (void)protocol;
@ -85,7 +88,8 @@ int Curl_socketpair(int domain, int type, int protocol,
goto error; goto error;
if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1) if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1)
goto error; goto error;
if(getsockname(listener, &a.addr, &addrlen) == -1) if(getsockname(listener, &a.addr, &addrlen) == -1 ||
addrlen < (int)sizeof(a.inaddr))
goto error; goto error;
if(listen(listener, 1) == -1) if(listen(listener, 1) == -1)
goto error; goto error;
@ -94,18 +98,30 @@ int Curl_socketpair(int domain, int type, int protocol,
goto error; goto error;
if(connect(socks[0], &a.addr, sizeof(a.inaddr)) == -1) if(connect(socks[0], &a.addr, sizeof(a.inaddr)) == -1)
goto error; goto error;
/* use non-blocking accept to make sure we don't block forever */
if(curlx_nonblock(listener, TRUE) < 0)
goto error;
pfd[0].fd = listener;
pfd[0].events = POLLIN;
pfd[0].revents = 0;
(void)Curl_poll(pfd, 1, 10*1000); /* 10 seconds */
socks[1] = accept(listener, NULL, NULL); socks[1] = accept(listener, NULL, NULL);
if(socks[1] == CURL_SOCKET_BAD) if(socks[1] == CURL_SOCKET_BAD)
goto error; goto error;
/* verify that nothing else connected */ /* verify that nothing else connected */
msnprintf(data[0], sizeof(data[0]), "%p", socks); addrlen = sizeof(a.inaddr);
dlen = strlen(data[0]); if(getsockname(socks[0], &a.addr, &addrlen) == -1 ||
if(swrite(socks[0], data[0], dlen) != dlen) addrlen < (int)sizeof(a.inaddr))
goto error; goto error;
if(sread(socks[1], data[1], sizeof(data[1])) != dlen) addrlen = sizeof(a2.inaddr);
if(getpeername(socks[1], &a2.addr, &addrlen) == -1 ||
addrlen < (int)sizeof(a2.inaddr))
goto error; goto error;
if(memcmp(data[0], data[1], dlen)) if(a.inaddr.sin_family != a2.inaddr.sin_family ||
a.inaddr.sin_addr.s_addr != a2.inaddr.sin_addr.s_addr ||
a.inaddr.sin_port != a2.inaddr.sin_port)
goto error; goto error;
sclose(listener); sclose(listener);