Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"", "gen_ut":1754122054, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets", "f":3, "items": [ {"schema":"libjg2-1", "cid":"58350e7505e56b2026ce55a92fa28fd9", "commit": {"type":"commit", "time": 1395648565, "time_ofs": 480, "oid_tree": { "oid": "f54eee5b74fe9a15cfd0969cdbc6adf8a32b64e4", "alias": []}, "oid":{ "oid": "3f13ea22641d6b49bb59709dade6e6dcdd5f06e5", "alias": []}, "msg": "add ipv6 support", "sig_commit": { "git_time": { "time": 1395648565, "offset": 480 }, "name": "Andy Green", "email": "andy.green@linaro.org", "md5": "4863edaebb4491aa6049a4d2d9c98c2c" }, "sig_author": { "git_time": { "time": 1395648565, "offset": 480 }, "name": "James Devine", "email": "fxmulder@gmail.com", "md5": "041e06161cf0598c35a60ccdbebf5d75" }}, "body": "add ipv6 support\n\n(changed to support runtime disable + integration by andy@warmcat.com)" , "diff": "diff --git a/CMakeLists.txt b/CMakeLists.txt\nindex d58ee67..d1e7eab 100644\n--- a/CMakeLists.txt\n+++ b/CMakeLists.txt\n@@ -52,7 +52,8 @@ option(LWS_WITHOUT_DEBUG \u0022Don't compile debug related code\u0022 OFF)\n option(LWS_WITHOUT_EXTENSIONS \u0022Don't compile with extensions\u0022 OFF)\n option(LWS_WITH_LATENCY \u0022Build latency measuring code into the library\u0022 OFF)\n option(LWS_WITHOUT_DAEMONIZE \u0022Don't build the daemonization api\u0022 OFF)\n-option(LWS_WITH_LIBEV \u0022Compile without support for libev\u0022 OFF)\n+option(LWS_WITH_LIBEV \u0022Compile with support for libev\u0022 OFF)\n+option(LWS_WITHOUT_IPV6 \u0022Compile without support for ipv6\u0022 OFF)\n \n # Allow the user to override installation directories.\n set(LWS_INSTALL_LIB_DIR lib CACHE PATH \u0022Installation directory for libraries\u0022)\n@@ -121,6 +122,11 @@ if (LWS_WITH_LIBEV)\n \tset(LWS_NO_EXTERNAL_POLL 1)\n endif()\n \n+if (LWS_WITHOUT_IPV6)\n+else()\n+\tset(LWS_WITH_IPV6 1)\n+endif()\n+\n if (MINGW)\n \tset(LWS_MINGW_SUPPORT 1)\n endif()\n@@ -877,6 +883,7 @@ message(\u0022 LWS_WITHOUT_EXTENSIONS \u003d ${LWS_WITHOUT_EXTENSIONS}\u0022)\n message(\u0022 LWS_WITH_LATENCY \u003d ${LWS_WITH_LATENCY}\u0022)\n message(\u0022 LWS_WITHOUT_DAEMONIZE \u003d ${LWS_WITHOUT_DAEMONIZE}\u0022)\n message(\u0022 LWS_USE_LIBEV \u003d ${LWS_USE_LIBEV}\u0022)\n+message(\u0022 LWS_WITH_IPV6 \u003d ${LWS_WITH_IPV6}\u0022)\n message(\u0022---------------------------------------------------------------------\u0022)\n \n # These will be available to parent projects including libwebsockets using add_subdirectory()\ndiff --git a/changelog b/changelog\nindex e3c464f..88f9c16 100644\n--- a/changelog\n+++ b/changelog\n@@ -44,6 +44,11 @@ eventloop instead of the default poll() one will also be compiled in. But to\n use it, you must also set the LWS_SERVER_OPTION_LIBEV flag on the context\n creation info struct options member.\n \n+IPV6 is supported and enabled by default, you can disable the support at\n+build-time by giving -DLWS_WITHOUT_IPV6, and disable use of it even if\n+compiled in by making sure the flag LWS_SERVER_OPTION_DISABLE_IPV6 is set on\n+the context creation info struct options member.\n+\n \n User api changes\n ----------------\ndiff --git a/config.h.cmake b/config.h.cmake\nindex a8247a9..6ca3460 100644\n--- a/config.h.cmake\n+++ b/config.h.cmake\n@@ -29,6 +29,9 @@\n /* Enable libev io loop */\n #cmakedefine LWS_USE_LIBEV\n \n+/* Build with support for ipv6 */\n+#cmakedefine LWS_WITH_IPV6\n+\n /* Turn on latency measuring code */\n #cmakedefine LWS_LATENCY\n \ndiff --git a/lib/client-handshake.c b/lib/client-handshake.c\nindex d87d210..4c50af8 100644\n--- a/lib/client-handshake.c\n+++ b/lib/client-handshake.c\n@@ -5,9 +5,16 @@ struct libwebsocket *libwebsocket_client_connect_2(\n \tstruct libwebsocket *wsi\n ) {\n \tstruct pollfd pfd;\n+#ifdef LWS_WITH_IPV6\n+\tstruct sockaddr_in6 server_addr6;\n+\tstruct sockaddr_in6 client_addr6;\n+\tstruct addrinfo hints, *result;\n+#endif\n+\tstruct sockaddr_in server_addr4;\n+\tstruct sockaddr_in client_addr4;\n \tstruct hostent *server_hostent;\n-\tstruct sockaddr_in server_addr;\n-\tstruct sockaddr_in client_addr;\n+\n+\tstruct sockaddr *v;\n \tint n;\n \tint plen \u003d 0;\n \tconst char *ads;\n@@ -27,10 +34,22 @@ struct libwebsocket *libwebsocket_client_connect_2(\n \t\t\tlws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),\n \t\t\twsi-\u003eu.hdr.ah-\u003ec_port);\n \t\tads \u003d context-\u003ehttp_proxy_address;\n-\t\tserver_addr.sin_port \u003d htons(context-\u003ehttp_proxy_port);\n+\n+#ifdef LWS_WITH_IPV6\n+\t\tif (LWS_IPV6_ENABLED(context))\n+\t\t\tserver_addr6.sin6_port \u003d htons(context-\u003ehttp_proxy_port);\n+\t\telse\n+#endif\n+\t\t\tserver_addr4.sin_port \u003d htons(context-\u003ehttp_proxy_port);\n+\n \t} else {\n \t\tads \u003d lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);\n-\t\tserver_addr.sin_port \u003d htons(wsi-\u003eu.hdr.ah-\u003ec_port);\n+#ifdef LWS_WITH_IPV6\n+\t\tif (LWS_IPV6_ENABLED(context))\n+\t\t\tserver_addr6.sin6_port \u003d htons(wsi-\u003eu.hdr.ah-\u003ec_port);\n+\t\telse\n+#endif\n+\t\t\tserver_addr4.sin_port \u003d htons(wsi-\u003eu.hdr.ah-\u003ec_port);\n \t}\n \n \t/*\n@@ -38,15 +57,61 @@ struct libwebsocket *libwebsocket_client_connect_2(\n \t */\n lwsl_client(\u0022libwebsocket_client_connect_2: address %s\u005cn\u0022, ads);\n \n-\tserver_hostent \u003d gethostbyname(ads);\n-\tif (server_hostent \u003d\u003d NULL) {\n-\t\tlwsl_err(\u0022Unable to get host name from %s\u005cn\u0022, ads);\n-\t\tgoto oom4;\n+#ifdef LWS_WITH_IPV6\n+\tif (LWS_IPV6_ENABLED(context)) {\n+\t\tmemset(\u0026hints, 0, sizeof(struct addrinfo));\n+\t\tn \u003d getaddrinfo(ads, NULL, \u0026hints, \u0026result);\n+\t\tif (n) {\n+\t\t\tlwsl_err(\u0022getaddrinfo: %s\u005cn\u0022, gai_strerror(n));\n+\t\t\tgoto oom4;\n+\t\t}\n+\n+\t\tserver_addr6.sin6_family \u003d AF_INET6;\n+\t\tswitch (result-\u003eai_family) {\n+\t\tcase AF_INET:\n+\t\t\t/* map IPv4 to IPv6 */\n+\t\t\tbzero((char *)\u0026server_addr6.sin6_addr,\n+\t\t\t\t\t\tsizeof(struct in6_addr));\n+\t\t\tserver_addr6.sin6_addr.s6_addr16[5] \u003d 0xffff;\n+\t\t\tbcopy(\u0026((struct sockaddr_in *)result-\u003eai_addr)-\u003esin_addr,\n+\t\t\t\t\u0026server_addr6.sin6_addr.s6_addr16[6],\n+\t\t\t\t\t\t\tsizeof(struct in_addr));\n+\t\t\tbreak;\n+\t\tcase AF_INET6:\n+\t\t\tmemcpy(\u0026server_addr6.sin6_addr,\n+\t\t\t \u0026((struct sockaddr_in6 *)result-\u003eai_addr)-\u003esin6_addr,\n+\t\t\t\t\t\tsizeof(struct in6_addr));\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tlwsl_err(\u0022Unknown address family\u005cn\u0022);\n+\t\t\tfreeaddrinfo(result);\n+\t\t\tgoto oom4;\n+\t\t}\n+\n+\t\tfreeaddrinfo(result);\n+\t} else\n+#endif\n+\t{\n+\t\tserver_hostent \u003d gethostbyname(ads);\n+\t\tif (!server_hostent) {\n+\t\t\tlwsl_err(\u0022Unable to get host name from %s\u005cn\u0022, ads);\n+\t\t\tgoto oom4;\n+\t\t}\n+\n+\t\tserver_addr4.sin_family \u003d AF_INET;\n+\t\tserver_addr4.sin_addr \u003d\n+\t\t\t\t*((struct in_addr *)server_hostent-\u003eh_addr);\n+\t\tbzero(\u0026server_addr4.sin_zero, 8);\n \t}\n \n \tif (wsi-\u003esock \u003c 0) {\n \n-\t\twsi-\u003esock \u003d socket(AF_INET, SOCK_STREAM, 0);\n+#ifdef LWS_WITH_IPV6\n+\t\tif (LWS_IPV6_ENABLED(context))\n+\t\t\twsi-\u003esock \u003d socket(AF_INET6, SOCK_STREAM, 0);\n+\t\telse\n+#endif\n+\t\t\twsi-\u003esock \u003d socket(AF_INET, SOCK_STREAM, 0);\n \n \t\tif (wsi-\u003esock \u003c 0) {\n \t\t\tlwsl_warn(\u0022Unable to open socket\u005cn\u0022);\n@@ -66,34 +131,51 @@ struct libwebsocket *libwebsocket_client_connect_2(\n \t\tlibwebsocket_set_timeout(wsi,\n \t\t\tPENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,\n \t\t\t\t\t\t\t AWAITING_TIMEOUT);\n+#ifdef LWS_WITH_IPV6\n+\t\tif (LWS_IPV6_ENABLED(context)) {\n+\t\t\tv \u003d (struct sockaddr *)\u0026client_addr6;\n+\t\t\tn \u003d sizeof(client_addr6);\n+\t\t\tbzero((char *)v, n);\n+\t\t\tclient_addr6.sin6_family \u003d AF_INET6;\n+\t\t} else\n+#endif\n+\t\t{\n+\t\t\tv \u003d (struct sockaddr *)\u0026client_addr4;\n+\t\t\tn \u003d sizeof(client_addr4);\n+\t\t\tbzero((char *)v, n);\n+\t\t\tclient_addr4.sin_family \u003d AF_INET;\n+\t\t}\n \n-\t\tbzero((char *) \u0026client_addr, sizeof(client_addr));\n-\t\tclient_addr.sin_family \u003d AF_INET;\n-\n-\t\tif (context-\u003eiface !\u003d NULL) {\n-\t\t\tif (interface_to_sa(context-\u003eiface, \u0026client_addr,\n-\t\t\t\t\t\tsizeof(client_addr)) \u003c 0) {\n-\t\t\t\tlwsl_err(\u0022Unable to find interface %s\u005cn\u0022, context-\u003eiface);\n+\t\tif (context-\u003eiface) {\n+\t\t\tif (interface_to_sa(context, context-\u003eiface,\n+\t\t\t\t\t(struct sockaddr_in *)v, n) \u003c 0) {\n+\t\t\t\tlwsl_err(\u0022Unable to find interface %s\u005cn\u0022,\n+\t\t\t\t\t\t\t\tcontext-\u003eiface);\n \t\t\t\tcompatible_close(wsi-\u003esock);\n \t\t\t\tgoto failed;\n \t\t\t}\n \n-\t\t\tif (bind(wsi-\u003esock, (struct sockaddr *) \u0026client_addr,\n-\t\t\t\t\t\t\tsizeof(client_addr)) \u003c 0) {\n-\t\t\t\tlwsl_err(\u0022Error binding to interface %s\u0022, context-\u003eiface);\n+\t\t\tif (bind(wsi-\u003esock, v, n) \u003c 0) {\n+\t\t\t\tlwsl_err(\u0022Error binding to interface %s\u0022,\n+\t\t\t\t\t\t\t\tcontext-\u003eiface);\n \t\t\t\tcompatible_close(wsi-\u003esock);\n \t\t\t\tgoto failed;\n \t\t\t}\n \t\t}\n \t}\n \n-\tserver_addr.sin_family \u003d AF_INET;\n-\tserver_addr.sin_addr \u003d *((struct in_addr *)server_hostent-\u003eh_addr);\n-\n-\tbzero(\u0026server_addr.sin_zero, 8);\n+#ifdef LWS_WITH_IPV6\n+\tif (LWS_IPV6_ENABLED(context)) {\n+\t\tv \u003d (struct sockaddr *)\u0026server_addr6;\n+\t\tn \u003d sizeof(struct sockaddr_in6);\n+\t} else\n+#endif\n+\t{\n+\t\tv \u003d (struct sockaddr *)\u0026server_addr4;\n+\t\tn \u003d sizeof(struct sockaddr);\n+\t}\n \n-\tif (connect(wsi-\u003esock, (struct sockaddr *)\u0026server_addr,\n-\t\t\t sizeof(struct sockaddr)) \u003d\u003d -1 || LWS_ERRNO \u003d\u003d LWS_EISCONN) {\n+\tif (connect(wsi-\u003esock, v, n) \u003d\u003d -1 || LWS_ERRNO \u003d\u003d LWS_EISCONN) {\n \n \t\tif (LWS_ERRNO \u003d\u003d LWS_EALREADY || LWS_ERRNO \u003d\u003d LWS_EINPROGRESS) {\n \t\t\tlwsl_client(\u0022nonblocking connect retry\u005cn\u0022);\n@@ -108,7 +190,6 @@ struct libwebsocket *libwebsocket_client_connect_2(\n \t\t}\n \n \t\tif (LWS_ERRNO !\u003d LWS_EISCONN) {\n-\t\t\n \t\t\tlwsl_debug(\u0022Connect failed errno\u003d%d\u005cn\u0022, LWS_ERRNO);\n \t\t\tgoto failed;\n \t\t}\ndiff --git a/lib/libwebsockets.c b/lib/libwebsockets.c\nindex 08a1844..845335f 100644\n--- a/lib/libwebsockets.c\n+++ b/lib/libwebsockets.c\n@@ -576,66 +576,96 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context,\n \t\t\t\t\tchar *rip, int rip_len)\n {\n \tsocklen_t len;\n-\tstruct sockaddr_in sin;\n+#ifdef LWS_WITH_IPV6\n+\tstruct sockaddr_in6 sin6;\n+#endif\n+\tstruct sockaddr_in sin4;\n \tstruct hostent *host;\n \tstruct hostent *host1;\n \tchar ip[128];\n \tunsigned char *p;\n \tint n;\n-\tint ret \u003d -1;\n #ifdef AF_LOCAL\n \tstruct sockaddr_un *un;\n #endif\n+\tint ret \u003d -1;\n \n \trip[0] \u003d '\u005c0';\n \tname[0] \u003d '\u005c0';\n \n \tlws_latency_pre(context, wsi);\n \n-\tlen \u003d sizeof(sin);\n-\tif (getpeername(fd, (struct sockaddr *) \u0026sin, \u0026len) \u003c 0) {\n-\t\tlwsl_warn(\u0022getpeername: %s\u005cn\u0022, strerror(LWS_ERRNO));\n-\t\tgoto bail;\n-\t}\n+#ifdef LWS_WITH_IPV6\n+\tif (LWS_IPV6_ENABLED(context)) {\n \n-\thost \u003d gethostbyaddr((char *) \u0026sin.sin_addr, sizeof(sin.sin_addr),\n-\t\t\t\t\t\t\t\t AF_INET);\n-\tif (host \u003d\u003d NULL) {\n-\t\tlwsl_warn(\u0022gethostbyaddr: %s\u005cn\u0022, strerror(LWS_ERRNO));\n-\t\tgoto bail;\n-\t}\n+\t\tlen \u003d sizeof(sin6);\n+\t\tif (getpeername(fd, (struct sockaddr *) \u0026sin6, \u0026len) \u003c 0) {\n+\t\t\tlwsl_warn(\u0022getpeername: %s\u005cn\u0022, strerror(LWS_ERRNO));\n+\t\t\tgoto bail;\n+\t\t}\n \n-\tstrncpy(name, host-\u003eh_name, name_len);\n-\tname[name_len - 1] \u003d '\u005c0';\n+\t\tif (inet_ntop(AF_INET6, \u0026sin6.sin6_addr, rip, rip_len) \u003d\u003d NULL) {\n+\t\t\tperror(\u0022inet_ntop\u0022);\n+\t\t\tgoto bail;\n+\t\t}\n \n-\thost1 \u003d gethostbyname(host-\u003eh_name);\n-\tif (host1 \u003d\u003d NULL)\n-\t\tgoto bail;\n-\tp \u003d (unsigned char *)host1;\n-\tn \u003d 0;\n-\twhile (p !\u003d NULL) {\n-\t\tp \u003d (unsigned char *)host1-\u003eh_addr_list[n++];\n-\t\tif (p \u003d\u003d NULL)\n-\t\t\tcontinue;\n-\t\tif ((host1-\u003eh_addrtype !\u003d AF_INET)\n-#ifdef AF_LOCAL\n-\t\t\t\u0026\u0026 (host1-\u003eh_addrtype !\u003d AF_LOCAL)\n+\t\t// Strip off the IPv4 to IPv6 header if one exists\n+\t\tif (strncmp(rip, \u0022::ffff:\u0022, 7) \u003d\u003d 0) {\n+\t\t\tmemmove(rip, rip + 7, strlen(rip) - 6);\n+\t\t}\n+\n+\t\tgetnameinfo((struct sockaddr *)\u0026sin6,\n+\t\t\t\tsizeof(struct sockaddr_in6), name,\n+\t\t\t\t\t\t\tname_len, NULL, 0, 0);\n+\n+\t} else\n #endif\n-\t\t\t)\n-\t\t\tcontinue;\n+\t{\n+\t\tlen \u003d sizeof(sin4);\n+\t\tif (getpeername(fd, (struct sockaddr *) \u0026sin4, \u0026len) \u003c 0) {\n+\t\t\tlwsl_warn(\u0022getpeername: %s\u005cn\u0022, strerror(LWS_ERRNO));\n+\t\t\tgoto bail;\n+\t\t}\n+\t\thost \u003d gethostbyaddr((char *) \u0026sin4.sin_addr,\n+\t\t\t\t\t\tsizeof(sin4.sin_addr), AF_INET);\n+\t\tif (host \u003d\u003d NULL) {\n+\t\t\tlwsl_warn(\u0022gethostbyaddr: %s\u005cn\u0022, strerror(LWS_ERRNO));\n+\t\t\tgoto bail;\n+\t\t}\n \n-\t\tif (host1-\u003eh_addrtype \u003d\u003d AF_INET)\n-\t\t\tsprintf(ip, \u0022%u.%u.%u.%u\u0022, p[0], p[1], p[2], p[3]);\n-#ifdef AF_LOCAL\n-\t\telse {\n-\t\t\tun \u003d (struct sockaddr_un *)p;\n-\t\t\tstrncpy(ip, un-\u003esun_path, sizeof(ip) - 1);\n-\t\t\tip[sizeof(ip) - 1] \u003d '\u005c0';\n+\t\tstrncpy(name, host-\u003eh_name, name_len);\n+\t\tname[name_len - 1] \u003d '\u005c0';\n+\n+\t\thost1 \u003d gethostbyname(host-\u003eh_name);\n+\t\tif (host1 \u003d\u003d NULL)\n+\t\t\tgoto bail;\n+\t\tp \u003d (unsigned char *)host1;\n+\t\tn \u003d 0;\n+\t\twhile (p !\u003d NULL) {\n+\t\t\tp \u003d (unsigned char *)host1-\u003eh_addr_list[n++];\n+\t\t\tif (p \u003d\u003d NULL)\n+\t\t\t\tcontinue;\n+\t\t\tif ((host1-\u003eh_addrtype !\u003d AF_INET)\n+\t#ifdef AF_LOCAL\n+\t\t\t\t\u0026\u0026 (host1-\u003eh_addrtype !\u003d AF_LOCAL)\n+\t#endif\n+\t\t\t\t)\n+\t\t\t\tcontinue;\n+\n+\t\t\tif (host1-\u003eh_addrtype \u003d\u003d AF_INET)\n+\t\t\t\tsprintf(ip, \u0022%u.%u.%u.%u\u0022,\n+\t\t\t\t\t\tp[0], p[1], p[2], p[3]);\n+\t#ifdef AF_LOCAL\n+\t\t\telse {\n+\t\t\t\tun \u003d (struct sockaddr_un *)p;\n+\t\t\t\tstrncpy(ip, un-\u003esun_path, sizeof(ip) - 1);\n+\t\t\t\tip[sizeof(ip) - 1] \u003d '\u005c0';\n+\t\t\t}\n+\t#endif\n+\t\t\tp \u003d NULL;\n+\t\t\tstrncpy(rip, ip, rip_len);\n+\t\t\trip[rip_len - 1] \u003d '\u005c0';\n \t\t}\n-#endif\n-\t\tp \u003d NULL;\n-\t\tstrncpy(rip, ip, rip_len);\n-\t\trip[rip_len - 1] \u003d '\u005c0';\n \t}\n \n \tret \u003d 0;\n@@ -2053,7 +2083,11 @@ libwebsocket_create_context(struct lws_context_creation_info *info)\n #ifndef LWS_NO_SERVER\n \tint opt \u003d 1;\n \tstruct libwebsocket *wsi;\n-\tstruct sockaddr_in serv_addr;\n+#ifdef LWS_WITH_IPV6\n+\tstruct sockaddr_in6 serv_addr6;\n+#endif\n+\tstruct sockaddr_in serv_addr4;\n+\tstruct sockaddr *v;\n #endif\n #ifndef LWS_NO_EXTENSIONS\n \tint m;\n@@ -2070,6 +2104,14 @@ libwebsocket_create_context(struct lws_context_creation_info *info)\n \n \tlwsl_notice(\u0022Initial logging level %d\u005cn\u0022, log_level);\n \tlwsl_notice(\u0022Library version: %s\u005cn\u0022, library_version);\n+#ifdef LWS_WITH_IPV6\n+\tif (!(info-\u003eoptions \u0026 LWS_SERVER_OPTION_DISABLE_IPV6))\n+\t\tlwsl_notice(\u0022IPV6 compiled in and enabled\u005cn\u0022);\n+\telse\n+\t\tlwsl_notice(\u0022IPV6 compiled in but disabled\u005cn\u0022);\n+#else\n+\tlwsl_notice(\u0022IPV6 not compiled in\u005cn\u0022);\n+#endif\n \tlwsl_info(\u0022 LWS_MAX_HEADER_LEN: %u\u005cn\u0022, LWS_MAX_HEADER_LEN);\n \tlwsl_info(\u0022 LWS_MAX_PROTOCOLS: %u\u005cn\u0022, LWS_MAX_PROTOCOLS);\n #ifndef LWS_NO_EXTENSIONS\n@@ -2489,7 +2531,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info)\n \t\t\t\t\t\t context-\u003essl_ctx, NULL, 0);\n \t}\n \n-\tif(info-\u003eoptions \u0026 LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT) {\n+\tif (info-\u003eoptions \u0026 LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT) {\n \t\t/* Normally SSL listener rejects non-ssl, optionally allow */\n \t\tcontext-\u003eallow_non_ssl_on_ssl_port \u003d 1;\n \t}\n@@ -2538,7 +2580,13 @@ libwebsocket_create_context(struct lws_context_creation_info *info)\n \tif (info-\u003eport !\u003d CONTEXT_PORT_NO_LISTEN) {\n \t\tint sockfd;\n \n-\t\tsockfd \u003d socket(AF_INET, SOCK_STREAM, 0);\n+#ifdef LWS_WITH_IPV6\n+\t\tif (LWS_IPV6_ENABLED(context))\n+\t\t\tsockfd \u003d socket(AF_INET6, SOCK_STREAM, 0);\n+\t\telse\n+#endif\n+\t\t\tsockfd \u003d socket(AF_INET, SOCK_STREAM, 0);\n+\n \t\tif (sockfd \u003c 0) {\n \t\t\tlwsl_err(\u0022ERROR opening socket\u005cn\u0022);\n \t\t\tgoto bail;\n@@ -2562,37 +2610,51 @@ libwebsocket_create_context(struct lws_context_creation_info *info)\n \t\tfcntl(sockfd, F_SETFL, O_NONBLOCK);\n \t\t#endif\n \n-\t\tbzero((char *) \u0026serv_addr, sizeof(serv_addr));\n-\t\tserv_addr.sin_family \u003d AF_INET;\n-\t\tif (info-\u003eiface \u003d\u003d NULL)\n-\t\t\tserv_addr.sin_addr.s_addr \u003d INADDR_ANY;\n-\t\telse\n-\t\t\tif (interface_to_sa(info-\u003eiface, \u0026serv_addr,\n-\t\t\t\t\t\tsizeof(serv_addr)) \u003c 0) {\n-\t\t\t\tlwsl_err(\u0022Unable to find interface %s\u005cn\u0022,\n-\t\t\t\t\t\t\tinfo-\u003eiface);\n-\t\t\t\tcompatible_close(sockfd);\n-\t\t\t\tgoto bail;\n+#ifdef LWS_WITH_IPV6\n+\t\tif (LWS_IPV6_ENABLED(context)) {\n+\t\t\tv \u003d (struct sockaddr *)\u0026serv_addr6;\n+\t\t\tn \u003d sizeof(struct sockaddr_in6);\n+\t\t\tbzero((char *) \u0026serv_addr6, sizeof(serv_addr6));\n+\t\t\tserv_addr6.sin6_addr \u003d in6addr_any;\n+\t\t\tserv_addr6.sin6_family \u003d AF_INET6;\n+\t\t\tserv_addr6.sin6_port \u003d htons(info-\u003eport);\n+\t\t} else\n+#endif\n+\t\t{\n+\t\t\tv \u003d (struct sockaddr *)\u0026serv_addr4;\n+\t\t\tn \u003d sizeof(serv_addr4);\n+\t\t\tbzero((char *) \u0026serv_addr4, sizeof(serv_addr4));\n+\t\t\tserv_addr4.sin_addr.s_addr \u003d INADDR_ANY;\n+\t\t\tserv_addr4.sin_family \u003d AF_INET;\n+\t\t\tserv_addr4.sin_port \u003d htons(info-\u003eport);\n+\n+\t\t\tif (info-\u003eiface) {\n+\t\t\t\tif (interface_to_sa(context, info-\u003eiface,\n+\t\t\t\t\t (struct sockaddr_in *)v, n) \u003c 0) {\n+\t\t\t\t\tlwsl_err(\u0022Unable to find interface %s\u005cn\u0022,\n+\t\t\t\t\t\t\t\tinfo-\u003eiface);\n+\t\t\t\t\tcompatible_close(sockfd);\n+\t\t\t\t\tgoto bail;\n+\t\t\t\t}\n \t\t\t}\n-\t\tserv_addr.sin_port \u003d htons(info-\u003eport);\n+\t\t} /* ipv4 */\n \n-\t\tn \u003d bind(sockfd, (struct sockaddr *) \u0026serv_addr,\n-\t\t\t\t\t\t\t sizeof(serv_addr));\n+\t\tn \u003d bind(sockfd, v, n);\n \t\tif (n \u003c 0) {\n \t\t\tlwsl_err(\u0022ERROR on binding to port %d (%d %d)\u005cn\u0022,\n-\t\t\t\t\t\t\tinfo-\u003eport, n, LWS_ERRNO);\n+\t\t\t\t\t\t info-\u003eport, n, LWS_ERRNO);\n \t\t\tcompatible_close(sockfd);\n \t\t\tgoto bail;\n \t\t}\n \t\t\n-\tstruct sockaddr_in sin;\n-\tsocklen_t len \u003d sizeof(sin);\n-\tif (getsockname(sockfd, (struct sockaddr *)\u0026sin, \u0026len) \u003d\u003d -1)\n-\t\tperror(\u0022getsockname\u0022);\n-\telse\n-\t\tinfo-\u003eport \u003d ntohs(sin.sin_port);\n+\t\tstruct sockaddr_in sin;\n+\t\tsocklen_t len \u003d sizeof(sin);\n+\t\tif (getsockname(sockfd, (struct sockaddr *)\u0026sin, \u0026len) \u003d\u003d -1)\n+\t\t\tperror(\u0022getsockname\u0022);\n+\t\telse\n+\t\t\tinfo-\u003eport \u003d ntohs(sin.sin_port);\n \t\n-\tcontext-\u003elisten_port \u003d info-\u003eport;\n+\t\tcontext-\u003elisten_port \u003d info-\u003eport;\n \n \t\twsi \u003d (struct libwebsocket *)malloc(\n \t\t\t\t\tsizeof(struct libwebsocket));\n@@ -2861,8 +2923,11 @@ LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int leve\n \t\tlwsl_emit \u003d log_emit_function;\n }\n \n+/* cast a struct sockaddr_in6 * into addr for ipv6 */\n+\n int\n-interface_to_sa(const char *ifname, struct sockaddr_in *addr, size_t addrlen)\n+interface_to_sa(struct libwebsocket_context *context,\n+\t\tconst char *ifname, struct sockaddr_in *addr, size_t addrlen)\n {\n \tint rc \u003d -1;\n #if defined(WIN32) || defined(_WIN32)\n@@ -2870,19 +2935,50 @@ interface_to_sa(const char *ifname, struct sockaddr_in *addr, size_t addrlen)\n #else\n \tstruct ifaddrs *ifr;\n \tstruct ifaddrs *ifc;\n-\tstruct sockaddr_in *sin;\n+#ifdef LWS_WITH_IPV6\n+\tstruct sockaddr_in6 *addr6 \u003d (struct sockaddr_in6 *)addr;\n+#endif\n \n \tgetifaddrs(\u0026ifr);\n \tfor (ifc \u003d ifr; ifc !\u003d NULL \u0026\u0026 rc; ifc \u003d ifc-\u003eifa_next) {\n-\t\tif (ifc-\u003eifa_addr \u003d\u003d NULL)\n+\t\tif (!ifc-\u003eifa_addr)\n \t\t\tcontinue;\n+\n \t\tlwsl_info(\u0022 interface %s vs %s\u005cn\u0022, ifc-\u003eifa_name, ifname);\n+\n \t\tif (strcmp(ifc-\u003eifa_name, ifname))\n \t\t\tcontinue;\n-\t\tsin \u003d (struct sockaddr_in *)ifc-\u003eifa_addr;\n-\t\tif (sin-\u003esin_family !\u003d AF_INET)\n+\n+\t\tswitch (ifc-\u003eifa_addr-\u003esa_family) {\n+\t\tcase AF_INET:\n+#ifdef LWS_WITH_IPV6\n+\t\t\tif (LWS_IPV6_ENABLED(context)) {\n+\t\t\t\t/* map IPv4 to IPv6 */\n+\t\t\t\tbzero((char *)\u0026addr6-\u003esin6_addr,\n+\t\t\t\t\t\tsizeof(struct in6_addr));\n+\t\t\t\taddr6-\u003esin6_addr.s6_addr16[5] \u003d 0xffff;\n+\t\t\t\tbcopy(\u0026((struct sockaddr_in *)ifc-\u003eifa_addr)-\u003e\n+\t\t\t\t\t\t\t\tsin_addr,\n+\t\t\t\t\t\u0026addr6-\u003esin6_addr.s6_addr16[6],\n+\t\t\t\t\t\t\tsizeof(struct in_addr));\n+\t\t\t} else\n+#endif\n+\t\t\t\tmemcpy(addr,\n+\t\t\t\t\t(struct sockaddr_in *)ifc-\u003eifa_addr,\n+\t\t\t\t\t\t sizeof(struct sockaddr_in));\n+\t\t\tbreak;\n+#ifdef LWS_WITH_IPV6\n+\t\tcase AF_INET6:\n+\t\t\tif (rc \u003e\u003d 0)\n+\t\t\t\tbreak;\n+\t\t\tmemcpy(\u0026addr6-\u003esin6_addr,\n+\t\t\t \u0026((struct sockaddr_in6 *)ifc-\u003eifa_addr)-\u003esin6_addr,\n+\t\t\t\t\t\t sizeof(struct in6_addr));\n+\t\t\tbreak;\n+#endif\n+\t\tdefault:\n \t\t\tcontinue;\n-\t\tmemcpy(addr, sin, addrlen);\n+\t\t}\n \t\trc \u003d 0;\n \t}\n \ndiff --git a/lib/libwebsockets.h b/lib/libwebsockets.h\nindex 5bdd8b6..5c41a57 100644\n--- a/lib/libwebsockets.h\n+++ b/lib/libwebsockets.h\n@@ -149,7 +149,8 @@ enum libwebsocket_context_options {\n \tLWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT \u003d 2,\n \tLWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME \u003d 4,\n \tLWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT \u003d 8,\n-\tLWS_SERVER_OPTION_LIBEV \u003d 16\n+\tLWS_SERVER_OPTION_LIBEV \u003d 16,\n+\tLWS_SERVER_OPTION_DISABLE_IPV6 \u003d 32,\n };\n \n enum libwebsocket_callback_reasons {\ndiff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h\nindex f56aba5..d2fdf95 100644\n--- a/lib/private-libwebsockets.h\n+++ b/lib/private-libwebsockets.h\n@@ -354,6 +354,11 @@ struct libwebsocket_context {\n #define LWS_LIBEV_ENABLED(context) (0)\n #endif\n \n+#ifdef LWS_WITH_IPV6\n+#define LWS_IPV6_ENABLED(context) (context-\u003eoptions \u0026 LWS_SERVER_OPTION_DISABLE_IPV6)\n+#else\n+#define LWS_IPV6_ENABLED(context) (0)\n+#endif\n \n enum uri_path_states {\n \tURIPS_IDLE,\n@@ -618,8 +623,8 @@ LWS_EXTERN int handshake_0405(struct libwebsocket_context *context,\n LWS_EXTERN int get_daemonize_pid();\n #endif\n \n-extern int interface_to_sa(const char *ifname,\n-\t\t struct sockaddr_in *addr, size_t addrlen);\n+extern int interface_to_sa(struct libwebsocket_context *context,\n+\t\tconst char *ifname, struct sockaddr_in *addr, size_t addrlen);\n \n #ifndef LWS_OPENSSL_SUPPORT\n \n","s":{"c":1754122054,"u": 9262}} ],"g": 13150,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}