diff options
author | Daniel Stenberg <daniel@haxx.se> | 2021-07-05 13:28:26 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2021-07-05 22:38:13 +0200 |
commit | cffbccd0960a580fb955dd5b8ee2eb9138e40e8f (patch) | |
tree | 134d349e813bca45be6266e62bcb794817bb681a | |
parent | 2b311d369d8164e810541fb7c92658326f98b364 (diff) | |
download | curl-cffbccd0960a580fb955dd5b8ee2eb9138e40e8f.tar.gz |
socks4: scan for the IPv4 address in resolve results
Follow-up to 84d2839740 which changed the resolving to always resolve
both address families, but since SOCKS4 only supports IPv4 it should
scan for and use the first available IPv4 address.
Reported-by: shithappens2016 on github
Fixes #7345
Closes #7346
-rw-r--r-- | lib/socks.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/lib/socks.c b/lib/socks.c index 5cde4a46a..6a9ac840f 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -279,18 +279,21 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, CONNECT_RESOLVED: case CONNECT_RESOLVED: { struct Curl_addrinfo *hp = NULL; - char buf[64]; /* * We cannot use 'hostent' as a struct that Curl_resolv() returns. It * returns a Curl_addrinfo pointer that may not always look the same. */ - if(dns) + if(dns) { hp = dns->addr; - if(hp) { - Curl_printable_address(hp, buf, sizeof(buf)); - if(hp->ai_family == AF_INET) { + /* scan for the first IPv4 address */ + while(hp && (hp->ai_family != AF_INET)) + hp = hp->ai_next; + + if(hp) { struct sockaddr_in *saddr_in; + char buf[64]; + Curl_printable_address(hp, buf, sizeof(buf)); saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr; socksreq[4] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[0]; @@ -299,19 +302,18 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3]; infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf); - } - else { - hp = NULL; /* fail! */ - failf(data, "SOCKS4 connection to %s not supported", buf); - } - Curl_resolv_unlock(data, dns); /* not used anymore from now on */ + Curl_resolv_unlock(data, dns); /* not used anymore from now on */ + } + else + failf(data, "SOCKS4 connection to %s not supported", hostname); } - if(!hp) { + else failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.", hostname); + + if(!hp) return CURLPX_RESOLVE_HOST; - } } /* FALLTHROUGH */ CONNECT_REQ_INIT: |