diff --git a/src/Cedar/Listener.c b/src/Cedar/Listener.c index 1eb876f5..6ea0d5cc 100644 --- a/src/Cedar/Listener.c +++ b/src/Cedar/Listener.c @@ -386,7 +386,14 @@ void ListenerTCPMainLoop(LISTENER *r) } else { - s = ListenEx6(r->Port, r->LocalOnly); + if (r->Cedar->Server == NULL) + { + s = ListenEx6(r->Port, r->LocalOnly); + } + else + { + s = ListenEx63(r->Port, r->LocalOnly, false, &r->Cedar->Server->ListenIP); + } } } else if (r->Protocol == LISTENER_INPROC) diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index 976cc97c..50056ecd 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -11224,16 +11224,21 @@ SOCK *NewUDP6(UINT port, IP *ip) addr.sin6_scope_id = ip->ipv6_scope_id; } + UINT true_flag = 1; + UINT false_flag = 0; +#ifdef OS_UNIX + // It is necessary to set the IPv6 Only flag on a UNIX system + (void)setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &true_flag, sizeof(true_flag)); +#endif // OS_UNIX + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0) { // Failure if (port != 0) { - UINT true_flag = 1; (void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(true_flag)); if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0) { - UINT false_flag = 0; (void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&false_flag, sizeof(false_flag)); #ifdef SO_EXCLUSIVEADDRUSE (void)setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&true_flag, sizeof(true_flag)); @@ -12848,6 +12853,10 @@ SOCK *ListenEx6(UINT port, bool local_only) return ListenEx62(port, local_only, false); } SOCK *ListenEx62(UINT port, bool local_only, bool enable_ca) +{ + return ListenEx63(port, local_only, enable_ca, NULL); +} +SOCK *ListenEx63(UINT port, bool local_only, bool enable_ca, IP *listen_ip) { SOCKET s; SOCK *sock; @@ -12867,6 +12876,18 @@ SOCK *ListenEx62(UINT port, bool local_only, bool enable_ca) GetLocalHostIP6(&localhost); addr.sin6_port = htons((UINT)port); + if (listen_ip == NULL || IsZeroIP(listen_ip)) + { + addr.sin6_addr = in6addr_any; + } + else if (IsIP6(listen_ip)) + { + IPToInAddr6(&addr.sin6_addr, listen_ip); + } + else + { + return NULL; + } addr.sin6_family = AF_INET6; if (local_only) @@ -12960,14 +12981,18 @@ SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca, IP *listen_ip) SetIP(&localhost, 127, 0, 0, 1); addr.sin_port = htons((UINT)port); - if (listen_ip == NULL) + if (listen_ip == NULL || IsZeroIP(listen_ip)) { *((UINT *)&addr.sin_addr) = htonl(INADDR_ANY); } - else + else if (IsIP4(listen_ip)) { IPToInAddr(&addr.sin_addr, listen_ip); } + else + { + return NULL; + } addr.sin_family = AF_INET; if (local_only) @@ -17594,7 +17619,7 @@ void UdpListenerThread(THREAD *thread, void *param) { IP *ip = LIST_DATA(iplist, i); - if (CmpIpAddr(ip, &u->ListenIP) != 0) + if (CmpIpAddr(ip, &u->ListenIP) != 0 && (!IsZeroIP(ip) || !IsZeroIP(&u->ListenIP))) { continue; } diff --git a/src/Mayaqua/Network.h b/src/Mayaqua/Network.h index 25ce9360..aa614f28 100644 --- a/src/Mayaqua/Network.h +++ b/src/Mayaqua/Network.h @@ -1069,6 +1069,7 @@ SOCK *ListenEx(UINT port, bool local_only); SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca, IP *listen_ip); SOCK *ListenEx6(UINT port, bool local_only); SOCK *ListenEx62(UINT port, bool local_only, bool enable_ca); +SOCK *ListenEx63(UINT port, bool local_only, bool enable_ca, IP *listen_ip); SOCK *Accept(SOCK *sock); SOCK *Accept6(SOCK *sock); UINT Send(SOCK *sock, void *data, UINT size, bool secure);