diff --git a/lib/client-handshake.c b/lib/client-handshake.c
index ba7a44afd406520a1fb409e41da19665e39ae9c0..5fb7c4e0b59291cbbc70dd4fedd09f8476e1c135 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;
- }
-
- 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;
- }
+ lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
+ AWAITING_TIMEOUT);
- 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 72cc2fd7cd8bb37c1dc8bed6cd6a02242e559f85..178a24fbd1e2b524c9d5143571249ea152c9c403 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 f84f942cd9d8ad703ab70662fa44989c57c2ab5b..0874e9fa53017f176e17c469780ce6d48097fc1c 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 eeb0b0d307b8c6b4f29581893a01bfbdb00d164b..2fac4aba1862665be3c970f35ac446156ba8b55e 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;