@@ -833,11 +833,27 @@ lws_create_adopt_udp2(struct lws *wsi, const char *ads,
833833 }
834834
835835#if defined(LWS_WITH_IPV6 ) && defined(IPV6_V6ONLY )
836+ /*
837+ * For IPv6 UDP sockets we own the IPV6_V6ONLY state rather
838+ * than inheriting the OS default (which is 0 = dual-stack on
839+ * Linux/macOS but 1 = v6-only on Windows):
840+ *
841+ * - by default (!MODIFY) we force v6-only, matching the TCP
842+ * listen path. Callers that want both families bind two
843+ * sockets (:: and 0.0.0.0) and rely on this -- e.g. dht,
844+ * auth_dns, extip.
845+ * - MODIFY && !VALUE explicitly requests dual-stack, so a
846+ * lone :: listener also receives IPv4-mapped packets
847+ * (the QUIC adoption path). Force V6ONLY=0 here, since
848+ * the OS default cannot be relied on (Windows = 1).
849+ * - MODIFY | VALUE explicitly requests v6-only.
850+ */
836851 if (s -> dest .sa4 .sin_family == AF_INET6 &&
837- !lws_sa46_is_ipv4_mapped (& s -> dest ) &&
838- (!(wsi -> a .vhost -> options & LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY ) ||
839- (wsi -> a .vhost -> options & LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE ))) {
840- int opt = 1 ;
852+ !lws_sa46_is_ipv4_mapped (& s -> dest )) {
853+ int opt = !(wsi -> a .vhost -> options &
854+ LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY ) ||
855+ !!(wsi -> a .vhost -> options &
856+ LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE );
841857 if (setsockopt (sock .sockfd , IPPROTO_IPV6 , IPV6_V6ONLY ,
842858 (const void * )& opt , sizeof (opt )) < 0 ) {
843859 lwsl_vhost_notice (wsi -> a .vhost , "set IPV6_V6ONLY fail" );
@@ -1024,10 +1040,11 @@ lws_create_adopt_udp2(struct lws *wsi, const char *ads,
10241040
10251041#if defined(LWS_WITH_IPV6 ) && defined(IPV6_V6ONLY )
10261042 if (dest .sa4 .sin_family == AF_INET6 &&
1027- !lws_sa46_is_ipv4_mapped (& dest ) &&
1028- (!(wsi -> a .vhost -> options & LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY ) ||
1029- (wsi -> a .vhost -> options & LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE ))) {
1030- int opt = 1 ;
1043+ !lws_sa46_is_ipv4_mapped (& dest )) {
1044+ int opt = !(wsi -> a .vhost -> options &
1045+ LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY ) ||
1046+ !!(wsi -> a .vhost -> options &
1047+ LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE );
10311048 if (setsockopt (sock .sockfd , IPPROTO_IPV6 , IPV6_V6ONLY ,
10321049 (const void * )& opt , sizeof (opt )) < 0 ) {
10331050 lwsl_vhost_notice (wsi -> a .vhost , "set IPV6_V6ONLY fail" );
0 commit comments