25 #ifdef HAVE_NETINET_IN_H 26 #include <netinet/in.h> 31 #ifdef HAVE_NETINET_TCP_H 32 #include <netinet/tcp.h> 34 #ifdef HAVE_SYS_IOCTL_H 35 #include <sys/ioctl.h> 43 #ifdef HAVE_ARPA_INET_H 44 #include <arpa/inet.h> 47 #if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE)) 48 #include <sys/filio.h> 52 #define in_addr_t unsigned long 89 #if defined(__DragonFly__) || defined(HAVE_WINSOCK_H) 91 #define KEEPALIVE_FACTOR(x) (x *= 1000) 93 #define KEEPALIVE_FACTOR(x) 96 #if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS) 97 #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) 99 struct tcp_keepalive {
101 u_long keepalivetime;
102 u_long keepaliveinterval;
113 if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
114 (
void *)&optval,
sizeof(optval)) < 0) {
115 infof(data,
"Failed to set SO_KEEPALIVE on fd %d\n", sockfd);
118 #if defined(SIO_KEEPALIVE_VALS) 119 struct tcp_keepalive vals;
124 vals.keepalivetime = optval;
127 vals.keepaliveinterval = optval;
128 if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals,
sizeof(vals),
129 NULL, 0, &dummy, NULL, NULL) != 0) {
130 infof(data,
"Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n",
131 (
int)sockfd, WSAGetLastError());
137 if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
138 (
void *)&optval,
sizeof(optval)) < 0) {
139 infof(data,
"Failed to set TCP_KEEPIDLE on fd %d\n", sockfd);
145 if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
146 (
void *)&optval,
sizeof(optval)) < 0) {
147 infof(data,
"Failed to set TCP_KEEPINTVL on fd %d\n", sockfd);
154 if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
155 (
void *)&optval,
sizeof(optval)) < 0) {
156 infof(data,
"Failed to set TCP_KEEPALIVE on fd %d\n", sockfd);
197 switch(timeout_set) {
245 struct sockaddr *sock = (
struct sockaddr *)&sa;
247 struct sockaddr_in *si4 = (
struct sockaddr_in *)&sa;
249 struct sockaddr_in6 *si6 = (
struct sockaddr_in6 *)&sa;
269 if(dev && (strlen(dev)<255) ) {
270 char myhost[256] =
"";
272 bool is_interface =
FALSE;
273 bool is_host =
FALSE;
274 static const char *if_prefix =
"if!";
275 static const char *host_prefix =
"host!";
277 if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
278 dev += strlen(if_prefix);
281 else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) {
282 dev += strlen(host_prefix);
289 myhost,
sizeof(myhost))) {
293 failf(data,
"Couldn't bind to interface '%s'", dev);
305 infof(data,
"Local Interface %s is ip %s using address family %i\n",
309 #ifdef SO_BINDTODEVICE 321 if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
324 infof(data,
"SO_BINDTODEVICE %s failed with errno %d: %s;" 325 " will do regular bind\n",
350 else if(af == AF_INET6)
362 infof(data,
"Name '%s' family %i resolved to '%s' family %i\n",
380 #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 381 char *scope_ptr = strchr(myhost,
'%');
386 si6->sin6_family = AF_INET6;
387 si6->sin6_port = htons(port);
388 #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 394 si6->sin6_scope_id = atoi(scope_ptr);
397 sizeof_sa =
sizeof(
struct sockaddr_in6);
402 if((af == AF_INET) &&
404 si4->sin_family = AF_INET;
405 si4->sin_port = htons(port);
406 sizeof_sa =
sizeof(
struct sockaddr_in);
411 failf(data,
"Couldn't bind to '%s'", dev);
419 si6->sin6_family = AF_INET6;
420 si6->sin6_port = htons(port);
421 sizeof_sa =
sizeof(
struct sockaddr_in6);
426 si4->sin_family = AF_INET;
427 si4->sin_port = htons(port);
428 sizeof_sa =
sizeof(
struct sockaddr_in);
433 if(
bind(sockfd, sock, sizeof_sa) >= 0) {
438 if(getsockname(sockfd, (
struct sockaddr *) &add, &size) < 0) {
440 failf(data,
"getsockname() failed with errno %d: %s",
444 infof(data,
"Local port: %hu\n", port);
450 infof(data,
"Bind to local port %hu failed, trying next\n", port);
453 if(sock->sa_family == AF_INET)
454 si4->sin_port = ntohs(port);
457 si6->sin6_port = ntohs(port);
465 failf(data,
"bind failed with errno %d: %s",
506 if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (
void *)&err, &errSize))
510 if(WSAENOPROTOOPT == err) {
517 if(EBADIOCTL == err) {
522 if((0 == err) || (EISCONN == err))
544 const int other = tempindex ^ 1;
556 int family = AF_UNSPEC;
567 family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
615 unsigned short us_port;
616 struct sockaddr_in *si = NULL;
618 struct sockaddr_in6 *si6 = NULL;
620 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) 621 struct sockaddr_un *su = NULL;
624 switch(sa->sa_family) {
626 si = (
struct sockaddr_in *)(
void *) sa;
629 us_port = ntohs(si->sin_port);
636 si6 = (
struct sockaddr_in6 *)(
void *) sa;
639 us_port = ntohs(si6->sin6_port);
645 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) 647 su = (
struct sockaddr_un*)sa;
658 errno = EAFNOSUPPORT;
677 if(getpeername(sockfd, (
struct sockaddr*) &ssrem, &len)) {
679 failf(data,
"getpeername() failed with errno %d: %s",
685 memset(&ssloc, 0,
sizeof(ssloc));
686 if(getsockname(sockfd, (
struct sockaddr*) &ssloc, &len)) {
688 failf(data,
"getsockname() failed with errno %d: %s",
695 failf(data,
"ssrem inet_ntop() failed with errno %d: %s",
703 failf(data,
"ssloc inet_ntop() failed with errno %d: %s",
747 failf(data,
"Connection time-out");
751 for(i = 0; i<2; i++) {
752 const int other = i ^ 1;
769 infof(data,
"After %ldms connect time, move on!\n",
775 if(i == 0 && conn->
tempaddr[1] == NULL &&
810 infof(data,
"Connection failed\n");
826 infof(data,
"connect to %s port %ld failed: %s\n",
863 failf(data,
"Failed to connect to %s port %ld: %s",
872 #if defined(TCP_NODELAY) 873 #if !defined(CURL_DISABLE_VERBOSE_STRINGS) 877 int level = IPPROTO_TCP;
879 #if defined(CURL_DISABLE_VERBOSE_STRINGS) 883 if(setsockopt(sockfd, level, TCP_NODELAY, (
void *)&onoff,
885 infof(data,
"Could not set TCP_NODELAY: %s\n",
888 infof(data,
"TCP_NODELAY set\n");
905 if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (
void *)&onoff,
907 infof(data,
"Could not set SO_NOSIGPIPE: %s\n",
911 #define nosigpipe(x,y) Curl_nop_stmt 927 #define DETECT_OS_NONE 0 928 #define DETECT_OS_PREVISTA 1 929 #define DETECT_OS_VISTA_OR_LATER 2 935 int curlen =
sizeof(curval);
937 static int detectOsState = DETECT_OS_NONE;
939 if(detectOsState == DETECT_OS_NONE) {
940 if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
941 VERSION_GREATER_THAN_EQUAL))
942 detectOsState = DETECT_OS_VISTA_OR_LATER;
944 detectOsState = DETECT_OS_PREVISTA;
947 if(detectOsState == DETECT_OS_VISTA_OR_LATER)
950 if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (
char *)&curval, &curlen) == 0)
954 setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (
const char *)&val,
sizeof(val));
974 bool isconnected =
FALSE;
995 failf(data,
"sa_addr inet_ntop() failed with errno %d: %s",
1000 infof(data,
" Trying %s...\n", ipaddress);
1003 is_tcp = (addr.
family == AF_INET || addr.
family == AF_INET6) &&
1006 is_tcp = (addr.
family == AF_INET) && addr.
socktype == SOCK_STREAM;
1033 if(addr.
family == AF_INET
1035 || addr.
family == AF_INET6
1059 if(!isconnected && (conn->
socktype == SOCK_STREAM)) {
1061 #if defined(CONNECT_DATA_IDEMPOTENT) 1062 #ifdef HAVE_BUILTIN_AVAILABLE 1063 if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {
1065 sa_endpoints_t endpoints;
1066 endpoints.sae_srcif = 0;
1067 endpoints.sae_srcaddr = NULL;
1068 endpoints.sae_srcaddrlen = 0;
1069 endpoints.sae_dstaddr = &addr.sa_addr;
1070 endpoints.sae_dstaddrlen = addr.
addrlen;
1072 rc = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY,
1073 CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT,
1074 NULL, 0, NULL, NULL);
1075 #ifdef HAVE_BUILTIN_AVAILABLE 1081 #elif defined(MSG_FASTOPEN) 1109 #if (EAGAIN) != (EWOULDBLOCK) 1122 infof(data,
"Immediate connect fail for %s: %s\n",
1153 if(timeout_ms < 0) {
1155 failf(data,
"Connection time-out");
1364 #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) 1366 struct sockaddr_in6 *
const sa6 = (
void *)&addr->sa_addr;
1367 sa6->sin6_scope_id = conn->
scope_id;
1380 #
if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
1381 ,
const char *reason
1393 closeit?
"closure":
"keep alive", reason));
struct ssl_connect_data ssl[2]
#define CURL_IPRESOLVE_V6
struct connectdata * lastconnect
bool Curl_conn_data_pending(struct connectdata *conn, int sockindex)
char primary_ip[MAX_IPADR_LEN]
#define Curl_sndbufset(y)
curl_opensocket_callback fopensocket
struct curltime connecttime
int curlx_sltosi(long slnum)
static void tcpkeepalive(struct Curl_easy *data, curl_socket_t sockfd)
void Curl_conncache_foreach(struct conncache *connc, void *param, int(*func)(struct connectdata *conn, void *param))
void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
struct Curl_multi * multi_easy
void Curl_conncontrol(struct connectdata *conn, int ctrl)
unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
static bool getaddressinfo(struct sockaddr *sa, char *addr, long *port)
#define CURL_IPRESOLVE_V4
const struct Curl_handler * handler
#define CURL_MAX_WRITE_SIZE
struct Curl_multi * multi
#define CURLRESOLV_PENDING
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock)
curl_socket_t tempsock[2]
#define HAPPY_EYEBALLS_TIMEOUT
CURLcode Curl_socket(struct connectdata *conn, const Curl_addrinfo *ai, struct Curl_sockaddr_ex *addr, curl_socket_t *sockfd)
struct curltime t_startop
UNITTEST_START int result
char ip_addr_str[MAX_IPADR_LEN]
CURLcode Curl_connecthost(struct connectdata *conn, const struct Curl_dns_entry *remotehost)
char * Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
int curlx_nonblock(curl_socket_t sockfd, int nonblock)
void Curl_verboseconnect(struct connectdata *conn)
struct sockaddr * ai_addr
struct proxy_info http_proxy
curl_sockopt_callback fsockopt
static CURLcode singleipconnect(struct connectdata *conn, const Curl_addrinfo *ai, curl_socket_t *sock)
memcpy(filename, filename1, strlen(filename1))
CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
unsigned int conn_protocol
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, struct connectdata **connp)
#define Curl_ssl_data_pending(x, y)
CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
const char * Curl_strerror(struct connectdata *conn, int err)
#define SOCKET_READABLE(x, z)
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
#define Curl_ssl_check_cxn(x)
const char * Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
#define SOCKET_WRITABLE(x, z)
CURLcode Curl_is_connected(struct connectdata *conn, int sockindex, bool *connected)
struct connectdata * tofind
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, unsigned int remote_scope_id, const char *interf, char *buf, int buf_size)
int Curl_resolv(struct connectdata *conn, const char *hostname, int port, struct Curl_dns_entry **entry)
static CURLcode bindlocal(struct connectdata *conn, curl_socket_t sockfd, int af, unsigned int scope)
void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns)
struct conncache conn_cache
const struct Curl_handler * given
struct proxy_info socks_proxy
int Curl_inet_pton(int af, const char *src, void *dst)
static unsigned short port
struct Curl_addrinfo * ai_next
bool Curl_connalive(struct connectdata *conn)
void * closesocket_client
time_t timeoutms_per_addr
char conn_local_ip[MAX_IPADR_LEN]
time_t curlx_tvdiff(struct curltime newer, struct curltime older)
#define DEFAULT_CONNECT_TIMEOUT
void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
curl_closesocket_callback fclosesocket
struct curltime t_startsingle
int Curl_num_addresses(const Curl_addrinfo *addr)
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
struct hostname conn_to_host
void Curl_persistconninfo(struct connectdata *conn)
char local_ip[MAX_IPADR_LEN]
char conn_primary_ip[MAX_IPADR_LEN]
static int conn_is_conn(struct connectdata *conn, void *param)
static CURLcode trynextip(struct connectdata *conn, int sockindex, int tempindex)
#define Curl_tvdiff(x, y)
curl_socklen_t ai_addrlen
#define CONNCTRL_CONNECTION
#define KEEPALIVE_FACTOR(x)
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, struct Curl_dns_entry **dnsentry)
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
Curl_addrinfo * tempaddr[2]
static bool verifyconnect(curl_socket_t sockfd, int *error)
#define CURL_SOCKOPT_ALREADY_CONNECTED