diff --git a/CMakeLists.txt b/CMakeLists.txt index b74913e4..41ebbc12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ option(LWS_WITHOUT_EXTENSIONS "Don't compile with extensions" OFF) option(LWS_WITH_LATENCY "Build latency measuring code into the library" OFF) option(LWS_WITHOUT_DAEMONIZE "Don't build the daemonization api" ON) option(LWS_IPV6 "Compile with support for ipv6" OFF) +option(LWS_UNIX_SOCK "Compile with support for UNIX domain socket" OFF) option(LWS_WITH_HTTP2 "Compile with support for http2" OFF) option(LWS_MBED3 "Platform is MBED3" OFF) option(LWS_SSL_SERVER_WITH_ECDH_CERT "Include SSL server use ECDH certificate" OFF) @@ -275,6 +276,10 @@ if (WIN32) set(LWS_IPV6 OFF) message(WARNING "IPv6 does not currently work on Windows!") endif() + if (LWS_UNIX_SOCK) + set(LWS_UNIX_SOCK OFF) + message(WARNING "Windows does not support UNIX domain sockets") + endif() else() set(LWS_OPENSSL_CLIENT_CERTS /etc/pki/tls/certs/ CACHE PATH "Client SSL certificate directory") endif() @@ -319,6 +324,10 @@ if (LWS_IPV6) set(LWS_USE_IPV6 1) endif() +if (LWS_UNIX_SOCK) + set(LWS_USE_UNIX_SOCK 1) +endif() + if (LWS_WITH_HTTP2) set(LWS_USE_HTTP2 1) endif() @@ -1434,6 +1443,7 @@ message(" LWS_WITHOUT_DAEMONIZE = ${LWS_WITHOUT_DAEMONIZE}") message(" LWS_USE_LIBEV = ${LWS_USE_LIBEV}") message(" LWS_USE_LIBUV = ${LWS_USE_LIBUV}") message(" LWS_IPV6 = ${LWS_IPV6}") +message(" LWS_UNIX_SOCK = ${LWS_UNIX_SOCK}") message(" LWS_WITH_HTTP2 = ${LWS_WITH_HTTP2}") message(" LWS_MBED3 = ${LWS_MBED3}") message(" LWS_SSL_SERVER_WITH_ECDH_CERT = ${LWS_SSL_SERVER_WITH_ECDH_CERT}") diff --git a/lib/context.c b/lib/context.c index f75be876..7c9250d9 100644 --- a/lib/context.c +++ b/lib/context.c @@ -278,6 +278,12 @@ lws_create_vhost(struct lws_context *context, vh->mount_list = mounts; +#ifdef LWS_USE_UNIX_SOCK + if (LWS_UNIX_SOCK_ENABLED(context)) { + lwsl_notice("Creating Vhost '%s' path \"%s\", %d protocols\n", + vh->name, info->iface, vh->count_protocols); + } else +#endif lwsl_notice("Creating Vhost '%s' port %d, %d protocols\n", vh->name, info->port, vh->count_protocols); diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 5fe0bdc8..c99e5784 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -1489,6 +1489,9 @@ lws_socket_bind(struct lws_context *context, int sockfd, int port, const char *iface) { #if LWS_POSIX +#ifdef LWS_USE_UNIX_SOCK + struct sockaddr_un serv_unix; +#endif #ifdef LWS_USE_IPV6 struct sockaddr_in6 serv_addr6; #endif @@ -1498,6 +1501,20 @@ lws_socket_bind(struct lws_context *context, int sockfd, int port, struct sockaddr_in sin; struct sockaddr *v; +#ifdef LWS_USE_UNIX_SOCK + if (LWS_UNIX_SOCK_ENABLED(context)) { + v = (struct sockaddr *)&serv_unix; + n = sizeof(struct sockaddr_un); + bzero((char *) &serv_unix, sizeof(serv_unix)); + serv_unix.sun_family = AF_UNIX; + if (sizeof(serv_unix.sun_path) <= strlen(iface)) { + lwsl_err("\"%s\" too long for UNIX domain socket\n", + iface); + return -1; + } + strcpy(serv_unix.sun_path, iface); + } else +#endif #ifdef LWS_USE_IPV6 if (LWS_IPV6_ENABLED(context)) { v = (struct sockaddr *)&serv_addr6; @@ -1526,6 +1543,13 @@ lws_socket_bind(struct lws_context *context, int sockfd, int port, } /* ipv4 */ n = bind(sockfd, v, n); +#ifdef LWS_USE_UNIX_SOCK + if (n < 0 && LWS_UNIX_SOCK_ENABLED(context)) { + lwsl_err("ERROR on binding fd %d to \"%s\" (%d %d)\n", + sockfd, iface, n, LWS_ERRNO); + return -1; + } else +#endif if (n < 0) { lwsl_err("ERROR on binding fd %d to port %d (%d %d)\n", sockfd, port, n, LWS_ERRNO); diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 278a5846..4d586ff6 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -332,6 +332,7 @@ enum lws_context_options { (1 << 12), LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT = (1 << 12), LWS_SERVER_OPTION_EXPLICIT_VHOSTS = (1 << 13), + LWS_SERVER_OPTION_UNIX_SOCK = (1 << 14), /****** add new things just above ---^ ******/ }; @@ -1373,6 +1374,8 @@ struct lws_protocol_vhost_options { * client * @iface: NULL to bind the listen socket to all interfaces, or the * interface name, eg, "eth2" + * If options specifies LWS_SERVER_OPTION_UNIX_SOCK, this member is + * the pathname of a UNIX domain socket. * @protocols: Array of structures listing supported protocols and a protocol- * specific callback for each one. The list is ended with an * entry that has a NULL callback pointer. diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 1cab3c17..b6c9bedb 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -848,6 +848,12 @@ LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info) #define LWS_IPV6_ENABLED(context) (0) #endif +#ifdef LWS_USE_UNIX_SOCK +#define LWS_UNIX_SOCK_ENABLED(context) \ + (context->options & LWS_SERVER_OPTION_UNIX_SOCK) +#else +#define LWS_UNIX_SOCK_ENABLED(context) (0) +#endif enum uri_path_states { URIPS_IDLE, URIPS_SEEN_SLASH, diff --git a/lib/server.c b/lib/server.c index 37a2ea3c..b2ea3f6f 100644 --- a/lib/server.c +++ b/lib/server.c @@ -61,6 +61,11 @@ lws_context_init_server(struct lws_context_creation_info *info, #endif for (m = 0; m < limit; m++) { +#ifdef LWS_USE_UNIX_SOCK + if (LWS_UNIX_SOCK_ENABLED(vhost->context)) + sockfd = socket(AF_UNIX, SOCK_STREAM, 0); + else +#endif #ifdef LWS_USE_IPV6 if (LWS_IPV6_ENABLED(context)) sockfd = socket(AF_INET6, SOCK_STREAM, 0); @@ -132,8 +137,14 @@ lws_context_init_server(struct lws_context_creation_info *info, #else mbed3_tcp_stream_bind(wsi->sock, info->port, wsi); #endif - if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) - lwsl_notice(" Listening on port %d\n", info->port); + if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) { +#ifdef LWS_USE_UNIX_SOCK + if (LWS_UNIX_SOCK_ENABLED(vhost->context)) + lwsl_notice(" Listening on \"%s\"\n", info->iface); + else +#endif + lwsl_notice(" Listening on port %d\n", info->port); + } return 0; diff --git a/lws_config.h.in b/lws_config.h.in index 452e9693..5e6b2069 100644 --- a/lws_config.h.in +++ b/lws_config.h.in @@ -52,6 +52,9 @@ /* Build with support for ipv6 */ #cmakedefine LWS_USE_IPV6 +/* Build with support for UNIX domain socket */ +#cmakedefine LWS_USE_UNIX_SOCK + /* Build with support for HTTP2 */ #cmakedefine LWS_USE_HTTP2