add ipv6 support
authorJames Devine <fxmulder@gmail.com>
Mon, 24 Mar 2014 08:09:25 +0000 (16:09 +0800)
committerAndy Green <andy.green@linaro.org>
Mon, 24 Mar 2014 08:09:25 +0000 (16:09 +0800)
(changed to support runtime disable + integration by andy@warmcat.com)

CMakeLists.txt
changelog
config.h.cmake
lib/client-handshake.c
lib/libwebsockets.c
lib/libwebsockets.h
lib/private-libwebsockets.h

index d58ee67..d1e7eab 100644 (file)
@@ -52,7 +52,8 @@ option(LWS_WITHOUT_DEBUG "Don't compile debug related code" OFF)
 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" OFF)
-option(LWS_WITH_LIBEV "Compile without support for libev" OFF)
+option(LWS_WITH_LIBEV "Compile with support for libev" OFF)
+option(LWS_WITHOUT_IPV6 "Compile without support for ipv6" OFF)
 
 # Allow the user to override installation directories.
 set(LWS_INSTALL_LIB_DIR       lib CACHE PATH "Installation directory for libraries")
@@ -121,6 +122,11 @@ if (LWS_WITH_LIBEV)
        set(LWS_NO_EXTERNAL_POLL 1)
 endif()
 
+if (LWS_WITHOUT_IPV6)
+else()
+       set(LWS_WITH_IPV6 1)
+endif()
+
 if (MINGW)
        set(LWS_MINGW_SUPPORT 1)
 endif()
@@ -877,6 +883,7 @@ message(" LWS_WITHOUT_EXTENSIONS = ${LWS_WITHOUT_EXTENSIONS}")
 message(" LWS_WITH_LATENCY = ${LWS_WITH_LATENCY}")
 message(" LWS_WITHOUT_DAEMONIZE = ${LWS_WITHOUT_DAEMONIZE}")
 message(" LWS_USE_LIBEV = ${LWS_USE_LIBEV}")
+message(" LWS_WITH_IPV6 = ${LWS_WITH_IPV6}")
 message("---------------------------------------------------------------------")
 
 # These will be available to parent projects including libwebsockets using add_subdirectory()
index e3c464f..88f9c16 100644 (file)
--- a/changelog
+++ b/changelog
@@ -44,6 +44,11 @@ eventloop instead of the default poll() one will also be compiled in.  But to
 use it, you must also set the LWS_SERVER_OPTION_LIBEV flag on the context
 creation info struct options member.
 
+IPV6 is supported and enabled by default, you can disable the support at
+build-time by giving -DLWS_WITHOUT_IPV6, and disable use of it even if
+compiled in by making sure the flag LWS_SERVER_OPTION_DISABLE_IPV6 is set on
+the context creation info struct options member.
+
 
 User api changes
 ----------------
index a8247a9..6ca3460 100644 (file)
@@ -29,6 +29,9 @@
 /* Enable libev io loop */
 #cmakedefine LWS_USE_LIBEV
 
+/* Build with support for ipv6 */
+#cmakedefine LWS_WITH_IPV6
+
 /* Turn on latency measuring code */
 #cmakedefine LWS_LATENCY
 
