diff options
author | Simon MacMullen <simon@rabbitmq.com> | 2011-01-19 11:15:35 +0000 |
---|---|---|
committer | Simon MacMullen <simon@rabbitmq.com> | 2011-01-19 11:15:35 +0000 |
commit | 64dc7c3d98354b569ae2498313c6e560a0094144 (patch) | |
tree | d7b4a83210cff6d4a6cd2346c0bbd1032572fdf9 | |
parent | 425439362c0a9fb8560401fbff0395e4df60ec5b (diff) | |
download | rabbitmq-server-64dc7c3d98354b569ae2498313c6e560a0094144.tar.gz |
Make port_to_listeners distinguish all the cases now, and write even more comments.
-rw-r--r-- | src/rabbit_networking.erl | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/src/rabbit_networking.erl b/src/rabbit_networking.erl index be1f4f80..bb5e814c 100644 --- a/src/rabbit_networking.erl +++ b/src/rabbit_networking.erl @@ -335,6 +335,7 @@ cmap(F) -> rabbit_misc:filter_exit_map(F, connections()). %% * Those which treat IPv4 addresses as a special kind of IPv6 address %% ("Single stack") %% - Linux by default, Windows Vista and later +%% - We also treat any (hypothetical?) IPv6-only machine the same way %% * Those which consider IPv6 and IPv4 to be completely separate things %% ("Dual stack") %% - OpenBSD, Windows XP / 2003, Linux if so configured @@ -361,7 +362,7 @@ cmap(F) -> rabbit_misc:filter_exit_map(F, connections()). %% want to bind to "0.0.0.0". %% %% Unfortunately it seems there is no way to detect single vs dual stack -%% apart from attempting to bind to the socket. +%% apart from attempting to bind to the port. port_to_listeners(Port) -> IPv4 = [inet, {ip, {0,0,0,0}}], IPv6 = [inet6, {ip, {0,0,0,0,0,0,0,0}}], @@ -369,16 +370,34 @@ port_to_listeners(Port) -> IPv6Listener = {"::", Port, inet6}, case gen_tcp:listen(Port, IPv6) of {ok, LSock6} -> - Status = case gen_tcp:listen(Port, IPv4) of - {ok, LSock4} -> gen_tcp:close(LSock4), - [IPv4Listener, IPv6Listener]; - {error, _} -> [IPv6Listener] - end, - gen_tcp:close(LSock6), - Status; + case gen_tcp:listen(Port, IPv4) of + {ok, LSock4} -> + %% Dual stack + gen_tcp:close(LSock6), + gen_tcp:close(LSock4), + [IPv4Listener, IPv6Listener]; + %% Checking the error here would only let us + %% distinguish single stack IPv6 / IPv4 vs IPv6 only, + %% which we figure out below anyway. + {error, _} -> + gen_tcp:close(LSock6), + case gen_tcp:listen(Port, IPv4) of + %% Single stack + {ok, LSock4} -> gen_tcp:close(LSock4), + [IPv6Listener]; + %% IPv6-only machine. Welcome to the future. + {error, eafnosupport} -> [IPv6Listener]; + %% Dual stack machine with something already + %% on IPv4, return that to force an error later. + {error, _} -> [IPv4Listener] + end + end; + {error, eafnosupport} -> + %% IPv4-only machine. Welcome to the 90s. + [IPv4Listener]; {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. - [IPv4Listener] + %% There's a general problem binding to the port, but plow + %% on; the error will get picked up later when we bind for + %% real. Return both listeners to ensure this. + [IPv4Listener, IPv6Listener] end. |