diff --git a/lib/connect.c b/lib/connect.c index 67698b1ca..e65d24d9e 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -671,59 +671,71 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, return FALSE; } +/* retrieves the start/end point information of a socket of an established + connection */ +void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd) +{ +#ifdef HAVE_GETPEERNAME + char buffer[STRERROR_LEN]; + struct Curl_sockaddr_storage ssrem; + curl_socklen_t plen; + plen = sizeof(struct Curl_sockaddr_storage); + if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) { + int error = SOCKERRNO; + failf(conn->data, "getpeername() failed with errno %d: %s", + error, Curl_strerror(error, buffer, sizeof(buffer))); + return; + } + if(!Curl_addr2string((struct sockaddr*)&ssrem, plen, + conn->primary_ip, &conn->primary_port)) { + failf(conn->data, "ssrem inet_ntop() failed with errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + return; + } + memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); +#else + (void)conn; + (void)sockfd; +#endif +} + +/* retrieves the start/end point information of a socket of an established + connection */ +void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd) +{ +#ifdef HAVE_GETSOCKNAME + char buffer[STRERROR_LEN]; + struct Curl_sockaddr_storage ssloc; + curl_socklen_t slen; + slen = sizeof(struct Curl_sockaddr_storage); + memset(&ssloc, 0, sizeof(ssloc)); + if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) { + int error = SOCKERRNO; + failf(conn->data, "getsockname() failed with errno %d: %s", + error, Curl_strerror(error, buffer, sizeof(buffer))); + return; + } + if(!Curl_addr2string((struct sockaddr*)&ssloc, slen, + conn->local_ip, &conn->local_port)) { + failf(conn->data, "ssloc inet_ntop() failed with errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + return; + } +#else + (void)conn; + (void)sockfd; +#endif +} + /* retrieves the start/end point information of a socket of an established connection */ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) { if(conn->transport == TRNSPRT_TCP) { -#if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME) if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { - struct Curl_easy *data = conn->data; - char buffer[STRERROR_LEN]; - struct Curl_sockaddr_storage ssrem; - struct Curl_sockaddr_storage ssloc; - curl_socklen_t plen; - curl_socklen_t slen; -#ifdef HAVE_GETPEERNAME - plen = sizeof(struct Curl_sockaddr_storage); - if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) { - int error = SOCKERRNO; - failf(data, "getpeername() failed with errno %d: %s", - error, Curl_strerror(error, buffer, sizeof(buffer))); - return; - } -#endif -#ifdef HAVE_GETSOCKNAME - slen = sizeof(struct Curl_sockaddr_storage); - memset(&ssloc, 0, sizeof(ssloc)); - if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) { - int error = SOCKERRNO; - failf(data, "getsockname() failed with errno %d: %s", - error, Curl_strerror(error, buffer, sizeof(buffer))); - return; - } -#endif -#ifdef HAVE_GETPEERNAME - if(!Curl_addr2string((struct sockaddr*)&ssrem, plen, - conn->primary_ip, &conn->primary_port)) { - failf(data, "ssrem inet_ntop() failed with errno %d: %s", - errno, Curl_strerror(errno, buffer, sizeof(buffer))); - return; - } - memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); -#endif -#ifdef HAVE_GETSOCKNAME - if(!Curl_addr2string((struct sockaddr*)&ssloc, slen, - conn->local_ip, &conn->local_port)) { - failf(data, "ssloc inet_ntop() failed with errno %d: %s", - errno, Curl_strerror(errno, buffer, sizeof(buffer))); - return; - } -#endif + Curl_conninfo_remote(conn, sockfd); + Curl_conninfo_local(conn, sockfd); } -#else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */ - (void)sockfd; /* unused */ -#endif } /* end of TCP-only section */ /* persist connection info in session handle */ diff --git a/lib/connect.h b/lib/connect.h index 8e6f57bee..9b1faf8fb 100644 --- a/lib/connect.h +++ b/lib/connect.h @@ -75,6 +75,8 @@ void Curl_sndbufset(curl_socket_t sockfd); #endif void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd); +void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd); +void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd); void Curl_persistconninfo(struct connectdata *conn); int Curl_closesocket(struct connectdata *conn, curl_socket_t sock); diff --git a/lib/ftp.c b/lib/ftp.c index b18c9ef34..50e7d7dda 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -1940,6 +1940,17 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, #endif { /* normal, direct, ftp connection */ + DEBUGASSERT(ftpc->newhost); + + /* postponed address resolution in case of tcp fastopen */ + if(conn->bits.tcp_fastopen && !conn->bits.reuse && !ftpc->newhost[0]) { + Curl_conninfo_remote(conn, conn->sock[FIRSTSOCKET]); + Curl_safefree(ftpc->newhost); + ftpc->newhost = strdup(control_address(conn)); + if(!ftpc->newhost) + return CURLE_OUT_OF_MEMORY; + } + rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr); if(rc == CURLRESOLV_PENDING) /* BLOCKING */