cf_h1_proxy_connect,
cf_h1_proxy_close,
Curl_cf_def_shutdown,
- Curl_cf_http_proxy_get_host,
cf_h1_proxy_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_cntrl,
Curl_cf_def_conn_is_alive,
Curl_cf_def_conn_keep_alive,
- Curl_cf_def_query,
+ Curl_cf_http_proxy_query,
};
CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf_at,
struct cf_h2_proxy_ctx *ctx = cf->ctx;
switch(query) {
+ case CF_QUERY_HOST_PORT:
+ *pres1 = (int)cf->conn->http_proxy.port;
+ *((const char **)pres2) = cf->conn->http_proxy.host.name;
+ return CURLE_OK;
case CF_QUERY_NEED_FLUSH: {
if(!Curl_bufq_is_empty(&ctx->outbufq) ||
!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) {
cf_h2_proxy_connect,
cf_h2_proxy_close,
cf_h2_proxy_shutdown,
- Curl_cf_http_proxy_get_host,
cf_h2_proxy_adjust_pollset,
cf_h2_proxy_data_pending,
cf_h2_proxy_send,
cf_haproxy_connect,
cf_haproxy_close,
Curl_cf_def_shutdown,
- Curl_cf_def_get_host,
cf_haproxy_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
cf_hc_connect,
cf_hc_close,
cf_hc_shutdown,
- Curl_cf_def_get_host,
cf_hc_adjust_pollset,
cf_hc_data_pending,
Curl_cf_def_send,
return result;
}
-static void cf_socket_get_host(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char **phost,
- const char **pdisplay_host,
- int *pport)
-{
- struct cf_socket_ctx *ctx = cf->ctx;
- (void)data;
- *phost = cf->conn->host.name;
- *pdisplay_host = cf->conn->host.dispname;
- *pport = ctx->ip.remote_port;
-}
-
static void cf_socket_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct easy_pollset *ps)
cf_tcp_connect,
cf_socket_close,
cf_socket_shutdown,
- cf_socket_get_host,
cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
cf_udp_connect,
cf_socket_close,
cf_socket_shutdown,
- cf_socket_get_host,
cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
cf_tcp_connect,
cf_socket_close,
cf_socket_shutdown,
- cf_socket_get_host,
cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
cf_tcp_accept_connect,
cf_socket_close,
cf_socket_shutdown,
- cf_socket_get_host,
cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
static void conn_report_connect_stats(struct Curl_easy *data,
struct connectdata *conn);
-void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
- const char **phost, const char **pdisplay_host,
- int *pport)
-{
- if(cf->next)
- cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
- else {
- *phost = cf->conn->host.name;
- *pdisplay_host = cf->conn->host.dispname;
- *pport = cf->conn->primary.remote_port;
- }
-}
-
void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct easy_pollset *ps)
return Curl_poll(pfds, npfds, timeout_ms);
}
-void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
- const char **phost, const char **pdisplay_host,
- int *pport)
+void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex,
+ const char **phost, int *pport)
{
- struct Curl_cfilter *cf;
+ struct Curl_cfilter *cf, *cf_proxy = NULL;
DEBUGASSERT(data->conn);
cf = data->conn->cfilter[sockindex];
- if(cf) {
- cf->cft->get_host(cf, data, phost, pdisplay_host, pport);
+ /* Find the "lowest" tunneling proxy filter that has not connected yet. */
+ while(cf && !cf->connected) {
+ if((cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY)) ==
+ (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY))
+ cf_proxy = cf;
+ cf = cf->next;
}
- else {
- /* Some filter ask during shutdown for this, mainly for debugging
- * purposes. We hand out the defaults, however this is not always
- * accurate, as the connection might be tunneled, etc. But all that
- * state is already gone here. */
+ /* cf_proxy (!= NULL) is not connected yet. It is talking
+ * to an interim host and any authentication or other things apply
+ * to this interim host and port. */
+ if(!cf_proxy || cf_proxy->cft->query(cf_proxy, data, CF_QUERY_HOST_PORT,
+ pport, CURL_UNCONST(phost))) {
+ /* Everything connected or query unsuccessful, the overall
+ * connection's destination is the answer */
*phost = data->conn->host.name;
- *pdisplay_host = data->conn->host.dispname;
*pport = data->conn->remote_port;
}
}
struct Curl_easy *data,
bool *done);
-/* Return the hostname and port the connection goes to.
- * This may change with the connection state of filters when tunneling
- * is involved.
- * @param cf the filter to ask
- * @param data the easy handle currently active
- * @param phost on return, points to the relevant, real hostname.
- * this is owned by the connection.
- * @param pdisplay_host on return, points to the printable hostname.
- * this is owned by the connection.
- * @param pport on return, contains the port number
- */
-typedef void Curl_cft_get_host(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char **phost,
- const char **pdisplay_host,
- int *pport);
-
struct easy_pollset;
/* Passing in an easy_pollset for monitoring of sockets, let
* - CF_QUERY_NEED_FLUSH: TRUE iff any of the filters have unsent data
* - CF_QUERY_IP_INFO: res1 says if connection used IPv6, res2 is the
* ip quadruple
+ * - CF_QUERY_HOST_PORT: the remote hostname and port a filter talks to
*/
/* query res1 res2 */
#define CF_QUERY_MAX_CONCURRENT 1 /* number - */
/* pass in a `const struct Curl_sockaddr_ex **` as `pres2`. Gets set
* to NULL when not connected. */
#define CF_QUERY_REMOTE_ADDR 10 /* - `Curl_sockaddr_ex *` */
+#define CF_QUERY_HOST_PORT 11 /* port const char * */
/**
* Query the cfilter for properties. Filters ignorant of a query will
Curl_cft_connect *do_connect; /* establish connection */
Curl_cft_close *do_close; /* close conn */
Curl_cft_shutdown *do_shutdown; /* shutdown conn */
- Curl_cft_get_host *get_host; /* host filter talks to */
Curl_cft_adjust_pollset *adjust_pollset; /* adjust transfer poll set */
Curl_cft_data_pending *has_data_pending;/* conn has data pending */
Curl_cft_send *do_send; /* send data */
/* Default implementations for the type functions, implementing pass-through
* the filter chain. */
-void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
- const char **phost, const char **pdisplay_host,
- int *pport);
void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct easy_pollset *ps);
#ifdef UNITTESTS
void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
#endif
-void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
- const char **phost, const char **pdisplay_host,
- int *pport);
+
+/**
+ * Get the remote hostname and port that the connection is currently
+ * talking to (or will talk to).
+ * Once connected or before connect starts,
+ * it is `conn->host.name` and `conn->remote_port`.
+ * During connect, when tunneling proxies are involved (http or socks),
+ * it will be the name and port the proxy currently negotiates with.
+ */
+void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex,
+ const char **phost, int *pport);
/**
* Get the maximum number of parallel transfers the connection
struct ip_quadruple ipquad;
int is_ipv6;
if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) {
- const char *host, *disphost;
+ const char *host;
int port;
- cf->next->cft->get_host(cf->next, data, &host, &disphost, &port);
+ Curl_conn_get_current_host(data, cf->sockindex, &host, &port);
CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u",
- disphost, ipquad.remote_ip, ipquad.remote_port);
+ host, ipquad.remote_ip, ipquad.remote_port);
}
}
data->info.numconnects++; /* to track the # of connections made */
cf_he_connect,
cf_he_close,
cf_he_shutdown,
- Curl_cf_def_get_host,
cf_he_adjust_pollset,
cf_he_data_pending,
Curl_cf_def_send,
cf_setup_connect,
cf_setup_close,
Curl_cf_def_shutdown,
- Curl_cf_def_get_host,
Curl_cf_def_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
const char *service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] :
sctx->sasl->params->service;
- const char *hostname, *disp_hostname;
+ const char *hostname;
int port;
- Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
+ Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port);
sctx->mech = SASL_MECH_STRING_NTLM;
sctx->state1 = SASL_NTLM;
if(sctx->user && oauth_bearer &&
(sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) {
- const char *hostname, *disp_hostname;
+ const char *hostname;
int port;
- Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
+ Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port);
sctx->mech = SASL_MECH_STRING_OAUTHBEARER;
sctx->state1 = SASL_OAUTH2;
struct connectdata *conn = data->conn;
saslstate newstate = SASL_FINAL;
struct bufref resp;
- const char *hostname, *disp_hostname;
+ const char *hostname;
int port;
#if defined(USE_KERBEROS5) || defined(USE_NTLM) \
|| !defined(CURL_DISABLE_DIGEST_AUTH)
const char *oauth_bearer = data->set.str[STRING_BEARER];
struct bufref serverdata;
- Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
+ Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port);
Curl_bufref_init(&serverdata);
Curl_bufref_init(&resp);
*progress = SASL_INPROGRESS;
cf_h2_connect,
cf_h2_close,
cf_h2_shutdown,
- Curl_cf_def_get_host,
cf_h2_adjust_pollset,
cf_h2_data_pending,
cf_h2_send,
return result;
}
-void Curl_cf_http_proxy_get_host(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char **phost,
- const char **pdisplay_host,
- int *pport)
+CURLcode Curl_cf_http_proxy_query(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query, int *pres1, void *pres2)
{
- (void)data;
- if(!cf->connected) {
- *phost = cf->conn->http_proxy.host.name;
- *pdisplay_host = cf->conn->http_proxy.host.dispname;
- *pport = (int)cf->conn->http_proxy.port;
- }
- else {
- cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
+ switch(query) {
+ case CF_QUERY_HOST_PORT:
+ *pres1 = (int)cf->conn->http_proxy.port;
+ *((const char **)pres2) = cf->conn->http_proxy.host.name;
+ return CURLE_OK;
+ default:
+ break;
}
+ return cf->next ?
+ cf->next->cft->query(cf->next, data, query, pres1, pres2) :
+ CURLE_UNKNOWN_OPTION;
}
static void http_proxy_cf_destroy(struct Curl_cfilter *cf,
http_proxy_cf_connect,
http_proxy_cf_close,
Curl_cf_def_shutdown,
- Curl_cf_http_proxy_get_host,
Curl_cf_def_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_cntrl,
Curl_cf_def_conn_is_alive,
Curl_cf_def_conn_keep_alive,
- Curl_cf_def_query,
+ Curl_cf_http_proxy_query,
};
CURLcode Curl_cf_http_proxy_insert_after(struct Curl_cfilter *cf_at,
/* Default proxy timeout in milliseconds */
#define PROXY_TIMEOUT (3600*1000)
-void Curl_cf_http_proxy_get_host(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char **phost,
- const char **pdisplay_host,
- int *pport);
+CURLcode Curl_cf_http_proxy_query(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query, int *pres1, void *pres2);
CURLcode Curl_cf_http_proxy_insert_after(struct Curl_cfilter *cf_at,
struct Curl_easy *data);
socks_proxy_cf_free(cf);
}
-static void socks_cf_get_host(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char **phost,
- const char **pdisplay_host,
- int *pport)
+static CURLcode socks_cf_query(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query, int *pres1, void *pres2)
{
- (void)data;
- if(!cf->connected) {
- *phost = cf->conn->socks_proxy.host.name;
- *pdisplay_host = cf->conn->http_proxy.host.dispname;
- *pport = (int)cf->conn->socks_proxy.port;
- }
- else {
- cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
+ struct socks_state *sx = cf->ctx;
+
+ switch(query) {
+ case CF_QUERY_HOST_PORT:
+ *pres1 = sx->remote_port;
+ *((const char **)pres2) = sx->hostname;
+ return CURLE_OK;
+ default:
+ break;
}
+ return cf->next ?
+ cf->next->cft->query(cf->next, data, query, pres1, pres2) :
+ CURLE_UNKNOWN_OPTION;
}
struct Curl_cftype Curl_cft_socks_proxy = {
socks_proxy_cf_connect,
socks_proxy_cf_close,
Curl_cf_def_shutdown,
- socks_cf_get_host,
socks_cf_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_cntrl,
Curl_cf_def_conn_is_alive,
Curl_cf_def_conn_keep_alive,
- Curl_cf_def_query,
+ socks_cf_query,
};
CURLcode Curl_cf_socks_proxy_insert_after(struct Curl_cfilter *cf_at,
cf_msh3_connect,
cf_msh3_close,
Curl_cf_def_shutdown,
- Curl_cf_def_get_host,
cf_msh3_adjust_pollset,
cf_msh3_data_pending,
cf_msh3_send,
cf_ngtcp2_connect,
cf_ngtcp2_close,
cf_ngtcp2_shutdown,
- Curl_cf_def_get_host,
cf_ngtcp2_adjust_pollset,
cf_ngtcp2_data_pending,
cf_ngtcp2_send,
cf_osslq_connect,
cf_osslq_close,
cf_osslq_shutdown,
- Curl_cf_def_get_host,
cf_osslq_adjust_pollset,
cf_osslq_data_pending,
cf_osslq_send,
cf_quiche_connect,
cf_quiche_close,
cf_quiche_shutdown,
- Curl_cf_def_get_host,
cf_quiche_adjust_pollset,
cf_quiche_data_pending,
cf_quiche_send,
ssl_cf_connect,
ssl_cf_close,
ssl_cf_shutdown,
- Curl_cf_def_get_host,
ssl_cf_adjust_pollset,
ssl_cf_data_pending,
ssl_cf_send,
ssl_cf_connect,
ssl_cf_close,
ssl_cf_shutdown,
- Curl_cf_def_get_host,
ssl_cf_adjust_pollset,
ssl_cf_data_pending,
ssl_cf_send,
cf_test_connect,
Curl_cf_def_close,
Curl_cf_def_shutdown,
- Curl_cf_def_get_host,
cf_test_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,