1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

connect: fix cli_hostname leak breaking staggered h1 pipeline

This commit is contained in:
Andy Green 2021-06-25 09:13:57 +01:00
parent c2e10db5f2
commit c0680fa2b6
3 changed files with 58 additions and 45 deletions

View file

@ -128,7 +128,7 @@ struct lws *
lws_client_connect_2_dnsreq(struct lws *wsi)
{
struct addrinfo *result = NULL;
const char *meth = NULL, *ads;
const char *meth = NULL;
#if defined(LWS_WITH_IPV6)
struct sockaddr_in addr;
const char *iface;
@ -151,17 +151,11 @@ lws_client_connect_2_dnsreq(struct lws *wsi)
*/
if (!wsi->cli_hostname_copy) {
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
const char *pa = lws_wsi_client_stash_item(wsi, CIS_HOST,
_WSI_TOKEN_CLIENT_PEER_ADDRESS);
if (pa)
wsi->cli_hostname_copy = lws_strdup(pa);
}
/*
@ -171,6 +165,10 @@ lws_client_connect_2_dnsreq(struct lws *wsi)
meth = lws_wsi_client_stash_item(wsi, CIS_METHOD,
_WSI_TOKEN_CLIENT_METHOD);
/* consult active connections to find out disposition */
adsin = lws_wsi_client_stash_item(wsi, CIS_ADDRESS,
_WSI_TOKEN_CLIENT_PEER_ADDRESS);
/* we only pipeline connections that said it was okay */
@ -187,11 +185,6 @@ lws_client_connect_2_dnsreq(struct lws *wsi)
strcmp(meth, "UDP") && strcmp(meth, "MQTT"))
goto solo;
/* consult active connections to find out disposition */
adsin = lws_wsi_client_stash_item(wsi, CIS_ADDRESS,
_WSI_TOKEN_CLIENT_PEER_ADDRESS);
if (!adsin)
/*
* This cannot happen since user code must provide the client
@ -256,24 +249,19 @@ solo:
lws_context_unlock(wsi->a.context);
}
/*
* unix socket destination?
*/
if (wsi->stash)
ads = wsi->stash->cis[CIS_ADDRESS];
else
ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
/*
* Since address must be given at client creation, should not be
* possible, but necessary to satisfy coverity
*/
if (!ads)
if (!adsin)
return NULL;
#if defined(LWS_WITH_UNIX_SOCK)
if (*ads == '+') {
/*
* unix socket destination?
*/
if (*adsin == '+') {
wsi->unix_skt = 1;
n = 0;
goto next_step;
@ -305,7 +293,7 @@ solo:
* Priority 1: connect to http proxy */
if (wsi->a.vhost->http.http_proxy_port) {
ads = wsi->a.vhost->http.http_proxy_address;
adsin = wsi->a.vhost->http.http_proxy_address;
port = (int)wsi->a.vhost->http.http_proxy_port;
#else
if (0) {
@ -317,7 +305,7 @@ solo:
} else if (wsi->a.vhost->socks_proxy_port) {
lwsl_client("Sending SOCKS Greeting\n");
ads = wsi->a.vhost->socks_proxy_address;
adsin = wsi->a.vhost->socks_proxy_address;
port = (int)wsi->a.vhost->socks_proxy_port;
#endif
} else {
@ -334,7 +322,7 @@ solo:
*/
lwsi_set_state(wsi, LRS_WAITING_DNS);
lwsl_info("%s: %s: lookup %s:%u\n", __func__, wsi->lc.gutag, ads, port);
lwsl_info("%s: %s: lookup %s:%u\n", __func__, wsi->lc.gutag, adsin, port);
wsi->conn_port = (uint16_t)port;
#if !defined(LWS_WITH_SYS_ASYNC_DNS)
@ -343,7 +331,7 @@ solo:
/*
* blocking dns resolution
*/
n = lws_getaddrinfo46(wsi, ads, &result);
n = lws_getaddrinfo46(wsi, adsin, &result);
}
#else
/* this is either FAILED, CONTINUING, or already called connect_4 */
@ -351,7 +339,7 @@ solo:
if (lws_fi(&wsi->fic, "dnsfail"))
return lws_client_connect_3_connect(wsi, NULL, NULL, -4, NULL);
else
n = lws_async_dns_query(wsi->a.context, wsi->tsi, ads,
n = lws_async_dns_query(wsi->a.context, wsi->tsi, adsin,
LWS_ADNS_RECORD_A, lws_client_connect_3_connect,
wsi, NULL);
@ -367,7 +355,7 @@ solo:
#if defined(LWS_WITH_UNIX_SOCK)
next_step:
#endif
return lws_client_connect_3_connect(wsi, ads, result, n, NULL);
return lws_client_connect_3_connect(wsi, adsin, result, n, NULL);
//#if defined(LWS_WITH_SYS_ASYNC_DNS)
failed1:

View file

@ -244,7 +244,7 @@ lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost,
{
int n = 0;
if (!vhost || !prot)
if (!vhost || !prot || !vhost->protocols || !prot->name)
return NULL;
/* allocate the vh priv array only on demand */
@ -252,6 +252,7 @@ lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost,
vhost->protocol_vh_privs = (void **)lws_zalloc(
(size_t)vhost->count_protocols * sizeof(void *),
"protocol_vh_privs");
if (!vhost->protocol_vh_privs)
return NULL;
}
@ -261,12 +262,17 @@ lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost,
if (n == vhost->count_protocols) {
n = 0;
while (n < vhost->count_protocols &&
strcmp(vhost->protocols[n].name, prot->name))
while (n < vhost->count_protocols) {
if (vhost->protocols[n].name &&
!strcmp(vhost->protocols[n].name, prot->name))
break;
n++;
}
if (n == vhost->count_protocols)
if (n == vhost->count_protocols) {
lwsl_err("%s: unknown protocol %p\n", __func__, prot);
return NULL;
}
}
vhost->protocol_vh_privs[n] = lws_zalloc((size_t)size, "vh priv");
@ -279,7 +285,8 @@ lws_protocol_vh_priv_get(struct lws_vhost *vhost,
{
int n = 0;
if (!vhost || !vhost->protocol_vh_privs || !prot)
if (!vhost || !vhost->protocols ||
!vhost->protocol_vh_privs || !prot || !prot->name)
return NULL;
while (n < vhost->count_protocols && &vhost->protocols[n] != prot)
@ -287,9 +294,12 @@ lws_protocol_vh_priv_get(struct lws_vhost *vhost,
if (n == vhost->count_protocols) {
n = 0;
while (n < vhost->count_protocols &&
strcmp(vhost->protocols[n].name, prot->name))
while (n < vhost->count_protocols) {
if (vhost->protocols[n].name &&
!strcmp(vhost->protocols[n].name, prot->name))
break;
n++;
}
if (n == vhost->count_protocols) {
lwsl_err("%s: unknown protocol %p\n", __func__, prot);
@ -442,12 +452,25 @@ lws_protocol_init_vhost(struct lws_vhost *vh, int *any)
* prepared in case the protocol handler wants to touch them
*/
if (pvo || !vh->pvo) {
if (pvo
#if !defined(LWS_WITH_PLUGINS)
/*
* with plugins, you have to explicitly
* instantiate them with pvos
*/
|| !vh->pvo
#endif
) {
lwsl_info("%s: init %s.%s\n", __func__, vh->name,
vh->protocols[n].name);
if (vh->protocols[n].callback((struct lws *)lwsa,
LWS_CALLBACK_PROTOCOL_INIT, NULL,
(void *)(pvo ? pvo->options : NULL), 0)) {
#if !defined(LWS_WITH_PLUGINS)
(void *)(pvo ? pvo->options : NULL),
#else
(void *)pvo->options,
#endif
0)) {
if (vh->protocol_vh_privs && vh->protocol_vh_privs[n]) {
lws_free(vh->protocol_vh_privs[n]);
vh->protocol_vh_privs[n] = NULL;

View file

@ -1065,8 +1065,10 @@ _lws_generic_transaction_completed_active_conn(struct lws **_wsi, char take_vh_l
/* take over his copy of his endpoint as an active connection */
wnew->cli_hostname_copy = wsi->cli_hostname_copy;
wsi->cli_hostname_copy = NULL;
if (!wnew->cli_hostname_copy && wsi->cli_hostname_copy) {
wnew->cli_hostname_copy = wsi->cli_hostname_copy;
wsi->cli_hostname_copy = NULL;
}
wnew->keep_warm_secs = wsi->keep_warm_secs;
/*