diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index ca534a50..dbc70920 100755 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -30,6 +30,14 @@ #include #endif +#ifdef LWS_USE_IPV6 +#if defined(WIN32) || defined(_WIN32) +#include +#else +#include +#endif +#endif + int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE; static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr; @@ -1595,7 +1603,46 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port, v = (struct sockaddr *)&serv_addr6; n = sizeof(struct sockaddr_in6); bzero((char *) &serv_addr6, sizeof(serv_addr6)); - serv_addr6.sin6_addr = in6addr_any; + + if (iface && + interface_to_sa(vhost->context, iface, + (struct sockaddr_in *)v, n) < 0) { + lwsl_err("Unable to find interface %s\n", iface); + return -1; + } + + if (iface) { + struct ifaddrs *addrs, *addr; + char ip[NI_MAXHOST]; + unsigned int i; + + getifaddrs(&addrs); + for (addr = addrs; addr; addr = addr->ifa_next) { + if (!addr->ifa_addr || + addr->ifa_addr->sa_family != AF_INET6) + continue; + + getnameinfo(addr->ifa_addr, + sizeof(struct sockaddr_in6), + ip, sizeof(ip), + NULL, 0, NI_NUMERICHOST); + + i = 0; + while (ip[i]) + if (ip[i++] == '%') { + ip[i - 1] = '\0'; + break; + } + + if (!strcmp(ip, iface)) { + serv_addr6.sin6_scope_id = + if_nametoindex(addr->ifa_name); + break; + } + } + freeifaddrs(addrs); + } + serv_addr6.sin6_family = AF_INET6; serv_addr6.sin6_port = htons(port); } else