diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2023-11-11 22:28:44 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2023-11-11 22:43:33 +0300 |
commit | 175ec788d14db88a2fafb920c8b5117209c12d5b (patch) | |
tree | 5ff4a7d314ce3887c5df8f051d83866edd585ac1 /contrib/libs/curl/lib/socketpair.c | |
parent | b6c20a8a26d0be34045f2604b4da1ee189920ed2 (diff) | |
download | ydb-175ec788d14db88a2fafb920c8b5117209c12d5b.tar.gz |
Update contrib/libs/curl to 8.2.1
Diffstat (limited to 'contrib/libs/curl/lib/socketpair.c')
-rw-r--r-- | contrib/libs/curl/lib/socketpair.c | 88 |
1 files changed, 71 insertions, 17 deletions
diff --git a/contrib/libs/curl/lib/socketpair.c b/contrib/libs/curl/lib/socketpair.c index 0f8798f087..963e1406f6 100644 --- a/contrib/libs/curl/lib/socketpair.c +++ b/contrib/libs/curl/lib/socketpair.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2019 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,6 +24,8 @@ #include "curl_setup.h" #include "socketpair.h" +#include "urldata.h" +#include "rand.h" #if !defined(HAVE_SOCKETPAIR) && !defined(CURL_DISABLE_SOCKETPAIR) #ifdef WIN32 @@ -65,7 +67,7 @@ int Curl_socketpair(int domain, int type, int protocol, union { struct sockaddr_in inaddr; struct sockaddr addr; - } a, a2; + } a; curl_socket_t listener; curl_socklen_t addrlen = sizeof(a.inaddr); int reuse = 1; @@ -85,9 +87,22 @@ int Curl_socketpair(int domain, int type, int protocol, socks[0] = socks[1] = CURL_SOCKET_BAD; +#if defined(WIN32) || defined(__CYGWIN__) + /* don't set SO_REUSEADDR on Windows */ + (void)reuse; +#ifdef SO_EXCLUSIVEADDRUSE + { + int exclusive = 1; + if(setsockopt(listener, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, + (char *)&exclusive, (curl_socklen_t)sizeof(exclusive)) == -1) + goto error; + } +#endif +#else if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, (curl_socklen_t)sizeof(reuse)) == -1) goto error; +#endif if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1) goto error; if(getsockname(listener, &a.addr, &addrlen) == -1 || @@ -107,29 +122,68 @@ int Curl_socketpair(int domain, int type, int protocol, pfd[0].fd = listener; pfd[0].events = POLLIN; pfd[0].revents = 0; - (void)Curl_poll(pfd, 1, 10*1000); /* 10 seconds */ + (void)Curl_poll(pfd, 1, 1000); /* one second */ socks[1] = accept(listener, NULL, NULL); if(socks[1] == CURL_SOCKET_BAD) goto error; + else { + struct curltime start = Curl_now(); + char rnd[9]; + char check[sizeof(rnd)]; + char *p = &check[0]; + size_t s = sizeof(check); - /* verify that nothing else connected */ - addrlen = sizeof(a.inaddr); - if(getsockname(socks[0], &a.addr, &addrlen) == -1 || - addrlen < (int)sizeof(a.inaddr)) - goto error; - addrlen = sizeof(a2.inaddr); - if(getpeername(socks[1], &a2.addr, &addrlen) == -1 || - addrlen < (int)sizeof(a2.inaddr)) - goto error; - 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; + if(Curl_rand(NULL, (unsigned char *)rnd, sizeof(rnd))) + goto error; + + /* write data to the socket */ + swrite(socks[0], rnd, sizeof(rnd)); + /* verify that we read the correct data */ + do { + ssize_t nread; + + pfd[0].fd = socks[1]; + pfd[0].events = POLLIN; + pfd[0].revents = 0; + (void)Curl_poll(pfd, 1, 1000); /* one second */ + + nread = sread(socks[1], p, s); + if(nread == -1) { + int sockerr = SOCKERRNO; + /* Don't block forever */ + if(Curl_timediff(Curl_now(), start) > (60 * 1000)) + goto error; + if( +#ifdef WSAEWOULDBLOCK + /* This is how Windows does it */ + (WSAEWOULDBLOCK == sockerr) +#else + /* errno may be EWOULDBLOCK or on some systems EAGAIN when it + returned due to its inability to send off data without + blocking. We therefore treat both error codes the same here */ + (EWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || + (EINTR == sockerr) || (EINPROGRESS == sockerr) +#endif + ) { + continue; + } + goto error; + } + s -= nread; + if(s) { + p += nread; + continue; + } + if(memcmp(rnd, check, sizeof(check))) + goto error; + break; + } while(1); + } sclose(listener); return 0; - error: +error: sclose(listener); sclose(socks[0]); sclose(socks[1]); |