index d87d210..4c50af8 100644 (file)
@@ -5,9 +5,16 @@ struct libwebsocket *libwebsocket_client_connect_2(
        struct libwebsocket *wsi
 ) {
        struct pollfd pfd;
+#ifdef LWS_WITH_IPV6
+       struct sockaddr_in6 server_addr6;
+       struct sockaddr_in6 client_addr6;
+       struct addrinfo hints, *result;
+#endif
+       struct sockaddr_in server_addr4;
+       struct sockaddr_in client_addr4;
        struct hostent *server_hostent;
-       struct sockaddr_in server_addr;
-       struct sockaddr_in client_addr;
+
+       struct sockaddr *v;
        int n;
        int plen = 0;
        const char *ads;
@@ -27,10 +34,22 @@ struct libwebsocket *libwebsocket_client_connect_2(
                        lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
                        wsi->u.hdr.ah->c_port);
                ads = context->http_proxy_address;
-               server_addr.sin_port = htons(context->http_proxy_port);
+
+#ifdef LWS_WITH_IPV6
+               if (LWS_IPV6_ENABLED(context))
+                       server_addr6.sin6_port = htons(context->http_proxy_port);
+               else
+#endif
+                       server_addr4.sin_port = htons(context->http_proxy_port);
+
        } else {
                ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
-               server_addr.sin_port = htons(wsi->u.hdr.ah->c_port);
+#ifdef LWS_WITH_IPV6
+               if (LWS_IPV6_ENABLED(context))
+                       server_addr6.sin6_port = htons(wsi->u.hdr.ah->c_port);
+               else
+#endif
+                       server_addr4.sin_port = htons(wsi->u.hdr.ah->c_port);
        }
 
        /*
@@ -38,15 +57,61 @@ struct libwebsocket *libwebsocket_client_connect_2(
         */
        lwsl_client("libwebsocket_client_connect_2: address %s\n", ads);
 
