diff --git a/lib/cf-socket.c b/lib/cf-socket.c index 986294f2f0..838a3855a2 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -84,13 +84,13 @@ /* retrieves ip address and port from a sockaddr structure. note it calls - * curlx_inet_ntop() and returns CURLcode. + * curlx_inet_ntop() and optionally returns socket error. * @unittest 1607 */ UNITTEST bool sockaddr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, uint16_t *port, CURLcode *result); + char *addr, uint16_t *port, int *sockerr); UNITTEST bool sockaddr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, uint16_t *port, CURLcode *result) + char *addr, uint16_t *port, int *sockerr) { struct sockaddr_in *si = NULL; #ifdef USE_IPV6 @@ -106,7 +106,7 @@ UNITTEST bool sockaddr2string(struct sockaddr *sa, curl_socklen_t salen, case AF_INET: si = (struct sockaddr_in *)(void *)sa; if(curlx_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN, - result)) { + sockerr)) { *port = ntohs(si->sin_port); return TRUE; } @@ -115,7 +115,7 @@ UNITTEST bool sockaddr2string(struct sockaddr *sa, curl_socklen_t salen, case AF_INET6: si6 = (struct sockaddr_in6 *)(void *)sa; if(curlx_inet_ntop(sa->sa_family, &si6->sin6_addr, addr, MAX_IPADR_LEN, - result)) { + sockerr)) { *port = ntohs(si6->sin6_port); return TRUE; } @@ -130,6 +130,7 @@ UNITTEST bool sockaddr2string(struct sockaddr *sa, curl_socklen_t salen, else addr[0] = 0; /* socket with no name */ *port = 0; + *sockerr = 0; return TRUE; #endif default: @@ -138,7 +139,7 @@ UNITTEST bool sockaddr2string(struct sockaddr *sa, curl_socklen_t salen, addr[0] = '\0'; *port = 0; - *result = CURLE_UNSUPPORTED_PROTOCOL; + *sockerr = SOCKEAFNOSUPPORT; return FALSE; } @@ -1084,21 +1085,23 @@ static void set_local_ip(struct Curl_cfilter *cf, #ifdef HAVE_GETSOCKNAME if((ctx->sock != CURL_SOCKET_BAD) && !(data->conn->scheme->protocol & CURLPROTO_TFTP)) { - CURLcode result; + int sockerr; /* TFTP does not connect, so it cannot get the IP like this */ struct Curl_sockaddr_storage ssloc; curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage); + VERBOSE(char buffer[STRERROR_LEN]); memset(&ssloc, 0, sizeof(ssloc)); if(getsockname(ctx->sock, (struct sockaddr *)&ssloc, &slen)) { - VERBOSE(char buffer[STRERROR_LEN]); - VERBOSE(int sockerr = SOCKERRNO); + sockerr = SOCKERRNO; infof(data, "getsockname() failed with errno %d: %s", sockerr, curlx_strerror(sockerr, buffer, sizeof(buffer))); } else if(!sockaddr2string((struct sockaddr *)&ssloc, slen, - ctx->ip.local_ip, &ctx->ip.local_port, &result)) { - infof(data, "ssloc inet_ntop() failed with %d", (int)result); + ctx->ip.local_ip, &ctx->ip.local_port, + &sockerr)) { + infof(data, "ssloc inet_ntop() failed with errno %d: %s", + sockerr, curlx_strerror(sockerr, buffer, sizeof(buffer))); } } #else @@ -1110,19 +1113,18 @@ static CURLcode set_remote_ip(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_socket_ctx *ctx = cf->ctx; - CURLcode result; + int sockerr; /* store remote address and port used in this connection attempt */ ctx->ip.transport = ctx->transport; if(!sockaddr2string(&ctx->addr.curl_sa_addr, (curl_socklen_t)ctx->addr.addrlen, - ctx->ip.remote_ip, &ctx->ip.remote_port, &result)) { - /* using bare errno instead of SOCKERRNO is safe here, because - sockaddr2string() calls curlx_inet_ntop(), and they both report failures - via errno (even on Windows builds). */ - ctx->sockerr = errno; + ctx->ip.remote_ip, &ctx->ip.remote_port, &sockerr)) { + char buffer[STRERROR_LEN]; + ctx->sockerr = sockerr; /* malformed address or bug in inet_ntop, try next address */ - failf(data, "curl_sa_addr inet_ntop() failed with %d", (int)result); + failf(data, "curl_sa_addr inet_ntop() failed with errno %d: %s", + sockerr, curlx_strerror(sockerr, buffer, sizeof(buffer))); return CURLE_FAILED_INIT; } return CURLE_OK; @@ -2105,7 +2107,8 @@ static void cf_tcp_set_accepted_remote_ip(struct Curl_cfilter *cf, { struct cf_socket_ctx *ctx = cf->ctx; #ifdef HAVE_GETPEERNAME - CURLcode result; + char buffer[STRERROR_LEN]; + int sockerr; struct Curl_sockaddr_storage ssrem; curl_socklen_t plen; @@ -2114,15 +2117,15 @@ static void cf_tcp_set_accepted_remote_ip(struct Curl_cfilter *cf, plen = sizeof(ssrem); memset(&ssrem, 0, plen); if(getpeername(ctx->sock, (struct sockaddr *)&ssrem, &plen)) { - char buffer[STRERROR_LEN]; - int sockerr = SOCKERRNO; + sockerr = SOCKERRNO; failf(data, "getpeername() failed with errno %d: %s", sockerr, curlx_strerror(sockerr, buffer, sizeof(buffer))); return; } if(!sockaddr2string((struct sockaddr *)&ssrem, plen, - ctx->ip.remote_ip, &ctx->ip.remote_port, &result)) { - failf(data, "ssrem inet_ntop() failed with %d", (int)result); + ctx->ip.remote_ip, &ctx->ip.remote_port, &sockerr)) { + failf(data, "ssrem inet_ntop() failed with errno %d: %s", + sockerr, curlx_strerror(sockerr, buffer, sizeof(buffer))); return; } #else diff --git a/lib/curlx/inet_ntop.c b/lib/curlx/inet_ntop.c index b975325dd2..62a1a84c59 100644 --- a/lib/curlx/inet_ntop.c +++ b/lib/curlx/inet_ntop.c @@ -54,7 +54,7 @@ * - takes an unsigned char* not an in_addr as input */ static char *inet_ntop4(const unsigned char *src, char *dst, size_t size, - CURLcode *result) + int *sockerr) { char tmp[sizeof("255.255.255.255")]; size_t len; @@ -70,12 +70,12 @@ static char *inet_ntop4(const unsigned char *src, char *dst, size_t size, len = strlen(tmp); if(len == 0 || len >= size) { - if(result) - *result = CURLE_BAD_FUNCTION_ARGUMENT; + if(sockerr) + *sockerr = SOCKEINVAL; return NULL; } - if(result) - *result = CURLE_OK; + if(sockerr) + *sockerr = 0; curlx_strcopy(dst, size, tmp, len); return dst; } @@ -84,7 +84,7 @@ static char *inet_ntop4(const unsigned char *src, char *dst, size_t size, * Convert IPv6 binary address into presentation (printable) format. */ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size, - CURLcode *result) + int *sockerr) { /* * Note that int32_t and int16_t need only be "at least" large enough @@ -153,7 +153,7 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size, */ if(i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { - if(!inet_ntop4(src + 12, tp, sizeof(tmp) - (tp - tmp), result)) { + if(!inet_ntop4(src + 12, tp, sizeof(tmp) - (tp - tmp), sockerr)) { return NULL; } tp += strlen(tp); @@ -183,12 +183,12 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size, /* Check for overflow, copy, and we are done. */ if((size_t)(tp - tmp) >= size) { - if(result) - *result = CURLE_BAD_FUNCTION_ARGUMENT; + if(sockerr) + *sockerr = SOCKEINVAL; return NULL; } - if(result) - *result = CURLE_OK; + if(sockerr) + *sockerr = 0; curlx_strcopy(dst, size, tmp, tp - tmp); return dst; } @@ -198,19 +198,19 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size, * * Returns pointer to presentation format address (`buf'). * Returns NULL on error and errno set with the specific - * error, EAFNOSUPPORT or ENOSPC. + * error, SOCKEAFNOSUPPORT or SOCKEINVAL. */ char *curlx_inet_ntop(int af, const void *src, char *buf, size_t size, - CURLcode *result) + int *sockerr) { switch(af) { case AF_INET: - return inet_ntop4((const unsigned char *)src, buf, size, result); + return inet_ntop4((const unsigned char *)src, buf, size, sockerr); case AF_INET6: - return inet_ntop6((const unsigned char *)src, buf, size, result); + return inet_ntop6((const unsigned char *)src, buf, size, sockerr); default: - if(result) - *result = CURLE_UNSUPPORTED_PROTOCOL; + if(sockerr) + *sockerr = SOCKEAFNOSUPPORT; return NULL; } } diff --git a/lib/curlx/inet_ntop.h b/lib/curlx/inet_ntop.h index 6dfae295f4..421a14036a 100644 --- a/lib/curlx/inet_ntop.h +++ b/lib/curlx/inet_ntop.h @@ -26,6 +26,6 @@ #include "curl_setup.h" char *curlx_inet_ntop(int af, const void *src, char *buf, size_t size, - CURLcode *result); + int *sockerr); #endif /* HEADER_CURL_INET_NTOP_H */ diff --git a/tests/unit/unit1607.c b/tests/unit/unit1607.c index 51b651707e..f234588466 100644 --- a/tests/unit/unit1607.c +++ b/tests/unit/unit1607.c @@ -140,7 +140,7 @@ static CURLcode test_unit1607(const char *arg) for(j = 0; j < addressnum; ++j) { uint16_t port = 0; char ipaddress[MAX_IPADR_LEN] = { 0 }; - CURLcode result; + int sockerr; if(!addr && !tests[i].address[j]) break; @@ -149,7 +149,7 @@ static CURLcode test_unit1607(const char *arg) continue; if(addr && !sockaddr2string(addr->ai_addr, addr->ai_addrlen, - ipaddress, &port, &result)) { + ipaddress, &port, &sockerr)) { curl_mfprintf(stderr, "%s:%d tests[%zu] failed. " "getaddressinfo failed.\n", __FILE__, __LINE__, i); diff --git a/tests/unit/unit1609.c b/tests/unit/unit1609.c index 1ed1734074..614170b946 100644 --- a/tests/unit/unit1609.c +++ b/tests/unit/unit1609.c @@ -142,13 +142,13 @@ static CURLcode test_unit1609(const char *arg) for(j = 0; j < addressnum; ++j) { uint16_t port = 0; char ipaddress[MAX_IPADR_LEN] = { 0 }; - CURLcode result; + int sockerr; if(!addr && !tests[i].address[j]) break; if(addr && !sockaddr2string(addr->ai_addr, addr->ai_addrlen, - ipaddress, &port, &result)) { + ipaddress, &port, &sockerr)) { curl_mfprintf(stderr, "%s:%d tests[%zu] failed. Curl_addr2string failed.\n", __FILE__, __LINE__, i);