diff --git a/lib/core-net/private-lib-core-net.h b/lib/core-net/private-lib-core-net.h index de27e7bc6..57081fff9 100644 --- a/lib/core-net/private-lib-core-net.h +++ b/lib/core-net/private-lib-core-net.h @@ -1262,7 +1262,10 @@ _lws_generic_transaction_completed_active_conn(struct lws *wsi); #define ACTIVE_CONNS_QUEUED 2 int -lws_vhost_active_conns(struct lws *wsi, struct lws **nwsi); +lws_vhost_active_conns(struct lws *wsi, struct lws **nwsi, const char *adsin); + +const char * +lws_wsi_client_stash_item(struct lws *wsi, int stash_idx, int hdr_idx); #ifdef __cplusplus }; diff --git a/lib/core-net/vhost.c b/lib/core-net/vhost.c index 1882281e8..e38f79659 100644 --- a/lib/core-net/vhost.c +++ b/lib/core-net/vhost.c @@ -1390,12 +1390,8 @@ lws_get_vhost_by_name(struct lws_context *context, const char *name) */ int -lws_vhost_active_conns(struct lws *wsi, struct lws **nwsi) +lws_vhost_active_conns(struct lws *wsi, struct lws **nwsi, const char *adsin) { - const char *adsin; - - adsin = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS); - lws_vhost_lock(wsi->vhost); /* ----------------------------------- { */ lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, @@ -1406,7 +1402,14 @@ lws_vhost_active_conns(struct lws *wsi, struct lws **nwsi) lwsl_debug("%s: check %s %s %d %d\n", __func__, adsin, w->cli_hostname_copy, wsi->c_port, w->c_port); - if (w != wsi && w->cli_hostname_copy && + if (w != wsi && + /* + * "same internet protocol"... this is a bit tricky, + * since h2 start out as h1 + */ + (w->role_ops == wsi->role_ops || + (lwsi_role_http(w) && lwsi_role_http(wsi))) && + w->cli_hostname_copy && !strcmp(adsin, w->cli_hostname_copy) && #if defined(LWS_WITH_TLS) (wsi->tls.use_ssl & LCCSCF_USE_SSL) == diff --git a/lib/core-net/wsi.c b/lib/core-net/wsi.c index 7f492d130..d8677b0c4 100644 --- a/lib/core-net/wsi.c +++ b/lib/core-net/wsi.c @@ -959,3 +959,19 @@ lws_http_mark_sse(struct lws *wsi) return 0; } + + +const char * +lws_wsi_client_stash_item(struct lws *wsi, int stash_idx, int hdr_idx) +{ + /* try the generic client stash */ + if (wsi->stash) + return wsi->stash->cis[stash_idx]; + +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + /* if not, use the ah stash if applicable */ + return lws_hdr_simple_ptr(wsi, hdr_idx); +#else + return NULL; +#endif +} diff --git a/lib/roles/http/client/client-handshake.c b/lib/roles/http/client/client-handshake.c index efc3d563c..496b5315f 100644 --- a/lib/roles/http/client/client-handshake.c +++ b/lib/roles/http/client/client-handshake.c @@ -64,10 +64,8 @@ lws_client_connect_4_established(struct lws *wsi, struct lws *wsi_piggyback, const char *cce = ""; int n, m, rawish = 0; - if (wsi->stash) - meth = wsi->stash->cis[CIS_METHOD]; - else - meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD); + meth = lws_wsi_client_stash_item(wsi, CIS_METHOD, + _WSI_TOKEN_CLIENT_METHOD); if (meth && !strcmp(meth, "RAW")) rawish = 1; @@ -83,11 +81,10 @@ lws_client_connect_4_established(struct lws *wsi, struct lws *wsi_piggyback, if (wsi->vhost->http.http_proxy_port) { const char *cpa; - if (wsi->stash) - cpa = wsi->stash->cis[CIS_ADDRESS]; - else - cpa = lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_PEER_ADDRESS); + cpa = lws_wsi_client_stash_item(wsi, CIS_ADDRESS, + _WSI_TOKEN_CLIENT_PEER_ADDRESS); + if (!cpa) + goto failed; lwsl_info("%s: going via proxy\n", __func__); @@ -548,10 +545,8 @@ ads_known: lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, AWAITING_TIMEOUT); - if (wsi->stash) - iface = wsi->stash->cis[CIS_IFACE]; - else - iface = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE); + iface = lws_wsi_client_stash_item(wsi, CIS_IFACE, + _WSI_TOKEN_CLIENT_IFACE); if (iface && *iface) { n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0, @@ -698,12 +693,13 @@ failed1: struct lws * lws_client_connect_2_dnsreq(struct lws *wsi) { - const char *meth = NULL, *ads; struct addrinfo *result = NULL; + const char *meth = NULL, *ads; #if defined(LWS_WITH_IPV6) struct sockaddr_in addr; const char *iface; #endif + const char *adsin; int n, port = 0; struct lws *w; @@ -713,10 +709,13 @@ lws_client_connect_2_dnsreq(struct lws *wsi) return wsi; } - if (wsi->stash) - meth = wsi->stash->cis[CIS_METHOD]; - else - meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD); + /* + * The first job is figure out if we want to pipeline on or just join + * an existing "active connection" to the same place + */ + + meth = lws_wsi_client_stash_item(wsi, CIS_METHOD, + _WSI_TOKEN_CLIENT_METHOD); /* we only pipeline connections that said it was okay */ @@ -734,7 +733,10 @@ lws_client_connect_2_dnsreq(struct lws *wsi) /* consult active connections to find out disposition */ - switch (lws_vhost_active_conns(wsi, &w)) { + adsin = lws_wsi_client_stash_item(wsi, CIS_ADDRESS, + _WSI_TOKEN_CLIENT_PEER_ADDRESS); + + switch (lws_vhost_active_conns(wsi, &w, adsin)) { case ACTIVE_CONNS_SOLO: break; case ACTIVE_CONNS_MUXED: @@ -756,17 +758,19 @@ solo: if (wsi->stash && wsi->stash->cis[CIS_HOST]) wsi->cli_hostname_copy = lws_strdup(wsi->stash->cis[CIS_HOST]); +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) else { char *pa = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS); if (pa) wsi->cli_hostname_copy = lws_strdup(pa); } +#endif } /* - * If we made our own connection, and we're doing a method that can take - * a pipeline, we are an "active client connection". + * If we made our own connection, and we're doing a method that can + * take a pipeline, we are an "active client connection". * * Add ourselves to the vhost list of those so that others can * piggyback on our transaction queue