diff options
author | Daniel Stenberg <daniel@haxx.se> | 2020-06-08 14:05:22 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-06-08 23:19:36 +0200 |
commit | 2a41e236716da4c41ebc1132bd36d9273bd0321f (patch) | |
tree | 5a11722ac44a0911745b6c8b4f8b371fc222de4e | |
parent | 0a35580e210df6a0548c114665f201ecd759eadd (diff) |
socks: detect connection close during handshake
The SOCKS4/5 state machines weren't properly terminated when the proxy
connection got closed, leading to a busy-loop.
Reported-By: zloi-user on github
Fixes #5532
Closes #5542
-rw-r--r-- | lib/socks.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/lib/socks.c b/lib/socks.c index 4c1af7b9d..b2215fef3 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -382,6 +382,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user, curl_easy_strerror(result)); return CURLE_COULDNT_CONNECT; } + else if(!result && !actualread) { + /* connection closed */ + failf(data, "connection to proxy closed"); + return CURLE_COULDNT_CONNECT; + } else if(actualread != sx->outstanding) { /* remain in reading state */ sx->outstanding -= actualread; @@ -592,6 +597,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user, failf(data, "Unable to receive initial SOCKS5 response."); return CURLE_COULDNT_CONNECT; } + else if(!result && !actualread) { + /* connection closed */ + failf(data, "Connection to proxy closed"); + return CURLE_COULDNT_CONNECT; + } else if(actualread != sx->outstanding) { /* remain in reading state */ sx->outstanding -= actualread; @@ -717,15 +727,19 @@ CURLcode Curl_SOCKS5(const char *proxy_user, failf(data, "Unable to receive SOCKS5 sub-negotiation response."); return CURLE_COULDNT_CONNECT; } - if(actualread != sx->outstanding) { + else if(!result && !actualread) { + /* connection closed */ + failf(data, "connection to proxy closed"); + return CURLE_COULDNT_CONNECT; + } + else if(actualread != sx->outstanding) { /* remain in state */ sx->outstanding -= actualread; sx->outp += actualread; return CURLE_OK; } - /* ignore the first (VER) byte */ - if(socksreq[1] != 0) { /* status */ + else if(socksreq[1] != 0) { /* status */ failf(data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); return CURLE_COULDNT_CONNECT; @@ -890,6 +904,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user, failf(data, "Failed to receive SOCKS5 connect request ack."); return CURLE_COULDNT_CONNECT; } + else if(!result && !actualread) { + /* connection closed */ + failf(data, "connection to proxy closed"); + return CURLE_COULDNT_CONNECT; + } else if(actualread != sx->outstanding) { /* remain in state */ sx->outstanding -= actualread; @@ -967,7 +986,12 @@ CURLcode Curl_SOCKS5(const char *proxy_user, failf(data, "Failed to receive SOCKS5 connect request ack."); return CURLE_COULDNT_CONNECT; } - if(actualread != sx->outstanding) { + else if(!result && !actualread) { + /* connection closed */ + failf(data, "connection to proxy closed"); + return CURLE_COULDNT_CONNECT; + } + else if(actualread != sx->outstanding) { /* remain in state */ sx->outstanding -= actualread; sx->outp += actualread; |