socket interface bind generalize to lws_socket_bind

Move the socket bind to interface code out of server into
libwebsockets.c and make a private api for it.

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2016-03-12 08:18:58 +08:00
parent 9a720bbb50
commit c793944f17
4 changed files with 70 additions and 77 deletions

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;