while not fixing things very nicely, it does make the SOCKS5 proxy
  connection slightly better as it now acknowledges the timeout for connection
  and it no longer segfaults in the case when SOCKS requires authentication
  and you did not specify username:password.
This commit is contained in:
Daniel Stenberg 2006-09-03 22:52:42 +00:00
parent 1e9be353c2
commit 466d093a92
4 changed files with 81 additions and 8 deletions

View File

@ -7,6 +7,13 @@
Changelog
Daniel (4 September 2006)
- "Dortik" (http://curl.haxx.se/bug/view.cgi?id=1551412) provided a patch that
while not fixing things very nicely, it does make the SOCKS5 proxy
connection slightly better as it now acknowledges the timeout for connection
and it no longer segfaults in the case when SOCKS requires authentication
and you did not specify username:password.
Daniel (31 August 2006)
- Dmitriy Sergeyev found and fixed a multi interface flaw when using asynch
name resolves. It could get stuck in the wrong state.

View File

@ -18,6 +18,8 @@ This release includes the following changes:
This release includes the following bugfixes:
o SOCKS5 proxy connects can now time-out
o SOCKS5 connects that require auth no longer segfaults when auth not given
o multi interface using asynch resolves could get stuck in wrong state
o the 'running_handles' counter wasn't always updated properly when
curl_multi_remove_handle() was used

View File

@ -3,7 +3,11 @@ join in and help us correct one or more of these! Also be sure to check the
changelog of the current development status, as one or more of these problems
may have been fixed since this was written!
34. The SOCKS connection codes don't properly acknowledge (connect) timeouts.
35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
bad when used with the multi interface.
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
Also see #12.
33. Doing multi-pass HTTP authentication on a non-default port does not work.
This happens because the multi-pass code abuses the redirect following code
@ -92,7 +96,7 @@ may have been fixed since this was written!
12. When connecting to a SOCKS proxy, the (connect) timeout is not properly
acknowledged after the actual TCP connect (during the SOCKS "negotiate"
phase). Pointed out by Lucas. Fix: need to select() and timeout properly.
phase).
11. Using configure --disable-[protocol] may cause 'make test' to fail for
tests using the disabled protocol(s).

View File

@ -2115,14 +2115,49 @@ static int handleSock5Proxy(const char *proxy_name,
int result;
CURLcode code;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
struct SessionHandle *data = conn->data;
long timeout;
Curl_nonblock(sock, FALSE);
/* get timeout */
if(data->set.timeout && data->set.connecttimeout) {
if (data->set.timeout < data->set.connecttimeout)
timeout = data->set.timeout*1000;
else
timeout = data->set.connecttimeout*1000;
}
else if(data->set.timeout)
timeout = data->set.timeout*1000;
else if(data->set.connecttimeout)
timeout = data->set.connecttimeout*1000;
else
timeout = DEFAULT_CONNECT_TIMEOUT;
Curl_nonblock(sock, TRUE);
/* wait until socket gets connected */
result = Curl_select(CURL_SOCKET_BAD, sock, timeout);
if(-1 == result) {
failf(conn->data, "SOCKS5: no connection here");
return 1;
}
else if(0 == result) {
failf(conn->data, "SOCKS5: connection timeout");
return 1;
}
if(result & CSELECT_ERR) {
failf(conn->data, "SOCKS5: error occured during connection");
return 1;
}
socksreq[0] = 5; /* version */
socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
socksreq[2] = 0; /* no authentication */
socksreq[3] = 2; /* username/password */
Curl_nonblock(sock, FALSE);
code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
&written);
if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
@ -2130,6 +2165,26 @@ static int handleSock5Proxy(const char *proxy_name,
return 1;
}
Curl_nonblock(sock, TRUE);
result = Curl_select(sock, CURL_SOCKET_BAD, timeout);
if(-1 == result) {
failf(conn->data, "SOCKS5 nothing to read");
return 1;
}
else if(0 == result) {
failf(conn->data, "SOCKS5 read timeout");
return 1;
}
if(result & CSELECT_ERR) {
failf(conn->data, "SOCKS5 read error occured");
return 1;
}
Curl_nonblock(sock, FALSE);
result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
if ((result != CURLE_OK) || (actualread != 2)) {
failf(conn->data, "Unable to receive initial SOCKS5 response.");
@ -2146,10 +2201,16 @@ static int handleSock5Proxy(const char *proxy_name,
}
else if (socksreq[1] == 2) {
/* Needs user name and password */
int userlen, pwlen, len;
userlen = (int)strlen(proxy_name);
pwlen = proxy_password?(int)strlen(proxy_password):0;
size_t userlen, pwlen;
int len;
if(proxy_name && proxy_password) {
userlen = strlen(proxy_name);
pwlen = proxy_password?strlen(proxy_password):0;
}
else {
userlen = 0;
pwlen = 0;
}
/* username/password request looks like
* +----+------+----------+------+----------+
@ -4209,4 +4270,3 @@ CURLcode Curl_do_more(struct connectdata *conn)
return result;
}