diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit_networking.erl | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/rabbit_networking.erl b/src/rabbit_networking.erl index 42eacc58c7..f394a1ab04 100644 --- a/src/rabbit_networking.erl +++ b/src/rabbit_networking.erl @@ -174,6 +174,17 @@ resolve_family({_,_,_,_,_,_,_,_}, auto) -> inet6; resolve_family(IP, auto) -> throw({error, {strange_family, IP}}); resolve_family(_, F) -> F. +check_tcp_listener_address(NamePrefix, Port) when is_integer(Port) -> + case ipv6_status(Port) of + ipv4_only -> + check_tcp_listener_address(NamePrefix, {"0.0.0.0", Port, inet}); + ipv6_single_stack -> + check_tcp_listener_address(NamePrefix, {"::", Port, inet6}); + ipv6_dual_stack -> + check_tcp_listener_address(NamePrefix, {"0.0.0.0", Port, inet}) + ++ check_tcp_listener_address(NamePrefix, {"::", Port, inet6}) + end; + check_tcp_listener_address(NamePrefix, {Host, Port}) -> %% auto: determine family IPv4 / IPv6 after converting to IP address check_tcp_listener_address(NamePrefix, {Host, Port, auto}); @@ -320,3 +331,37 @@ hostname() -> end. cmap(F) -> rabbit_misc:filter_exit_map(F, connections()). + +%%-------------------------------------------------------------------- + +%% How to test on Linux: +%% Single stack (default): +%% echo 0 > /proc/sys/net/ipv6/bindv6only +%% Dual stack: +%% echo 1 > /proc/sys/net/ipv6/bindv6only +%% IPv4 only: +%% add ipv6.disable=1 to GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub then +%% sudo update-grub && sudo reboot + +ipv6_status(Port) -> + %% Unfortunately it seems there is no way to detect single vs dual stack + %% apart from attempting to bind to the socket. + IPv4 = [inet, {ip, {0,0,0,0}}], + IPv6 = [inet6, {ip, {0,0,0,0,0,0,0,0}}], + case gen_tcp:listen(Port, IPv6) of + {ok, LSock6} -> + Status = case gen_tcp:listen(Port, IPv4) of + {ok, LSock4} -> + gen_tcp:close(LSock4), + ipv6_dual_stack; + {error, _} -> + ipv6_single_stack + end, + gen_tcp:close(LSock6), + Status; + {error, _} -> + %% It could be that there's a general problem binding to + %% the port, but plow on; the error will get picked up + %% later when we bind for real. + ipv4_only + end. |
