diff --git a/lib/client-handshake.c b/lib/client-handshake.c index e335cc71..dc6de916 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -12,7 +12,7 @@ lws_client_connect_2(struct lws *wsi) struct sockaddr_in server_addr4; struct lws_pollfd pfd; struct sockaddr *v; - const char *cce = ""; + const char *cce = "", *iface; int n, plen = 0; const char *ads; @@ -240,10 +240,14 @@ lws_client_connect_2(struct lws *wsi) lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, AWAITING_TIMEOUT); - n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0, wsi->vhost->iface); - if (n < 0) { - cce = "unable to bind socket"; - goto failed; + iface = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE); + + if (iface) { + n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0, iface); + if (n < 0) { + cce = "unable to bind socket"; + goto failed; + } } } @@ -420,7 +424,7 @@ LWS_VISIBLE struct lws * lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, const char *path, const char *host) { - char origin[300] = "", protocol[300] = "", method[32] = "", *p; + char origin[300] = "", protocol[300] = "", method[32] = "", iface[16] = "", *p; struct lws *wsi = *pwsi; if (wsi->redirects == 3) { @@ -450,6 +454,10 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, if (p) strncpy(method, p, sizeof(method) - 1); + p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE); + if (p) + strncpy(method, p, sizeof(iface) - 1); + lwsl_debug("redirect ads='%s', port=%d, path='%s', ssl = %d\n", address, port, path, ssl); @@ -485,6 +493,11 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, method)) return NULL; + if (iface[0]) + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE, + iface)) + return NULL; + origin[0] = '/'; strncpy(&origin[1], path, sizeof(origin) - 2); if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, origin)) @@ -691,6 +704,7 @@ lws_client_connect_via_info(struct lws_client_connect_info *i) wsi->u.hdr.stash->origin[0] = '\0'; wsi->u.hdr.stash->protocol[0] = '\0'; wsi->u.hdr.stash->method[0] = '\0'; + wsi->u.hdr.stash->iface[0] = '\0'; strncpy(wsi->u.hdr.stash->address, i->address, sizeof(wsi->u.hdr.stash->address) - 1); @@ -707,6 +721,9 @@ lws_client_connect_via_info(struct lws_client_connect_info *i) if (i->method) strncpy(wsi->u.hdr.stash->method, i->method, sizeof(wsi->u.hdr.stash->method) - 1); + if (i->iface) + strncpy(wsi->u.hdr.stash->iface, i->iface, + sizeof(wsi->u.hdr.stash->iface) - 1); wsi->u.hdr.stash->address[sizeof(wsi->u.hdr.stash->address) - 1] = '\0'; wsi->u.hdr.stash->path[sizeof(wsi->u.hdr.stash->path) - 1] = '\0'; @@ -714,6 +731,7 @@ lws_client_connect_via_info(struct lws_client_connect_info *i) wsi->u.hdr.stash->origin[sizeof(wsi->u.hdr.stash->origin) - 1] = '\0'; wsi->u.hdr.stash->protocol[sizeof(wsi->u.hdr.stash->protocol) - 1] = '\0'; wsi->u.hdr.stash->method[sizeof(wsi->u.hdr.stash->method) - 1] = '\0'; + wsi->u.hdr.stash->iface[sizeof(wsi->u.hdr.stash->iface) - 1] = '\0'; if (i->pwsi) *i->pwsi = wsi; @@ -796,6 +814,10 @@ lws_client_connect_via_info2(struct lws *wsi) if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD, stash->method)) goto bail1; + if (stash->iface[0]) + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE, + stash->iface)) + goto bail1; #if defined(LWS_WITH_SOCKS5) if (!wsi->vhost->socks_proxy_port) diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 690a7f22..2db2fc68 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -2423,6 +2423,9 @@ struct lws_client_connect_info { * even before the new wsi is returned and even if ultimately no wsi * is returned. */ + const char *iface; + /**< NULL to allow routing on any interface, or interface name or IP + * to bind the socket to */ /* Add new things just above here ---^ * This is part of the ABI, don't needlessly break compatibility @@ -3020,6 +3023,7 @@ enum lws_token_indexes { _WSI_TOKEN_CLIENT_HOST, _WSI_TOKEN_CLIENT_ORIGIN, _WSI_TOKEN_CLIENT_METHOD, + _WSI_TOKEN_CLIENT_IFACE, /* always last real token index*/ WSI_TOKEN_COUNT, diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index be5a4c56..845d4a5f 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1192,6 +1192,7 @@ struct client_info_stash { char origin[256]; char protocol[256]; char method[16]; + char iface[16]; }; #endif