diff options
Diffstat (limited to 'Utilities/cmcurl/lib/connect.c')
-rw-r--r-- | Utilities/cmcurl/lib/connect.c | 133 |
1 files changed, 71 insertions, 62 deletions
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c index 18ac32c..0047f9a 100644 --- a/Utilities/cmcurl/lib/connect.c +++ b/Utilities/cmcurl/lib/connect.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -56,7 +56,6 @@ #include <inet.h> #endif -#include "curl_printf.h" #include "urldata.h" #include "sendf.h" #include "if2ip.h" @@ -73,8 +72,10 @@ #include "warnless.h" #include "conncache.h" #include "multihandle.h" +#include "system_win32.h" -/* The last #include files should be: */ +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" #include "curl_memory.h" #include "memdebug.h" @@ -103,7 +104,7 @@ struct tcp_keepalive { #endif static void -tcpkeepalive(struct SessionHandle *data, +tcpkeepalive(struct Curl_easy *data, curl_socket_t sockfd) { int optval = data->set.tcp_keepalive?1:0; @@ -178,7 +179,7 @@ singleipconnect(struct connectdata *conn, * * @unittest: 1303 */ -long Curl_timeleft(struct SessionHandle *data, +long Curl_timeleft(struct Curl_easy *data, struct timeval *nowp, bool duringconnect) { @@ -238,7 +239,7 @@ long Curl_timeleft(struct SessionHandle *data, static CURLcode bindlocal(struct connectdata *conn, curl_socket_t sockfd, int af, unsigned int scope) { - struct SessionHandle *data = conn->data; + struct Curl_easy *data = conn->data; struct Curl_sockaddr_storage sa; struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */ @@ -619,7 +620,7 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr, switch (sa->sa_family) { case AF_INET: - si = (struct sockaddr_in*) sa; + si = (struct sockaddr_in*)(void*) sa; if(Curl_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) { us_port = ntohs(si->sin_port); @@ -629,7 +630,7 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr, break; #ifdef ENABLE_IPV6 case AF_INET6: - si6 = (struct sockaddr_in6*)sa; + si6 = (struct sockaddr_in6*)(void*) sa; if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr, addr, MAX_IPADR_LEN)) { us_port = ntohs(si6->sin6_port); @@ -662,13 +663,13 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) curl_socklen_t len; struct Curl_sockaddr_storage ssrem; struct Curl_sockaddr_storage ssloc; - struct SessionHandle *data = conn->data; + struct Curl_easy *data = conn->data; if(conn->socktype == SOCK_DGRAM) /* there's no connection! */ return; - if(!conn->bits.reuse) { + if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { int error; len = sizeof(struct Curl_sockaddr_storage); @@ -719,7 +720,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, int sockindex, bool *connected) { - struct SessionHandle *data = conn->data; + struct Curl_easy *data = conn->data; CURLcode result = CURLE_OK; long allow; int error = 0; @@ -764,6 +765,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0); if(rc == 0) { /* no connection yet */ + error = 0; if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) { infof(data, "After %ldms connect time, move on!\n", conn->timeoutms_per_addr); @@ -776,7 +778,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, trynextip(conn, sockindex, 1); } } - else if(rc == CURL_CSELECT_OUT) { + else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) { if(verifyconnect(conn->tempsock[i], &error)) { /* we are connected with TCP, awesome! */ @@ -841,6 +843,8 @@ CURLcode Curl_is_connected(struct connectdata *conn, if(result) { /* no more addresses to try */ + const char* hostname; + /* if the first address family runs out of addresses to try before the happy eyeball timeout, go ahead and try the next family now */ if(conn->tempaddr[1] == NULL) { @@ -849,20 +853,27 @@ CURLcode Curl_is_connected(struct connectdata *conn, return result; } + if(conn->bits.proxy) + hostname = conn->proxy.name; + else if(conn->bits.conn_to_host) + hostname = conn->conn_to_host.name; + else + hostname = conn->host.name; + failf(data, "Failed to connect to %s port %ld: %s", - conn->bits.proxy?conn->proxy.name:conn->host.name, - conn->port, Curl_strerror(conn, error)); + hostname, conn->port, Curl_strerror(conn, error)); } return result; } -static void tcpnodelay(struct connectdata *conn, - curl_socket_t sockfd) +void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) { -#ifdef TCP_NODELAY - struct SessionHandle *data= conn->data; - curl_socklen_t onoff = (curl_socklen_t) data->set.tcp_nodelay; +#if defined(TCP_NODELAY) +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) + struct Curl_easy *data = conn->data; +#endif + curl_socklen_t onoff = (curl_socklen_t) 1; int level = IPPROTO_TCP; #if 0 @@ -878,6 +889,10 @@ static void tcpnodelay(struct connectdata *conn, level = pe->p_proto; #endif +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) conn; +#endif + if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff, sizeof(onoff)) < 0) infof(data, "Could not set TCP_NODELAY: %s\n", @@ -898,7 +913,7 @@ static void tcpnodelay(struct connectdata *conn, static void nosigpipe(struct connectdata *conn, curl_socket_t sockfd) { - struct SessionHandle *data= conn->data; + struct Curl_easy *data= conn->data; int onoff = 1; if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, sizeof(onoff)) < 0) @@ -913,7 +928,7 @@ static void nosigpipe(struct connectdata *conn, /* When you run a program that uses the Windows Sockets API, you may experience slow performance when you copy data to a TCP server. - http://support.microsoft.com/kb/823764 + https://support.microsoft.com/kb/823764 Work-around: Make the Socket Send Buffer Size Larger Than the Program Send Buffer Size @@ -931,43 +946,15 @@ void Curl_sndbufset(curl_socket_t sockfd) int val = CURL_MAX_WRITE_SIZE + 32; int curval = 0; int curlen = sizeof(curval); - DWORD majorVersion = 6; static int detectOsState = DETECT_OS_NONE; if(detectOsState == DETECT_OS_NONE) { -#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \ - (_WIN32_WINNT < _WIN32_WINNT_WIN2K) - OSVERSIONINFO osver; - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - - detectOsState = DETECT_OS_PREVISTA; - if(GetVersionEx(&osver)) { - if(osver.dwMajorVersion >= majorVersion) - detectOsState = DETECT_OS_VISTA_OR_LATER; - } -#else - ULONGLONG cm; - OSVERSIONINFOEX osver; - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwMajorVersion = majorVersion; - - cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); - - if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION | - VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR), - cm)) + if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) detectOsState = DETECT_OS_VISTA_OR_LATER; else detectOsState = DETECT_OS_PREVISTA; -#endif } if(detectOsState == DETECT_OS_VISTA_OR_LATER) @@ -995,10 +982,10 @@ static CURLcode singleipconnect(struct connectdata *conn, curl_socket_t *sockp) { struct Curl_sockaddr_ex addr; - int rc; + int rc = -1; int error = 0; bool isconnected = FALSE; - struct SessionHandle *data = conn->data; + struct Curl_easy *data = conn->data; curl_socket_t sockfd; CURLcode result; char ipaddress[MAX_IPADR_LEN]; @@ -1033,7 +1020,7 @@ static CURLcode singleipconnect(struct connectdata *conn, is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM; #endif if(is_tcp && data->set.tcp_nodelay) - tcpnodelay(conn, sockfd); + Curl_tcpnodelay(conn, sockfd); nosigpipe(conn, sockfd); @@ -1084,7 +1071,29 @@ static CURLcode singleipconnect(struct connectdata *conn, /* Connect TCP sockets, bind UDP */ if(!isconnected && (conn->socktype == SOCK_STREAM)) { - rc = connect(sockfd, &addr.sa_addr, addr.addrlen); + if(conn->bits.tcp_fastopen) { +#if defined(CONNECT_DATA_IDEMPOTENT) /* OS X */ + sa_endpoints_t endpoints; + endpoints.sae_srcif = 0; + endpoints.sae_srcaddr = NULL; + endpoints.sae_srcaddrlen = 0; + endpoints.sae_dstaddr = &addr.sa_addr; + endpoints.sae_dstaddrlen = addr.addrlen; + + rc = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY, + CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT, + NULL, 0, NULL, NULL); +#elif defined(MSG_FASTOPEN) /* Linux */ + if(conn->given->flags & PROTOPT_SSL) + rc = connect(sockfd, &addr.sa_addr, addr.addrlen); + else + rc = 0; /* Do nothing */ +#endif + } + else { + rc = connect(sockfd, &addr.sa_addr, addr.addrlen); + } + if(-1 == rc) error = SOCKERRNO; } @@ -1140,7 +1149,7 @@ static CURLcode singleipconnect(struct connectdata *conn, CURLcode Curl_connecthost(struct connectdata *conn, /* context */ const struct Curl_dns_entry *remotehost) { - struct SessionHandle *data = conn->data; + struct Curl_easy *data = conn->data; struct timeval before = Curl_tvnow(); CURLcode result = CURLE_COULDNT_CONNECT; @@ -1199,11 +1208,11 @@ static int conn_is_conn(struct connectdata *conn, void *param) /* * Used to extract socket and connectdata struct for the most recent - * transfer on the given SessionHandle. + * transfer on the given Curl_easy. * * The returned socket will be CURL_SOCKET_BAD in case of failure! */ -curl_socket_t Curl_getconnectinfo(struct SessionHandle *data, +curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, struct connectdata **connp) { curl_socket_t sockfd; @@ -1243,10 +1252,10 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data, } /* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */ #ifdef MSG_PEEK - else { + else if(sockfd != CURL_SOCKET_BAD) { /* use the socket */ char buf; - if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf, + if(recv((RECV_TYPE_ARG1)sockfd, (RECV_TYPE_ARG2)&buf, (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) { return CURL_SOCKET_BAD; /* FIN received */ } @@ -1303,7 +1312,7 @@ CURLcode Curl_socket(struct connectdata *conn, struct Curl_sockaddr_ex *addr, curl_socket_t *sockfd) { - struct SessionHandle *data = conn->data; + struct Curl_easy *data = conn->data; struct Curl_sockaddr_ex dummy; if(!addr) |