-       server_hostent = gethostbyname(ads);
-       if (server_hostent == NULL) {
-               lwsl_err("Unable to get host name from %s\n", ads);
-               goto oom4;
+#ifdef LWS_WITH_IPV6
+       if (LWS_IPV6_ENABLED(context)) {
+               memset(&hints, 0, sizeof(struct addrinfo));
+               n = getaddrinfo(ads, NULL, &hints, &result);
+               if (n) {
+                       lwsl_err("getaddrinfo: %s\n", gai_strerror(n));
+                       goto oom4;
+               }
+
+               server_addr6.sin6_family = AF_INET6;
+               switch (result->ai_family) {
+               case AF_INET:
+                       /* map IPv4 to IPv6 */
+                       bzero((char *)&server_addr6.sin6_addr,
+                                               sizeof(struct in6_addr));
+                       server_addr6.sin6_addr.s6_addr16[5] = 0xffff;
+                       bcopy(&((struct sockaddr_in *)result->ai_addr)->sin_addr,
+                               &server_addr6.sin6_addr.s6_addr16[6],
+                                                       sizeof(struct in_addr));
+                       break;
+               case AF_INET6:
+                       memcpy(&server_addr6.sin6_addr,
+                         &((struct sockaddr_in6 *)result->ai_addr)->sin6_addr,
+                                               sizeof(struct in6_addr));
+                       break;
+               default:
+                       lwsl_err("Unknown address family\n");
+                       freeaddrinfo(result);
+                       goto oom4;
+               }
+
+               freeaddrinfo(result);
+       } else
+#endif
+       {
+               server_hostent = gethostbyname(ads);
+               if (!server_hostent) {
+                       lwsl_err("Unable to get host name from %s\n", ads);
+                       goto oom4;
+               }
+
+               server_addr4.sin_family = AF_INET;
+               server_addr4.sin_addr =
+                               *((struct in_addr *)server_hostent->h_addr);
+               bzero(&server_addr4.sin_zero, 8);
        }
 
        if (wsi->sock < 0) {
 
-               wsi->sock = socket(AF_INET, SOCK_STREAM, 0);
+#ifdef LWS_WITH_IPV6
+               if (LWS_IPV6_ENABLED(context))
+                       wsi->sock = socket(AF_INET6, SOCK_STREAM, 0);
+               else
+#endif
+                       wsi->sock = socket(AF_INET, SOCK_STREAM, 0);
 
                if (wsi->sock < 0) {
                        lwsl_warn("Unable to open socket\n");
@@ -66,34 +131,51 @@ struct libwebsocket *libwebsocket_client_connect_2(
                libwebsocket_set_timeout(wsi,
                        PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
                                                              AWAITING_TIMEOUT);
+#ifdef LWS_WITH_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;
+               }
 
-               bzero((char *) &client_addr, sizeof(client_addr));
-               client_addr.sin_family = AF_INET;
-
-               if (context->iface != NULL) {
-                       if (interface_to_sa(context->iface, &client_addr,
-                                               sizeof(client_addr)) < 0) {
-                               lwsl_err("Unable to find interface %s\n", context->iface);
+               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);
                                compatible_close(wsi->sock);
                                goto failed;
                        }
 
-                       if (bind(wsi->sock, (struct sockaddr *) &client_addr,
-                                                       sizeof(client_addr)) < 0) {
-                               lwsl_err("Error binding to interface %s", context->iface);
+                       if (bind(wsi->sock, v, n) < 0) {
+                               lwsl_err("Error binding to interface %s",
+                                                               context->iface);
                                compatible_close(wsi->sock);
                                goto failed;
                        }
                }
        }
 
-       server_addr.sin_family = AF_INET;
-       server_addr.sin_addr = *((struct in_addr *)server_hostent->h_addr);
-
-       bzero(&server_addr.sin_zero, 8);
+#ifdef LWS_WITH_IPV6
+       if (LWS_IPV6_ENABLED(context)) {
+               v = (struct sockaddr *)&server_addr6;
+               n = sizeof(struct sockaddr_in6);
+       } else
+#endif
+       {
+               v = (struct sockaddr *)&server_addr4;
+               n = sizeof(struct sockaddr);
+       }
 
-       if (connect(wsi->sock, (struct sockaddr *)&server_addr,
-                         sizeof(struct sockaddr)) == -1 || LWS_ERRNO == LWS_EISCONN)  {
+       if (connect(wsi->sock, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) {
 
                if (LWS_ERRNO == LWS_EALREADY || LWS_ERRNO == LWS_EINPROGRESS) {
                        lwsl_client("nonblocking connect retry\n");
@@ -108,7 +190,6 @@ struct libwebsocket *libwebsocket_client_connect_2(
                }
 
                if (LWS_ERRNO != LWS_EISCONN) {
-               
                        lwsl_debug("Connect failed errno=%d\n", LWS_ERRNO);
                        goto failed;
                }
index 08a1844..845335f 100644 (file)
@@ -576,66 +576,96 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
                                        char *rip, int rip_len)
 {
        socklen_t len;
-       struct sockaddr_in sin;
+#ifdef LWS_WITH_IPV6
+       struct sockaddr_in6 sin6;
+#endif
+       struct sockaddr_in sin4;
        struct hostent *host;
        struct hostent *host1;
        char ip[128];
        unsigned char *p;
        int n;
-       int ret = -1;
 #ifdef AF_LOCAL
        struct sockaddr_un *un;
 #endif
+       int ret = -1;
 
        rip[0] = '\0';
        name[0] = '\0';
 
        lws_latency_pre(context, wsi);
 
-       len = sizeof(sin);
-       if (getpeername(fd, (struct sockaddr *) &sin, &len) < 0) {
-               lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
-               goto bail;
-       }
+#ifdef LWS_WITH_IPV6
+       if (LWS_IPV6_ENABLED(context)) {
 
-       host = gethostbyaddr((char *) &sin.sin_addr, sizeof(sin.sin_addr),
-                                                                      AF_INET);
-       if (host == NULL) {
-               lwsl_warn("gethostbyaddr: %s\n", strerror(LWS_ERRNO));
-               goto bail;
-       }
+               len = sizeof(sin6);
+               if (getpeername(fd, (struct sockaddr *) &sin6, &len) < 0) {
+                       lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
+                       goto bail;
+               }
 
-       strncpy(name, host->h_name, name_len);
-       name[name_len - 1] = '\0';
+               if (inet_ntop(AF_INET6, &sin6.sin6_addr, rip, rip_len) == NULL) {
+                       perror("inet_ntop");
+                       goto bail;
+               }
 
-       host1 = gethostbyname(host->h_name);
-       if (host1 == NULL)
-               goto bail;
-       p = (unsigned char *)host1;
-       n = 0;
-       while (p != NULL) {
-               p = (unsigned char *)host1->h_addr_list[n++];
-               if (p == NULL)
-                       continue;
-               if ((host1->h_addrtype != AF_INET)
-#ifdef AF_LOCAL
-                       && (host1->h_addrtype != AF_LOCAL)
+               // Strip off the IPv4 to IPv6 header if one exists
+               if (strncmp(rip, "::ffff:", 7) == 0) {
+                       memmove(rip, rip + 7, strlen(rip) - 6);
+               }
+
+               getnameinfo((struct sockaddr *)&sin6,
+                               sizeof(struct sockaddr_in6), name,
+                                                       name_len, NULL, 0, 0);
+
+       } else
 #endif
-                       )
-                       continue;
+       {
+               len = sizeof(sin4);
+               if (getpeername(fd, (struct sockaddr *) &sin4, &len) < 0) {
+                       lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
+                       goto bail;
+               }
+               host = gethostbyaddr((char *) &sin4.sin_addr,
+                                               sizeof(sin4.sin_addr), AF_INET);
+               if (host == NULL) {
+                       lwsl_warn("gethostbyaddr: %s\n", strerror(LWS_ERRNO));
+                       goto bail;
+               }
 
-               if (host1->h_addrtype == AF_INET)
-                       sprintf(ip, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
-#ifdef AF_LOCAL
-               else {
-                       un = (struct sockaddr_un *)p;
-                       strncpy(ip, un->sun_path, sizeof(ip) - 1);
-                       ip[sizeof(ip) - 1] = '\0';
+               strncpy(name, host->h_name, name_len);
+               name[name_len - 1] = '\0';
+
+               host1 = gethostbyname(host->h_name);
+               if (host1 == NULL)
+                       goto bail;
+               p = (unsigned char *)host1;
+               n = 0;
+               while (p != NULL) {
+                       p = (unsigned char *)host1->h_addr_list[n++];
+                       if (p == NULL)
+                               continue;
+                       if ((host1->h_addrtype != AF_INET)
+       #ifdef AF_LOCAL
+                               && (host1->h_addrtype != AF_LOCAL)
+       #endif
+                               )
+                               continue;
+
+                       if (host1->h_addrtype == AF_INET)
+                               sprintf(ip, "%u.%u.%u.%u",
+                                               p[0], p[1], p[2], p[3]);
+       #ifdef AF_LOCAL
+                       else {
+                               un = (struct sockaddr_un *)p;
+                               strncpy(ip, un->sun_path, sizeof(ip) - 1);
+                               ip[sizeof(ip) - 1] = '\0';
+                       }
+       #endif
+                       p = NULL;
+                       strncpy(rip, ip, rip_len);
+                       rip[rip_len - 1] = '\0';
                }
-#endif
-               p = NULL;
-               strncpy(rip, ip, rip_len);
-               rip[rip_len - 1] = '\0';
        }
 
        ret = 0;
@@ -2053,7 +2083,11 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
 #ifndef LWS_NO_SERVER
        int opt = 1;
        struct libwebsocket *wsi;
-       struct sockaddr_in serv_addr;
+#ifdef LWS_WITH_IPV6
+       struct sockaddr_in6 serv_addr6;
+#endif
+       struct sockaddr_in serv_addr4;
+       struct sockaddr *v;
 #endif
 #ifndef LWS_NO_EXTENSIONS
        int m;
@@ -2070,6 +2104,14 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
 
        lwsl_notice("Initial logging level %d\n", log_level);
        lwsl_notice("Library version: %s\n", library_version);
+#ifdef LWS_WITH_IPV6
+       if (!(info->options & LWS_SERVER_OPTION_DISABLE_IPV6))
+               lwsl_notice("IPV6 compiled in and enabled\n");
+       else
+               lwsl_notice("IPV6 compiled in but disabled\n");
+#else
+       lwsl_notice("IPV6 not compiled in\n");
+#endif
        lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN);
        lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS);
 #ifndef LWS_NO_EXTENSIONS
@@ -2489,7 +2531,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
                                                     context->ssl_ctx, NULL, 0);
        }
 
-       if(info->options & LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT) {
+       if (info->options & LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT) {
                /* Normally SSL listener rejects non-ssl, optionally allow */
                context->allow_non_ssl_on_ssl_port = 1;
        }
@@ -2538,7 +2580,13 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
        if (info->port != CONTEXT_PORT_NO_LISTEN) {
                int sockfd;
 
-               sockfd = socket(AF_INET, SOCK_STREAM, 0);
+#ifdef LWS_WITH_IPV6
+               if (LWS_IPV6_ENABLED(context))
+                       sockfd = socket(AF_INET6, SOCK_STREAM, 0);
+               else
+#endif
+                       sockfd = socket(AF_INET, SOCK_STREAM, 0);
+
                if (sockfd < 0) {
                        lwsl_err("ERROR opening socket\n");
                        goto bail;
@@ -2562,37 +2610,51 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
                fcntl(sockfd, F_SETFL, O_NONBLOCK);
                #endif
 
-               bzero((char *) &serv_addr, sizeof(serv_addr));
-               serv_addr.sin_family = AF_INET;
-               if (info->iface == NULL)
-                       serv_addr.sin_addr.s_addr = INADDR_ANY;
-               else
-                       if (interface_to_sa(info->iface, &serv_addr,
-                                               sizeof(serv_addr)) < 0) {
-                               lwsl_err("Unable to find interface %s\n",
-                                                       info->iface);
-                               compatible_close(sockfd);
-                               goto bail;
+#ifdef LWS_WITH_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;
+                       serv_addr4.sin_port = htons(info->port);
+
+                       if (info->iface) {
+                               if (interface_to_sa(context, info->iface,
+                                          (struct sockaddr_in *)v, n) < 0) {
+                                       lwsl_err("Unable to find interface %s\n",
+                                                               info->iface);
+                                       compatible_close(sockfd);
+                                       goto bail;
+                               }
                        }
-               serv_addr.sin_port = htons(info->port);
+               } /* ipv4 */
 
-               n = bind(sockfd, (struct sockaddr *) &serv_addr,
-                                                            sizeof(serv_addr));
+               n = bind(sockfd, v, n);
                if (n < 0) {
                        lwsl_err("ERROR on binding to port %d (%d %d)\n",
-                                                       info->port, n, LWS_ERRNO);
+                                                     info->port, n, LWS_ERRNO);
                        compatible_close(sockfd);
                        goto bail;
                }
                
-       struct sockaddr_in sin;
-       socklen_t len = sizeof(sin);
-       if (getsockname(sockfd, (struct sockaddr *)&sin, &len) == -1)
-               perror("getsockname");
-       else
-               info->port = ntohs(sin.sin_port);
+               struct sockaddr_in sin;
+               socklen_t len = sizeof(sin);
+               if (getsockname(sockfd, (struct sockaddr *)&sin, &len) == -1)
+                       perror("getsockname");
+               else
+                       info->port = ntohs(sin.sin_port);
        
-       context->listen_port = info->port;
+               context->listen_port = info->port;
 
                wsi = (struct libwebsocket *)malloc(
                                        sizeof(struct libwebsocket));
@@ -2861,8 +2923,11 @@ LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int leve
                lwsl_emit = log_emit_function;
 }
 
+/* cast a struct sockaddr_in6 * into addr for ipv6 */
+
 int
-interface_to_sa(const char *ifname, struct sockaddr_in *addr, size_t addrlen)
+interface_to_sa(struct libwebsocket_context *context,
+               const char *ifname, struct sockaddr_in *addr, size_t addrlen)
 {
        int rc = -1;
 #if defined(WIN32) || defined(_WIN32)
@@ -2870,19 +2935,50 @@ interface_to_sa(const char *ifname, struct sockaddr_in *addr, size_t addrlen)
 #else
        struct ifaddrs *ifr;
        struct ifaddrs *ifc;
-       struct sockaddr_in *sin;
+#ifdef LWS_WITH_IPV6
+       struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
+#endif
 
        getifaddrs(&ifr);
        for (ifc = ifr; ifc != NULL && rc; ifc = ifc->ifa_next) {
-               if (ifc->ifa_addr == NULL)
+               if (!ifc->ifa_addr)
                        continue;
+
                lwsl_info(" interface %s vs %s\n", ifc->ifa_name, ifname);
+
                if (strcmp(ifc->ifa_name, ifname))
                        continue;
-               sin = (struct sockaddr_in *)ifc->ifa_addr;
-               if (sin->sin_family != AF_INET)
+
+               switch (ifc->ifa_addr->sa_family) {
+               case AF_INET:
+#ifdef LWS_WITH_IPV6
+                       if (LWS_IPV6_ENABLED(context)) {
+                               /* map IPv4 to IPv6 */
+                               bzero((char *)&addr6->sin6_addr,
+                                               sizeof(struct in6_addr));
+                               addr6->sin6_addr.s6_addr16[5] = 0xffff;
+                               bcopy(&((struct sockaddr_in *)ifc->ifa_addr)->
+                                                               sin_addr,
+                                       &addr6->sin6_addr.s6_addr16[6],
+                                                       sizeof(struct in_addr));
+                       } else
+#endif
+                               memcpy(addr,
+                                       (struct sockaddr_in *)ifc->ifa_addr,
+                                                   sizeof(struct sockaddr_in));
+                       break;
+#ifdef LWS_WITH_IPV6
+               case AF_INET6:
+                       if (rc >= 0)
+                               break;
+                       memcpy(&addr6->sin6_addr,
+                         &((struct sockaddr_in6 *)ifc->ifa_addr)->sin6_addr,
+                                                      sizeof(struct in6_addr));
+                       break;
+#endif
+               default:
                        continue;
-               memcpy(addr, sin, addrlen);
+               }
                rc = 0;
        }
 
index 5bdd8b6..5c41a57 100644 (file)
@@ -149,7 +149,8 @@ enum libwebsocket_context_options {
        LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2,
        LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4,
        LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = 8,
-       LWS_SERVER_OPTION_LIBEV = 16
+       LWS_SERVER_OPTION_LIBEV = 16,
+       LWS_SERVER_OPTION_DISABLE_IPV6 = 32,
 };
 
 enum libwebsocket_callback_reasons {
index f56aba5..d2fdf95 100644 (file)
@@ -354,6 +354,11 @@ struct libwebsocket_context {
 #define LWS_LIBEV_ENABLED(context) (0)
 #endif
 
+#ifdef LWS_WITH_IPV6
+#define LWS_IPV6_ENABLED(context) (context->options & LWS_SERVER_OPTION_DISABLE_IPV6)
+#else
+#define LWS_IPV6_ENABLED(context) (0)
+#endif
 
 enum uri_path_states {
        URIPS_IDLE,
@@ -618,8 +623,8 @@ LWS_EXTERN int handshake_0405(struct libwebsocket_context *context,
 LWS_EXTERN int get_daemonize_pid();
 #endif
 
-extern int interface_to_sa(const char *ifname,
-                     struct sockaddr_in *addr, size_t addrlen);
+extern int interface_to_sa(struct libwebsocket_context *context,
+               const char *ifname, struct sockaddr_in *addr, size_t addrlen);
 
 #ifndef LWS_OPENSSL_SUPPORT