diff --git a/lib/client-handshake.c b/lib/client-handshake.c index ba7a44af..5fb7c4e0 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -5,13 +5,11 @@ lws_client_connect_2(struct lws *wsi) { #ifdef LWS_USE_IPV6 struct sockaddr_in6 server_addr6; - struct sockaddr_in6 client_addr6; struct addrinfo hints, *result; #endif struct lws_context *context = wsi->context; struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; struct sockaddr_in server_addr4; - struct sockaddr_in client_addr4; struct lws_pollfd pfd; struct sockaddr *v; int n, plen = 0; @@ -172,38 +170,12 @@ lws_client_connect_2(struct lws *wsi) * handling as oom4 does. We have to run the whole close flow. */ - lws_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, - AWAITING_TIMEOUT); -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - v = (struct sockaddr *)&client_addr6; - n = sizeof(client_addr6); - bzero((char *)v, n); - client_addr6.sin6_family = AF_INET6; - } else -#endif - { - v = (struct sockaddr *)&client_addr4; - n = sizeof(client_addr4); - bzero((char *)v, n); - client_addr4.sin_family = AF_INET; - } + lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, + AWAITING_TIMEOUT); - if (context->iface) { - if (interface_to_sa(context, context->iface, - (struct sockaddr_in *)v, n) < 0) { - lwsl_err("Unable to find interface %s\n", - context->iface); - goto failed; - } - - if (bind(wsi->sock, v, n) < 0) { - lwsl_err("Error binding to interface %s", - context->iface); - goto failed; - } - } + n = lws_socket_bind(context, wsi->sock, 0, context->iface); + if (n < 0) + goto failed; } #ifdef LWS_USE_IPV6 diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 72cc2fd7..178a24fb 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -1414,6 +1414,63 @@ lws_extension_callback_pm_deflate(struct lws_context *context, } #endif +LWS_EXTERN int +lws_socket_bind(struct lws_context *context, int sockfd, int port, + const char *iface) +{ +#if LWS_POSIX +#ifdef LWS_USE_IPV6 + struct sockaddr_in6 serv_addr6; +#endif + struct sockaddr_in serv_addr4; + socklen_t len = sizeof(struct sockaddr); + int n; + struct sockaddr_in sin; + struct sockaddr *v; + +#ifdef LWS_USE_IPV6 + if (LWS_IPV6_ENABLED(context)) { + v = (struct sockaddr *)&serv_addr6; + n = sizeof(struct sockaddr_in6); + bzero((char *) &serv_addr6, sizeof(serv_addr6)); + serv_addr6.sin6_addr = in6addr_any; + serv_addr6.sin6_family = AF_INET6; + serv_addr6.sin6_port = htons(port); + } else +#endif + { + v = (struct sockaddr *)&serv_addr4; + n = sizeof(serv_addr4); + bzero((char *) &serv_addr4, sizeof(serv_addr4)); + serv_addr4.sin_addr.s_addr = INADDR_ANY; + serv_addr4.sin_family = AF_INET; + + if (iface && + interface_to_sa(context, iface, + (struct sockaddr_in *)v, n) < 0) { + lwsl_err("Unable to find interface %s\n", iface); + return -1; + } + + serv_addr4.sin_port = htons(port); + } /* ipv4 */ + + n = bind(sockfd, v, n); + if (n < 0) { + lwsl_err("ERROR on binding to port %d (%d %d)\n", + port, n, LWS_ERRNO); + return -1; + } + + if (getsockname(sockfd, (struct sockaddr *)&sin, &len) == -1) + lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO)); + else + port = ntohs(sin.sin_port); +#endif + + return port; +} + LWS_VISIBLE LWS_EXTERN int lws_is_cgi(struct lws *wsi) { #ifdef LWS_WITH_CGI diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index f84f942c..0874e9fa 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1160,6 +1160,10 @@ struct lws { LWS_EXTERN int log_level; +LWS_EXTERN int +lws_socket_bind(struct lws_context *context, int sockfd, int port, + const char *iface); + LWS_EXTERN void lws_close_free_wsi(struct lws *wsi, enum lws_close_status); diff --git a/lib/server.c b/lib/server.c index eeb0b0d3..2fac4aba 100644 --- a/lib/server.c +++ b/lib/server.c @@ -26,15 +26,8 @@ int lws_context_init_server(struct lws_context_creation_info *info, struct lws_context *context) { -#ifdef LWS_USE_IPV6 - struct sockaddr_in6 serv_addr6; -#endif -#if LWS_POSIX - struct sockaddr_in serv_addr4; - socklen_t len = sizeof(struct sockaddr); +#ifdef LWS_POSIX int n, opt = 1, limit = 1; - struct sockaddr_in sin; - struct sockaddr *v; #endif lws_sockfd_type sockfd; struct lws *wsi; @@ -88,43 +81,10 @@ lws_context_init_server(struct lws_context_creation_info *info, lws_plat_set_socket_options(context, sockfd); #if LWS_POSIX -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - v = (struct sockaddr *)&serv_addr6; - n = sizeof(struct sockaddr_in6); - bzero((char *) &serv_addr6, sizeof(serv_addr6)); - serv_addr6.sin6_addr = in6addr_any; - serv_addr6.sin6_family = AF_INET6; - serv_addr6.sin6_port = htons(info->port); - } else -#endif - { - v = (struct sockaddr *)&serv_addr4; - n = sizeof(serv_addr4); - bzero((char *) &serv_addr4, sizeof(serv_addr4)); - serv_addr4.sin_addr.s_addr = INADDR_ANY; - serv_addr4.sin_family = AF_INET; - - if (info->iface && interface_to_sa(context, info->iface, - (struct sockaddr_in *)v, n) < 0) { - lwsl_err("Unable to find interface %s\n", info->iface); - goto bail; - } - - serv_addr4.sin_port = htons(info->port); - } /* ipv4 */ - - n = bind(sockfd, v, n); - if (n < 0) { - lwsl_err("ERROR on binding to port %d (%d %d)\n", - info->port, n, LWS_ERRNO); + n = lws_socket_bind(context, sockfd, info->port, info->iface); + if (n < 0) goto bail; - } - - if (getsockname(sockfd, (struct sockaddr *)&sin, &len) == -1) - lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO)); - else - info->port = ntohs(sin.sin_port); + info->port = n; #endif context->listen_port = info->port;