mirror of
https://github.com/moparisthebest/curl
synced 2024-12-23 16:48:49 -05:00
ftp: retry getpeername for FTP with TCP_FASTOPEN
In the case of TFO, the remote host name is not resolved at the connetion time. For FTP that has lead to missing hostname for the secondary connection. Therefore the name resolution is done at the time, when FTP requires it. Fixes #6252 Closes #6265 Closes #6282
This commit is contained in:
parent
7a6fdd503d
commit
2c0d721215
104
lib/connect.c
104
lib/connect.c
@ -671,59 +671,71 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
|
|||||||
return FALSE;
|
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
|
/* retrieves the start/end point information of a socket of an established
|
||||||
connection */
|
connection */
|
||||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
||||||
{
|
{
|
||||||
if(conn->transport == TRNSPRT_TCP) {
|
if(conn->transport == TRNSPRT_TCP) {
|
||||||
#if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
|
|
||||||
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
|
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
|
||||||
struct Curl_easy *data = conn->data;
|
Curl_conninfo_remote(conn, sockfd);
|
||||||
char buffer[STRERROR_LEN];
|
Curl_conninfo_local(conn, sockfd);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
#else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */
|
|
||||||
(void)sockfd; /* unused */
|
|
||||||
#endif
|
|
||||||
} /* end of TCP-only section */
|
} /* end of TCP-only section */
|
||||||
|
|
||||||
/* persist connection info in session handle */
|
/* persist connection info in session handle */
|
||||||
|
@ -75,6 +75,8 @@ void Curl_sndbufset(curl_socket_t sockfd);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
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);
|
void Curl_persistconninfo(struct connectdata *conn);
|
||||||
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
|
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
|
||||||
|
|
||||||
|
11
lib/ftp.c
11
lib/ftp.c
@ -1940,6 +1940,17 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* normal, direct, ftp connection */
|
/* 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);
|
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
|
Loading…
Reference in New Issue
Block a user