diff options
Diffstat (limited to 'libs/libcurl/src/cf-socket.c')
-rw-r--r-- | libs/libcurl/src/cf-socket.c | 135 |
1 files changed, 58 insertions, 77 deletions
diff --git a/libs/libcurl/src/cf-socket.c b/libs/libcurl/src/cf-socket.c index e552120b31..b40bd05801 100644 --- a/libs/libcurl/src/cf-socket.c +++ b/libs/libcurl/src/cf-socket.c @@ -82,7 +82,9 @@ #include "rand.h"
#include "share.h"
#include "strdup.h"
+#include "system_win32.h"
#include "version_win32.h"
+#include "strparse.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -113,8 +115,8 @@ static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd) int level = IPPROTO_TCP;
char buffer[STRERROR_LEN];
- if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
- sizeof(onoff)) < 0)
+ if(setsockopt(sockfd, level, TCP_NODELAY,
+ (void *)&onoff, sizeof(onoff)) < 0)
infof(data, "Could not set TCP_NODELAY: %s",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
#else
@@ -133,8 +135,8 @@ static void nosigpipe(struct Curl_easy *data, {
int onoff = 1;
(void)data;
- if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
- sizeof(onoff)) < 0) {
+ if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE,
+ (void *)&onoff, sizeof(onoff)) < 0) {
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
char buffer[STRERROR_LEN];
infof(data, "Could not set SO_NOSIGPIPE: %s",
@@ -181,7 +183,7 @@ tcpkeepalive(struct Curl_easy *data, /* only set IDLE and INTVL if setting KEEPALIVE is successful */
if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
- (void *)&optval, sizeof(optval)) < 0) {
+ (void *)&optval, sizeof(optval)) < 0) {
infof(data, "Failed to set SO_KEEPALIVE on fd "
"%" FMT_SOCKET_T ": errno %d",
sockfd, SOCKERRNO);
@@ -234,7 +236,7 @@ tcpkeepalive(struct Curl_easy *data, optval = curlx_sltosi(data->set.tcp_keepidle);
KEEPALIVE_FACTOR(optval);
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
- (void *)&optval, sizeof(optval)) < 0) {
+ (void *)&optval, sizeof(optval)) < 0) {
infof(data, "Failed to set TCP_KEEPIDLE on fd "
"%" FMT_SOCKET_T ": errno %d",
sockfd, SOCKERRNO);
@@ -244,7 +246,7 @@ tcpkeepalive(struct Curl_easy *data, optval = curlx_sltosi(data->set.tcp_keepidle);
KEEPALIVE_FACTOR(optval);
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
- (void *)&optval, sizeof(optval)) < 0) {
+ (void *)&optval, sizeof(optval)) < 0) {
infof(data, "Failed to set TCP_KEEPALIVE on fd "
"%" FMT_SOCKET_T ": errno %d",
sockfd, SOCKERRNO);
@@ -254,7 +256,7 @@ tcpkeepalive(struct Curl_easy *data, optval = curlx_sltosi(data->set.tcp_keepidle);
KEEPALIVE_FACTOR(optval);
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
- (void *)&optval, sizeof(optval)) < 0) {
+ (void *)&optval, sizeof(optval)) < 0) {
infof(data, "Failed to set TCP_KEEPALIVE_THRESHOLD on fd "
"%" FMT_SOCKET_T ": errno %d",
sockfd, SOCKERRNO);
@@ -264,7 +266,7 @@ tcpkeepalive(struct Curl_easy *data, optval = curlx_sltosi(data->set.tcp_keepintvl);
KEEPALIVE_FACTOR(optval);
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
- (void *)&optval, sizeof(optval)) < 0) {
+ (void *)&optval, sizeof(optval)) < 0) {
infof(data, "Failed to set TCP_KEEPINTVL on fd "
"%" FMT_SOCKET_T ": errno %d",
sockfd, SOCKERRNO);
@@ -285,7 +287,7 @@ tcpkeepalive(struct Curl_easy *data, curlx_sltosi(data->set.tcp_keepintvl);
KEEPALIVE_FACTOR(optval);
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD,
- (void *)&optval, sizeof(optval)) < 0) {
+ (void *)&optval, sizeof(optval)) < 0) {
infof(data, "Failed to set TCP_KEEPALIVE_ABORT_THRESHOLD on fd "
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
}
@@ -293,7 +295,7 @@ tcpkeepalive(struct Curl_easy *data, #ifdef TCP_KEEPCNT
optval = curlx_sltosi(data->set.tcp_keepcnt);
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT,
- (void *)&optval, sizeof(optval)) < 0) {
+ (void *)&optval, sizeof(optval)) < 0) {
infof(data, "Failed to set TCP_KEEPCNT on fd "
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
}
@@ -420,7 +422,7 @@ static int socket_close(struct Curl_easy *data, struct connectdata *conn, if(use_callback && conn && conn->fclosesocket) {
int rc;
- Curl_multi_closed(data, sock);
+ Curl_multi_will_close(data, sock);
Curl_set_in_callback(data, TRUE);
rc = conn->fclosesocket(conn->closesocket_client, sock);
Curl_set_in_callback(data, FALSE);
@@ -429,7 +431,7 @@ static int socket_close(struct Curl_easy *data, struct connectdata *conn, if(conn)
/* tell the multi-socket code about this */
- Curl_multi_closed(data, sock);
+ Curl_multi_will_close(data, sock);
sclose(sock);
@@ -460,9 +462,6 @@ int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn, Windows. Following function trying to detect OS version and skips
SO_SNDBUF adjustment for Windows Vista and above.
*/
-#define DETECT_OS_NONE 0
-#define DETECT_OS_PREVISTA 1
-#define DETECT_OS_VISTA_OR_LATER 2
void Curl_sndbuf_init(curl_socket_t sockfd)
{
@@ -470,17 +469,7 @@ void Curl_sndbuf_init(curl_socket_t sockfd) int curval = 0;
int curlen = sizeof(curval);
- static int detectOsState = DETECT_OS_NONE;
-
- if(detectOsState == DETECT_OS_NONE) {
- if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
- VERSION_GREATER_THAN_EQUAL))
- detectOsState = DETECT_OS_VISTA_OR_LATER;
- else
- detectOsState = DETECT_OS_PREVISTA;
- }
-
- if(detectOsState == DETECT_OS_VISTA_OR_LATER)
+ if(Curl_isVistaOrGreater)
return;
if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
@@ -732,7 +721,7 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn, if(scope_ptr)
*(scope_ptr++) = '\0';
#endif
- if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
+ if(curlx_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
si6->sin6_family = AF_INET6;
si6->sin6_port = htons(port);
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
@@ -741,10 +730,10 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn, Curl_printable_address. The latter returns only numeric scope
IDs and the former returns none at all. So the scope ID, if
present, is known to be numeric */
- unsigned long scope_id = strtoul(scope_ptr, NULL, 10);
- if(scope_id > UINT_MAX)
+ curl_off_t scope_id;
+ if(Curl_str_number((const char **)CURL_UNCONST(&scope_ptr),
+ &scope_id, UINT_MAX))
return CURLE_UNSUPPORTED_PROTOCOL;
-
si6->sin6_scope_id = (unsigned int)scope_id;
}
#endif
@@ -755,7 +744,7 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn, #endif
/* IPv4 address */
if((af == AF_INET) &&
- (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
+ (curlx_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
si4->sin_family = AF_INET;
si4->sin_port = htons(port);
sizeof_sa = sizeof(struct sockaddr_in);
@@ -855,7 +844,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) * Someone got to verify this on Win-NT 4.0, 2000."
*/
-#ifdef _WIN32_WCE
+#ifdef UNDER_CE
Sleep(0);
#else
SleepEx(0, FALSE);
@@ -865,7 +854,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize))
err = SOCKERRNO;
-#ifdef _WIN32_WCE
+#ifdef UNDER_CE
/* Old Windows CE versions do not support SO_ERROR */
if(WSAENOPROTOOPT == err) {
SET_SOCKERRNO(0);
@@ -879,7 +868,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) err = 0;
}
#endif
- if((0 == err) || (EISCONN == err))
+ if((0 == err) || (SOCKEISCONN == err))
/* we are connected, awesome! */
rc = TRUE;
else
@@ -902,10 +891,10 @@ static CURLcode socket_connect_result(struct Curl_easy *data, const char *ipaddress, int error)
{
switch(error) {
- case EINPROGRESS:
- case EWOULDBLOCK:
+ case SOCKEINPROGRESS:
+ case SOCKEWOULDBLOCK:
#if defined(EAGAIN)
-#if (EAGAIN) != (EWOULDBLOCK)
+#if (EAGAIN) != (SOCKEWOULDBLOCK)
/* On some platforms EAGAIN and EWOULDBLOCK are the
* same value, and on others they are different, hence
* the odd #if
@@ -932,15 +921,6 @@ static CURLcode socket_connect_result(struct Curl_easy *data, }
}
-/* We have a recv buffer to enhance reads with len < NW_SMALL_READS.
- * This happens often on TLS connections where the TLS implementation
- * tries to read the head of a TLS record, determine the length of the
- * full record and then make a subsequent read for that.
- * On large reads, we will not fill the buffer to avoid the double copy. */
-#define NW_RECV_CHUNK_SIZE (64 * 1024)
-#define NW_RECV_CHUNKS 1
-#define NW_SMALL_READS (1024)
-
struct cf_socket_ctx {
int transport;
struct Curl_sockaddr_ex addr; /* address to connect to */
@@ -983,28 +963,28 @@ static CURLcode cf_socket_ctx_init(struct cf_socket_ctx *ctx, #ifdef DEBUGBUILD
{
- char *p = getenv("CURL_DBG_SOCK_WBLOCK");
+ const char *p = getenv("CURL_DBG_SOCK_WBLOCK");
if(p) {
- long l = strtol(p, NULL, 10);
- if(l >= 0 && l <= 100)
+ curl_off_t l;
+ if(!Curl_str_number(&p, &l, 100))
ctx->wblock_percent = (int)l;
}
p = getenv("CURL_DBG_SOCK_WPARTIAL");
if(p) {
- long l = strtol(p, NULL, 10);
- if(l >= 0 && l <= 100)
+ curl_off_t l;
+ if(!Curl_str_number(&p, &l, 100))
ctx->wpartial_percent = (int)l;
}
p = getenv("CURL_DBG_SOCK_RBLOCK");
if(p) {
- long l = strtol(p, NULL, 10);
- if(l >= 0 && l <= 100)
+ curl_off_t l;
+ if(!Curl_str_number(&p, &l, 100))
ctx->rblock_percent = (int)l;
}
p = getenv("CURL_DBG_SOCK_RMAX");
if(p) {
- long l = strtol(p, NULL, 10);
- if(l >= 0)
+ curl_off_t l;
+ if(!Curl_str_number(&p, &l, CURL_OFF_T_MAX))
ctx->recv_max = (size_t)l;
}
}
@@ -1018,7 +998,7 @@ static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data) struct cf_socket_ctx *ctx = cf->ctx;
if(ctx && CURL_SOCKET_BAD != ctx->sock) {
- CURL_TRC_CF(data, cf, "cf_socket_close(%" FMT_SOCKET_T ")", ctx->sock);
+ CURL_TRC_CF(data, cf, "cf_socket_close, fd=%" FMT_SOCKET_T, ctx->sock);
if(ctx->sock == cf->conn->sock[cf->sockindex])
cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD;
socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
@@ -1040,7 +1020,7 @@ static CURLcode cf_socket_shutdown(struct Curl_cfilter *cf, if(cf->connected) {
struct cf_socket_ctx *ctx = cf->ctx;
- CURL_TRC_CF(data, cf, "cf_socket_shutdown(%" FMT_SOCKET_T ")", ctx->sock);
+ CURL_TRC_CF(data, cf, "cf_socket_shutdown, fd=%" FMT_SOCKET_T, ctx->sock);
/* On TCP, and when the socket looks well and non-blocking mode
* can be enabled, receive dangling bytes before close to avoid
* entering RST states unnecessarily. */
@@ -1313,7 +1293,7 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data, static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
- bool blocking, bool *done)
+ bool *done)
{
struct cf_socket_ctx *ctx = cf->ctx;
CURLcode result = CURLE_COULDNT_CONNECT;
@@ -1325,9 +1305,6 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf, return CURLE_OK;
}
- if(blocking)
- return CURLE_UNSUPPORTED_PROTOCOL;
-
*done = FALSE; /* a negative world view is best */
if(ctx->sock == CURL_SOCKET_BAD) {
int error;
@@ -1538,15 +1515,16 @@ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, int sockerr = SOCKERRNO;
if(
-#ifdef WSAEWOULDBLOCK
+#ifdef USE_WINSOCK
/* This is how Windows does it */
- (WSAEWOULDBLOCK == sockerr)
+ (SOCKEWOULDBLOCK == 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)
+ (SOCKEWOULDBLOCK == sockerr) ||
+ (EAGAIN == sockerr) || (SOCKEINTR == sockerr) ||
+ (SOCKEINPROGRESS == sockerr)
#endif
) {
/* this is just a case of EWOULDBLOCK */
@@ -1606,14 +1584,15 @@ static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, int sockerr = SOCKERRNO;
if(
-#ifdef WSAEWOULDBLOCK
+#ifdef USE_WINSOCK
/* This is how Windows does it */
- (WSAEWOULDBLOCK == sockerr)
+ (SOCKEWOULDBLOCK == 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)
+ (SOCKEWOULDBLOCK == sockerr) ||
+ (EAGAIN == sockerr) || (SOCKEINTR == sockerr)
#endif
) {
/* this is just a case of EWOULDBLOCK */
@@ -1849,7 +1828,9 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, /* QUIC needs a connected socket, nonblocking */
DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD);
- rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, /* NOLINT */
+ /* error: The 1st argument to 'connect' is -1 but should be >= 0
+ NOLINTNEXTLINE(clang-analyzer-unix.StdCLibraryFunctions) */
+ rc = connect(ctx->sock, &ctx->addr.curl_sa_addr,
(curl_socklen_t)ctx->addr.addrlen);
if(-1 == rc) {
return socket_connect_result(data, ctx->ip.remote_ip, SOCKERRNO);
@@ -1867,8 +1848,9 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, * non-blocking socket created by cf_socket_open() to it. Thus, we
* do not need to call curlx_nonblock() in cf_udp_setup_quic() anymore.
*/
+#ifdef __linux__
switch(ctx->addr.family) {
-#if defined(__linux__) && defined(IP_MTU_DISCOVER)
+#ifdef IP_MTU_DISCOVER
case AF_INET: {
int val = IP_PMTUDISC_DO;
(void)setsockopt(ctx->sock, IPPROTO_IP, IP_MTU_DISCOVER, &val,
@@ -1876,7 +1858,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, break;
}
#endif
-#if defined(__linux__) && defined(IPV6_MTU_DISCOVER)
+#ifdef IPV6_MTU_DISCOVER
case AF_INET6: {
int val = IPV6_PMTUDISC_DO;
(void)setsockopt(ctx->sock, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val,
@@ -1886,24 +1868,24 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, #endif
}
-#if defined(__linux__) && defined(UDP_GRO) && \
+#if defined(UDP_GRO) && \
(defined(HAVE_SENDMMSG) || defined(HAVE_SENDMSG)) && \
((defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || defined(USE_QUICHE))
(void)setsockopt(ctx->sock, IPPROTO_UDP, UDP_GRO, &one,
(socklen_t)sizeof(one));
#endif
+#endif
return CURLE_OK;
}
static CURLcode cf_udp_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
- bool blocking, bool *done)
+ bool *done)
{
struct cf_socket_ctx *ctx = cf->ctx;
CURLcode result = CURLE_COULDNT_CONNECT;
- (void)blocking;
if(cf->connected) {
*done = TRUE;
return CURLE_OK;
@@ -2108,7 +2090,7 @@ static void cf_tcp_set_accepted_remote_ip(struct Curl_cfilter *cf, static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
- bool blocking, bool *done)
+ bool *done)
{
struct cf_socket_ctx *ctx = cf->ctx;
#ifdef USE_IPV6
@@ -2124,7 +2106,6 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf, /* we start accepted, if we ever close, we cannot go on */
(void)data;
- (void)blocking;
if(cf->connected) {
*done = TRUE;
return CURLE_OK;
|