CURLcode result;
const char *client_ip;
struct ip_quadruple ipquad;
- int is_ipv6;
+ bool is_ipv6;
DEBUGASSERT(ctx);
DEBUGASSERT(ctx->state == HAPROXY_INIT);
/* use this socket from now on */
cf->conn->sock[cf->sockindex] = ctx->sock;
set_local_ip(cf, data);
- if(cf->sockindex == FIRSTSOCKET) {
- cf->conn->primary = ctx->ip;
- #ifdef USE_IPV6
+#ifdef USE_IPV6
+ if(cf->sockindex == FIRSTSOCKET)
cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6);
- #endif
- }
- else {
- cf->conn->secondary = ctx->ip;
- }
+#endif
ctx->active = TRUE;
}
return CURLE_RECV_ERROR;
}
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static CURLcode cf_verboseconnect(struct Curl_easy *data,
+ struct Curl_cfilter *cf)
+{
+ if(Curl_trc_is_verbose(data)) {
+ struct ip_quadruple ipquad;
+ bool is_ipv6;
+ CURLcode result;
+
+ result = Curl_conn_cf_get_ip_info(cf, data, &is_ipv6, &ipquad);
+ if(result)
+ return result;
+
+ infof(data, "Established %sconnection to %s (%s port %u) from %s port %u ",
+ (cf->sockindex == SECONDARYSOCKET) ? "2nd " : "",
+ CURL_CONN_HOST_DISPNAME(data->conn),
+ ipquad.remote_ip, ipquad.remote_port,
+ ipquad.local_ip, ipquad.local_port);
+ }
+ return CURLE_OK;
+}
+#endif
+
CURLcode Curl_conn_connect(struct Curl_easy *data,
int sockindex,
bool blocking,
cf_cntrl_update_info(data, data->conn);
conn_report_connect_stats(data, data->conn);
data->conn->keepalive = curlx_now();
- Curl_verboseconnect(data, data->conn, sockindex);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ result = cf_verboseconnect(data, cf);
+#endif
goto out;
}
else if(result) {
return FALSE;
}
+CURLcode Curl_conn_get_ip_info(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex,
+ bool *is_ipv6, struct ip_quadruple *ipquad)
+{
+ struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL;
+ return Curl_conn_cf_get_ip_info(cf, data, is_ipv6, ipquad);
+}
+
bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
{
struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL;
CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf,
struct Curl_easy *data,
- int *is_ipv6, struct ip_quadruple *ipquad)
+ bool *is_ipv6, struct ip_quadruple *ipquad)
{
- if(cf)
- return cf->cft->query(cf, data, CF_QUERY_IP_INFO, is_ipv6, ipquad);
- return CURLE_UNKNOWN_OPTION;
+ CURLcode result = CURLE_UNKNOWN_OPTION;
+ if(cf) {
+ int ipv6 = 0;
+ result = cf->cft->query(cf, data, CF_QUERY_IP_INFO, &ipv6, ipquad);
+ *is_ipv6 = !!ipv6;
+ }
+ return result;
}
curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex)
CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf,
struct Curl_easy *data,
- int *is_ipv6, struct ip_quadruple *ipquad);
+ bool *is_ipv6, struct ip_quadruple *ipquad);
bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf,
struct Curl_easy *data);
struct connectdata *conn, int sockindex,
struct curl_tlssessioninfo *info);
+CURLcode Curl_conn_get_ip_info(struct Curl_easy *data,
+ struct connectdata *conn, int sockindex,
+ bool *is_ipv6, struct ip_quadruple *ipquad);
+
/**
* Connection provides multiplexing of easy handles at `socketindex`.
*/
} cf_connect_state;
struct cf_he_ctx {
- int transport;
cf_ip_connect_create *cf_create;
cf_connect_state state;
struct eyeballer *baller[2];
struct eyeballer *winner;
struct curltime started;
+ int transport;
};
/* when there are more than one IP address left to use, this macro returns how
struct curltime now;
size_t i;
int ongoing, not_started;
- const char *hostname;
/* Check if any of the conn->tempsock we use for establishing connections
* succeeded and, if so, close any ongoing other ones.
}
}
+ {
+ const char *hostname, *proxy_name = NULL;
+ int port;
#ifndef CURL_DISABLE_PROXY
- if(conn->bits.socksproxy)
- hostname = conn->socks_proxy.host.name;
- else if(conn->bits.httpproxy)
- hostname = conn->http_proxy.host.name;
- else
+ if(conn->bits.socksproxy)
+ proxy_name = conn->socks_proxy.host.name;
+ else if(conn->bits.httpproxy)
+ proxy_name = conn->http_proxy.host.name;
#endif
- 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 %u after "
- "%" FMT_TIMEDIFF_T " ms: %s",
- hostname, conn->primary.remote_port,
- curlx_timediff(now, data->progress.t_startsingle),
- curl_easy_strerror(result));
+ hostname = conn->bits.conn_to_host ?
+ conn->conn_to_host.name : conn->host.name;
+
+ if(cf->sockindex == SECONDARYSOCKET)
+ port = conn->secondary_port;
+ else if(cf->conn->bits.conn_to_port)
+ port = conn->conn_to_port;
+ else
+ port = conn->remote_port;
+
+ failf(data, "Failed to connect to %s port %u %s%s%safter "
+ "%" FMT_TIMEDIFF_T " ms: %s",
+ hostname, port,
+ proxy_name ? "via " : "",
+ proxy_name ? proxy_name : "",
+ proxy_name ? " " : "",
+ curlx_timediff(now, data->progress.t_startsingle),
+ curl_easy_strerror(result));
+ }
#ifdef SOCKETIMEDOUT
if(SOCKETIMEDOUT == data->state.os_errno)
#ifndef CURL_DISABLE_VERBOSE_STRINGS
if(Curl_trc_cf_is_verbose(cf, data)) {
struct ip_quadruple ipquad;
- int is_ipv6;
+ bool is_ipv6;
if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) {
const char *host;
int port;
}
-static char *control_address(struct connectdata *conn)
+static char *control_address_dup(struct Curl_easy *data,
+ struct connectdata *conn)
{
+ struct ip_quadruple ipquad;
+ bool is_ipv6;
+
/* Returns the control connection IP address.
If a proxy tunnel is used, returns the original hostname instead, because
the effective control connection address is the proxy address,
not the ftp host. */
#ifndef CURL_DISABLE_PROXY
if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
- return conn->host.name;
+ return strdup(conn->host.name);
#endif
- return conn->primary.remote_ip;
+ if(!Curl_conn_get_ip_info(data, conn, FIRSTSOCKET, &is_ipv6, &ipquad))
+ return strdup(ipquad.remote_ip);
+ return NULL;
}
static bool match_pasv_6nums(const char *p,
return CURLE_FTP_WEIRD_PASV_REPLY;
}
ftpc->newport = (unsigned short)num;
- ftpc->newhost = strdup(control_address(conn));
+ ftpc->newhost = control_address_dup(data, conn);
if(!ftpc->newhost)
return CURLE_OUT_OF_MEMORY;
}
infof(data, "Skip %u.%u.%u.%u for data connection, reuse %s instead",
ip[0], ip[1], ip[2], ip[3],
conn->host.name);
- ftpc->newhost = strdup(control_address(conn));
+ ftpc->newhost = control_address_dup(data, conn);
}
else
ftpc->newhost = aprintf("%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy) {
- /*
- * This connection uses a proxy and we need to connect to the proxy again
+ /* This connection uses a proxy and we need to connect to the proxy again
* here. We do not want to rely on a former host lookup that might've
- * expired now, instead we remake the lookup here and now!
- */
+ * expired now, instead we remake the lookup here and now! */
+ struct ip_quadruple ipquad;
+ bool is_ipv6;
const char * const host_name = conn->bits.socksproxy ?
conn->socks_proxy.host.name : conn->http_proxy.host.name;
- (void)Curl_resolv_blocking(data, host_name, conn->primary.remote_port,
- conn->ip_version, &dns);
+
+ result = Curl_conn_get_ip_info(data, data->conn, FIRSTSOCKET,
+ &is_ipv6, &ipquad);
+ if(result)
+ return result;
+
+ (void)Curl_resolv_blocking(data, host_name, ipquad.remote_port,
+ is_ipv6 ? CURL_IPRESOLVE_V6 : CURL_IPRESOLVE_V4,
+ &dns);
/* we connect to the proxy's port */
- connectport = (unsigned short)conn->primary.remote_port;
+ connectport = (unsigned short)ipquad.remote_port;
if(!dns) {
failf(data, "cannot resolve proxy host %s:%hu", host_name, connectport);
/* postponed address resolution in case of tcp fastopen */
if(conn->bits.tcp_fastopen && !conn->bits.reuse && !ftpc->newhost[0]) {
free(ftpc->newhost);
- ftpc->newhost = strdup(control_address(conn));
+ ftpc->newhost = control_address_dup(data, conn);
if(!ftpc->newhost)
return CURLE_OUT_OF_MEMORY;
}
const char *p_accept; /* Accept: string */
unsigned char httpversion;
const char *alpn;
+ const char *info_version = NULL;
/* Always consider the DO phase done after this function call, even if there
may be parts of the request that are not yet sent, since we can deal with
alpn = Curl_conn_get_alpn_negotiated(data, conn);
if(alpn && !strcmp("h3", alpn)) {
DEBUGASSERT(Curl_conn_http_version(data, conn) == 30);
+ info_version = "HTTP/3";
}
else if(alpn && !strcmp("h2", alpn)) {
#ifndef CURL_DISABLE_PROXY
if((Curl_conn_http_version(data, conn) != 20) &&
- conn->bits.proxy && !conn->bits.tunnel_proxy
- ) {
+ conn->bits.proxy && !conn->bits.tunnel_proxy) {
result = Curl_http2_switch(data);
if(result)
goto fail;
}
else
#endif
- DEBUGASSERT(Curl_conn_http_version(data, conn) == 20);
+ DEBUGASSERT(Curl_conn_http_version(data, conn) == 20);
+ info_version = "HTTP/2";
}
else {
/* Check if user wants to use HTTP/2 with clear TCP */
result = Curl_http2_switch(data);
if(result)
goto fail;
+ info_version = "HTTP/2";
}
+ else
+ info_version = "HTTP/1.x";
}
+ if(info_version && !data->conn->bits.reuse)
+ infof(data, "using %s", info_version);
+
/* Add collecting of headers written to client. For a new connection,
* we might have done that already, but reuse
* or multiplex needs it here as well. */
#endif
char *user = NULL;
char *passwd = NULL;
+ struct ip_quadruple ipquad;
+ bool is_ipv6;
*done = TRUE; /* unconditionally */
infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d",
goto quit;
}
+ result = Curl_conn_get_ip_info(data, conn, FIRSTSOCKET, &is_ipv6, &ipquad);
+ if(result)
+ goto quit;
+
/* Get the URL scheme (either ldap or ldaps) */
if(Curl_conn_is_ssl(conn, FIRSTSOCKET))
ldap_ssl = 1;
#ifdef HAVE_LDAP_SSL
#ifdef USE_WIN32_LDAP
/* Win32 LDAP SDK does not support insecure mode without CA! */
- server = ldap_sslinit(host, (curl_ldap_num_t)conn->primary.remote_port, 1);
+ server = ldap_sslinit(host, (curl_ldap_num_t)ipquad.remote_port, 1);
ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
#else
int ldap_option;
result = CURLE_SSL_CERTPROBLEM;
goto quit;
}
- server = ldap_init(host, conn->primary.remote_port);
+ server = ldap_init(host, ipquad.remote_port);
if(!server) {
failf(data, "LDAP local: Cannot connect to %s:%u",
- conn->host.dispname, conn->primary.remote_port);
+ conn->host.dispname, ipquad.remote_port);
result = CURLE_COULDNT_CONNECT;
goto quit;
}
goto quit;
}
else {
- server = ldap_init(host, (curl_ldap_num_t)conn->primary.remote_port);
+ server = ldap_init(host, (curl_ldap_num_t)ipquad.remote_port);
if(!server) {
failf(data, "LDAP local: Cannot connect to %s:%u",
- conn->host.dispname, conn->primary.remote_port);
+ conn->host.dispname, ipquad.remote_port);
result = CURLE_COULDNT_CONNECT;
goto quit;
}
result = connect_SOCKS(cf, sx, data);
if(!result && sx->state == CONNECT_DONE) {
cf->connected = TRUE;
- Curl_verboseconnect(data, conn, cf->sockindex);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ if(Curl_trc_is_verbose(data)) {
+ struct ip_quadruple ipquad;
+ bool is_ipv6;
+ result = Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad);
+ if(result)
+ return result;
+ infof(data, "Opened %sSOCKS connection from %s port %u to %s port %u "
+ "(via %s port %u)",
+ (sockindex == SECONDARYSOCKET) ? "2nd " : "",
+ ipquad.local_ip, ipquad.local_port,
+ sx->hostname, sx->remote_port,
+ ipquad.remote_ip, ipquad.remote_port);
+ }
+#endif
socks_proxy_cf_free(cf);
}
return result;
}
-/*
- * verboseconnect() displays verbose information after a connect
- */
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-void Curl_verboseconnect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
-{
- if(data->set.verbose && sockindex == SECONDARYSOCKET)
- infof(data, "Connected 2nd connection to %s port %u",
- conn->secondary.remote_ip, conn->secondary.remote_port);
- else
- infof(data, "Connected to %s (%s) port %u",
- CURL_CONN_HOST_DISPNAME(conn), conn->primary.remote_ip,
- conn->primary.remote_port);
-#ifndef CURL_DISABLE_HTTP
- if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
- const char *alpn = Curl_conn_get_alpn_negotiated(data, conn);
- if(!alpn || !strcmp("http/1.1", alpn) || !strcmp("http/1.0", alpn))
- infof(data, "using HTTP/1.x");
- else if(!strcmp("h2", alpn))
- infof(data, "using HTTP/2");
- else if(!strcmp("h3", alpn))
- infof(data, "using HTTP/3");
- else
- infof(data, "using ALPN protocol '%s'", alpn);
- }
-#endif
-}
-#endif
-
/*
* Allocate and initialize a new connectdata object.
*/
conn->sockfd = CURL_SOCKET_BAD;
conn->writesockfd = CURL_SOCKET_BAD;
conn->connection_id = -1; /* no ID */
- conn->primary.remote_port = -1; /* unknown at this point */
conn->remote_port = -1; /* unknown at this point */
/* Default protocol-independent behavior does not support persistent
valid = FALSE;
}
if(valid)
- conn->primary.remote_port = conn->remote_port = (unsigned short)port;
+ conn->remote_port = (unsigned short)port;
}
(void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
static CURLcode setup_connection_internals(struct Curl_easy *data,
struct connectdata *conn)
{
- const struct Curl_handler *p;
const char *hostname;
int port;
CURLcode result;
- /* Perform setup complement if some. */
- p = conn->handler;
-
- if(p->setup_connection) {
- result = (*p->setup_connection)(data, conn);
-
+ if(conn->handler->setup_connection) {
+ result = conn->handler->setup_connection(data, conn);
if(result)
return result;
-
- p = conn->handler; /* May have changed. */
}
- if(conn->primary.remote_port < 0)
- /* we check for -1 here since if proxy was detected already, this was
- likely already set to the proxy port */
- conn->primary.remote_port = p->defport;
-
/* Now create the destination name */
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
hostname = conn->http_proxy.host.name;
- port = conn->primary.remote_port;
+ port = conn->http_proxy.port;
}
else
#endif
port = CURL_DEFAULT_PROXY_PORT;
}
}
- if(port >= 0) {
+ if(port >= 0)
proxyinfo->port = port;
- if(conn->primary.remote_port < 0 || sockstype ||
- !conn->socks_proxy.host.rawalloc)
- conn->primary.remote_port = port;
- }
/* now, clone the proxy hostname */
uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE);
struct Curl_dns_entry **pdns)
{
struct hostname *ehost;
+ int eport;
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
const char *peertype = "host";
CURLcode result;
if(CONN_IS_PROXIED(conn)) {
ehost = conn->bits.socksproxy ? &conn->socks_proxy.host :
&conn->http_proxy.host;
+ eport = conn->bits.socksproxy ? conn->socks_proxy.port :
+ conn->http_proxy.port;
peertype = "proxy";
}
else
ehost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host;
/* If not connecting via a proxy, extract the port from the URL, if it is
* there, thus overriding any defaults that might have been set above. */
- conn->primary.remote_port = conn->bits.conn_to_port ? conn->conn_to_port :
- conn->remote_port;
+ eport = conn->bits.conn_to_port ? conn->conn_to_port : conn->remote_port;
}
/* Resolve target host right on */
return CURLE_OUT_OF_MEMORY;
result = Curl_resolv_timeout(data, conn->hostname_resolve,
- conn->primary.remote_port, conn->ip_version,
+ eport, conn->ip_version,
pdns, timeout_ms);
DEBUGASSERT(!result || !*pdns);
if(result == CURLE_AGAIN) {
#define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
specified */
-#ifdef CURL_DISABLE_VERBOSE_STRINGS
-#define Curl_verboseconnect(x,y,z) Curl_nop_stmt
-#else
-void Curl_verboseconnect(struct Curl_easy *data, struct connectdata *conn,
- int sockindex);
-#endif
-
/**
* Return TRUE iff the given connection is considered dead.
* @param nowp NULL or pointer to time being checked against.
struct proxy_info socks_proxy;
struct proxy_info http_proxy;
#endif
- /* 'primary' and 'secondary' get filled with IP quadruple
- (local/remote numerical ip address and port) whenever a connect is
- *attempted*.
- When more than one address is tried for a connection these will hold data
- for the last attempt. When the connection is actually established
- these are updated with data which comes directly from the socket. */
- struct ip_quadruple primary;
- struct ip_quadruple secondary;
char *user; /* username string, allocated */
char *passwd; /* password string, allocated */
char *options; /* options string, allocated */
def get_data_ports(self, r: ExecResult) -> List[int]:
return [int(m.group(1)) for line in r.trace_lines if
- (m := re.match(r'.*Connected 2nd connection to .* port (\d+)', line))]
+ (m := re.match(r'.*Established 2nd connection to .* \(\S+ port (\d+)\)', line))]