Fossil SCM
Enhance the socket listener logic on unix so that it makes sure the IPV6_V6ONLY socket option is disabled, as we are told that this option is enabled by default on FreeBSD.
Commit
0eeaa6224cdbdbda632c5422d98aedd66603ec8bbbe1e11ea3f6b10f18f27e83
Parent
2d3ace5a9fb4de5…
1 file changed
+17
+17
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -2498,10 +2498,26 @@ | ||
| 2498 | 2498 | fossil_free(zToFree); |
| 2499 | 2499 | fgetc(g.httpIn); /* Read past the "," separating header from content */ |
| 2500 | 2500 | cgi_init(); |
| 2501 | 2501 | } |
| 2502 | 2502 | |
| 2503 | +/* | |
| 2504 | +** Change the listening socket, if necessary, so that it will accept both IPv4 | |
| 2505 | +** and IPv6 | |
| 2506 | +*/ | |
| 2507 | +static void allowBothIpV4andV6(int listener){ | |
| 2508 | +#if defined(IPV6_V6ONLY) | |
| 2509 | + int ipv6only = -1; | |
| 2510 | + socklen_t ipv6only_size = sizeof(ipv6only); | |
| 2511 | + getsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &ipv6only_size); | |
| 2512 | + if( ipv6only ){ | |
| 2513 | + ipv6only = 0; | |
| 2514 | + setsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, ipv6only_size); | |
| 2515 | + } | |
| 2516 | +#endif /* defined(IPV6_ONLY) */ | |
| 2517 | +} | |
| 2518 | + | |
| 2503 | 2519 | |
| 2504 | 2520 | #if INTERFACE |
| 2505 | 2521 | /* |
| 2506 | 2522 | ** Bitmap values for the flags parameter to cgi_http_server(). |
| 2507 | 2523 | */ |
| @@ -2625,10 +2641,11 @@ | ||
| 2625 | 2641 | listener = socket(AF_INET6, SOCK_STREAM, 0); |
| 2626 | 2642 | if( listener<0 ){ |
| 2627 | 2643 | iPort++; |
| 2628 | 2644 | continue; |
| 2629 | 2645 | } |
| 2646 | + allowBothIpV4andV6(listener); | |
| 2630 | 2647 | } |
| 2631 | 2648 | |
| 2632 | 2649 | /* if we can't terminate nicely, at least allow the socket to be reused */ |
| 2633 | 2650 | setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); |
| 2634 | 2651 | |
| 2635 | 2652 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -2498,10 +2498,26 @@ | |
| 2498 | fossil_free(zToFree); |
| 2499 | fgetc(g.httpIn); /* Read past the "," separating header from content */ |
| 2500 | cgi_init(); |
| 2501 | } |
| 2502 | |
| 2503 | |
| 2504 | #if INTERFACE |
| 2505 | /* |
| 2506 | ** Bitmap values for the flags parameter to cgi_http_server(). |
| 2507 | */ |
| @@ -2625,10 +2641,11 @@ | |
| 2625 | listener = socket(AF_INET6, SOCK_STREAM, 0); |
| 2626 | if( listener<0 ){ |
| 2627 | iPort++; |
| 2628 | continue; |
| 2629 | } |
| 2630 | } |
| 2631 | |
| 2632 | /* if we can't terminate nicely, at least allow the socket to be reused */ |
| 2633 | setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); |
| 2634 | |
| 2635 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -2498,10 +2498,26 @@ | |
| 2498 | fossil_free(zToFree); |
| 2499 | fgetc(g.httpIn); /* Read past the "," separating header from content */ |
| 2500 | cgi_init(); |
| 2501 | } |
| 2502 | |
| 2503 | /* |
| 2504 | ** Change the listening socket, if necessary, so that it will accept both IPv4 |
| 2505 | ** and IPv6 |
| 2506 | */ |
| 2507 | static void allowBothIpV4andV6(int listener){ |
| 2508 | #if defined(IPV6_V6ONLY) |
| 2509 | int ipv6only = -1; |
| 2510 | socklen_t ipv6only_size = sizeof(ipv6only); |
| 2511 | getsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &ipv6only_size); |
| 2512 | if( ipv6only ){ |
| 2513 | ipv6only = 0; |
| 2514 | setsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, ipv6only_size); |
| 2515 | } |
| 2516 | #endif /* defined(IPV6_ONLY) */ |
| 2517 | } |
| 2518 | |
| 2519 | |
| 2520 | #if INTERFACE |
| 2521 | /* |
| 2522 | ** Bitmap values for the flags parameter to cgi_http_server(). |
| 2523 | */ |
| @@ -2625,10 +2641,11 @@ | |
| 2641 | listener = socket(AF_INET6, SOCK_STREAM, 0); |
| 2642 | if( listener<0 ){ |
| 2643 | iPort++; |
| 2644 | continue; |
| 2645 | } |
| 2646 | allowBothIpV4andV6(listener); |
| 2647 | } |
| 2648 | |
| 2649 | /* if we can't terminate nicely, at least allow the socket to be reused */ |
| 2650 | setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); |
| 2651 | |
| 2652 |