summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/connect.c')
-rw-r--r--libs/libcurl/src/connect.c87
1 files changed, 53 insertions, 34 deletions
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c
index 611d6d2f02..0a7475cb6a 100644
--- a/libs/libcurl/src/connect.c
+++ b/libs/libcurl/src/connect.c
@@ -745,13 +745,15 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
Curl_persistconninfo(conn);
}
-/* after a TCP connection to the proxy has been verified, this function does
- the next magic step.
+/* After a TCP connection to the proxy has been verified, this function does
+ the next magic steps. If 'done' isn't set TRUE, it is not done yet and
+ must be called again.
Note: this function's sub-functions call failf()
*/
-static CURLcode connected_proxy(struct connectdata *conn, int sockindex)
+static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
+ bool *done)
{
CURLcode result = CURLE_OK;
@@ -760,44 +762,63 @@ static CURLcode connected_proxy(struct connectdata *conn, int sockindex)
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
*/
- const char * const host = conn->bits.httpproxy ?
- conn->http_proxy.host.name :
- conn->bits.conn_to_host ?
- conn->conn_to_host.name :
- sockindex == SECONDARYSOCKET ?
- conn->secondaryhostname : conn->host.name;
- const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
- sockindex == SECONDARYSOCKET ? conn->secondary_port :
- conn->bits.conn_to_port ? conn->conn_to_port :
- conn->remote_port;
- conn->bits.socksproxy_connecting = TRUE;
+ const char * const host =
+ conn->bits.httpproxy ?
+ conn->http_proxy.host.name :
+ conn->bits.conn_to_host ?
+ conn->conn_to_host.name :
+ sockindex == SECONDARYSOCKET ?
+ conn->secondaryhostname : conn->host.name;
+ const int port =
+ conn->bits.httpproxy ? (int)conn->http_proxy.port :
+ sockindex == SECONDARYSOCKET ? conn->secondary_port :
+ conn->bits.conn_to_port ? conn->conn_to_port :
+ conn->remote_port;
switch(conn->socks_proxy.proxytype) {
case CURLPROXY_SOCKS5:
case CURLPROXY_SOCKS5_HOSTNAME:
result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
- host, port, sockindex, conn);
+ host, port, sockindex, conn, done);
break;
case CURLPROXY_SOCKS4:
case CURLPROXY_SOCKS4A:
result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
- conn);
+ conn, done);
break;
default:
failf(conn->data, "unknown proxytype option given");
result = CURLE_COULDNT_CONNECT;
} /* switch proxytype */
- conn->bits.socksproxy_connecting = FALSE;
#else
(void)sockindex;
#endif /* CURL_DISABLE_PROXY */
}
+ else
+ *done = TRUE; /* no SOCKS proxy, so consider us connected */
return result;
}
/*
+ * post_SOCKS() is called after a successful connect to the peer, which
+ * *could* be a SOCKS proxy
+ */
+static void post_SOCKS(struct connectdata *conn,
+ int sockindex,
+ bool *connected)
+{
+ conn->bits.tcpconnect[sockindex] = TRUE;
+
+ *connected = TRUE;
+ if(sockindex == FIRSTSOCKET)
+ Curl_pgrsTime(conn->data, TIMER_CONNECT); /* connect done */
+ Curl_updateconninfo(conn, conn->sock[sockindex]);
+ Curl_verboseconnect(conn);
+}
+
+/*
* Curl_is_connected() checks if the socket has connected.
*/
@@ -834,6 +855,14 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return CURLE_OPERATION_TIMEDOUT;
}
+ if(SOCKS_STATE(conn->cnnct.state)) {
+ /* still doing SOCKS */
+ result = connect_SOCKS(conn, sockindex, connected);
+ if(!result && *connected)
+ post_SOCKS(conn, sockindex, connected);
+ return result;
+ }
+
for(i = 0; i<2; i++) {
const int other = i ^ 1;
if(conn->tempsock[i] == CURL_SOCKET_BAD)
@@ -900,18 +929,13 @@ CURLcode Curl_is_connected(struct connectdata *conn,
conn->tempsock[other] = CURL_SOCKET_BAD;
}
- /* see if we need to do any proxy magic first once we connected */
- result = connected_proxy(conn, sockindex);
- if(result)
+ /* see if we need to kick off any SOCKS proxy magic once we
+ connected */
+ result = connect_SOCKS(conn, sockindex, connected);
+ if(result || !*connected)
return result;
- conn->bits.tcpconnect[sockindex] = TRUE;
-
- *connected = TRUE;
- if(sockindex == FIRSTSOCKET)
- Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
- Curl_updateconninfo(conn, conn->sock[sockindex]);
- Curl_verboseconnect(conn);
+ post_SOCKS(conn, sockindex, connected);
return CURLE_OK;
}
@@ -1007,8 +1031,6 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
sizeof(onoff)) < 0)
infof(data, "Could not set TCP_NODELAY: %s\n",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
- else
- infof(data, "TCP_NODELAY set\n");
#else
(void)conn;
(void)sockfd;
@@ -1216,8 +1238,6 @@ static CURLcode singleipconnect(struct connectdata *conn,
if(setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
(void *)&optval, sizeof(optval)) < 0)
infof(data, "Failed to enable TCP Fast Open on fd %d\n", sockfd);
- else
- infof(data, "TCP_FASTOPEN_CONNECT set\n");
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
#elif defined(MSG_FASTOPEN) /* old Linux */
@@ -1428,12 +1448,11 @@ int Curl_closesocket(struct connectdata *conn,
curl_socket_t sock)
{
if(conn && conn->fclosesocket) {
- if((sock == conn->sock[SECONDARYSOCKET]) &&
- conn->sock_accepted[SECONDARYSOCKET])
+ if((sock == conn->sock[SECONDARYSOCKET]) && conn->sock_accepted)
/* if this socket matches the second socket, and that was created with
accept, then we MUST NOT call the callback but clear the accepted
status */
- conn->sock_accepted[SECONDARYSOCKET] = FALSE;
+ conn->sock_accepted = FALSE;
else {
int rc;
Curl_multi_closed(conn->data, sock);