summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2006-09-03 22:52:42 +0000
committerDaniel Stenberg <daniel@haxx.se>2006-09-03 22:52:42 +0000
commit466d093a92f3e8ccbb8af026e786bc41708caba6 (patch)
tree9945242e6dd096694db9141fa60a2dfc42d81bb5
parent1e9be353c27a6351d96183acf23167db6394d611 (diff)
downloadgnurl-466d093a92f3e8ccbb8af026e786bc41708caba6.tar.gz
gnurl-466d093a92f3e8ccbb8af026e786bc41708caba6.tar.bz2
gnurl-466d093a92f3e8ccbb8af026e786bc41708caba6.zip
- "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.
-rw-r--r--CHANGES7
-rw-r--r--RELEASE-NOTES2
-rw-r--r--docs/KNOWN_BUGS8
-rw-r--r--lib/url.c72
4 files changed, 81 insertions, 8 deletions
diff --git a/CHANGES b/CHANGES
index 1d8c39b28..29ede8c5c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 05fe3b190..6ac3a3915 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -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
diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS
index 38c657f03..d16fdbb5b 100644
--- a/docs/KNOWN_BUGS
+++ b/docs/KNOWN_BUGS
@@ -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).
diff --git a/lib/url.c b/lib/url.c
index aaf59132a..68339790b 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -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;
}
-