From e0b33dc2585f230554da7f5bd165cd0c40b72783 Mon Sep 17 00:00:00 2001 From: JianBo He Date: Fri, 22 Jul 2022 10:31:59 +0800 Subject: [PATCH] fix(listener): support listen on ipv6 address --- apps/emqx/src/emqx_schema.erl | 27 ++++++++++++++++++++-- apps/emqx_management/src/emqx_mgmt_cli.erl | 14 ++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index 5652b37f7..a6cdb4772 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -2113,9 +2113,13 @@ to_comma_separated_atoms(Str) -> to_bar_separated_list(Str) -> {ok, string:tokens(Str, "| ")}. +%% @doc support the following format: +%% - 127.0.0.1:1883 +%% - ::1:1883 +%% - [::1]:1883 to_ip_port(Str) -> - case string:tokens(Str, ": ") of - [Ip, Port] -> + case split_ip_port(Str) of + {Ip, Port} -> PortVal = list_to_integer(Port), case inet:parse_address(Ip) of {ok, R} -> @@ -2133,6 +2137,25 @@ to_ip_port(Str) -> {error, Str} end. +split_ip_port(Str) -> + case lists:split(string:rchr(Str, $:), Str) of + %% no port + {[], Str} -> + error; + {IpPlusColon, PortString} -> + IpStr0 = lists:droplast(IpPlusColon), + case IpStr0 of + %% dropp head/tail brackets + [$[ | S] -> + case lists:last(S) of + $] -> {lists:droplast(S), PortString}; + _ -> error + end; + _ -> + {IpStr0, PortString} + end + end. + to_erl_cipher_suite(Str) -> case ssl:str_to_suite(Str) of {error, Reason} -> error({invalid_cipher, Reason}); diff --git a/apps/emqx_management/src/emqx_mgmt_cli.erl b/apps/emqx_management/src/emqx_mgmt_cli.erl index e6730a18c..c846c9d58 100644 --- a/apps/emqx_management/src/emqx_mgmt_cli.erl +++ b/apps/emqx_management/src/emqx_mgmt_cli.erl @@ -566,23 +566,23 @@ trace_type(_, _) -> error. listeners([]) -> lists:foreach( fun({ID, Conf}) -> - {Host, Port} = maps:get(bind, Conf), + Bind = maps:get(bind, Conf), Acceptors = maps:get(acceptors, Conf), ProxyProtocol = maps:get(proxy_protocol, Conf, undefined), Running = maps:get(running, Conf), CurrentConns = - case emqx_listeners:current_conns(ID, {Host, Port}) of + case emqx_listeners:current_conns(ID, Bind) of {error, _} -> []; CC -> [{current_conn, CC}] end, MaxConn = - case emqx_listeners:max_conns(ID, {Host, Port}) of + case emqx_listeners:max_conns(ID, Bind) of {error, _} -> []; MC -> [{max_conns, MC}] end, Info = [ - {listen_on, {string, format_listen_on(Port)}}, + {listen_on, {string, format_listen_on(Bind)}}, {acceptors, Acceptors}, {proxy_protocol, ProxyProtocol}, {running, Running} @@ -806,8 +806,10 @@ format_listen_on(Port) when is_integer(Port) -> io_lib:format("0.0.0.0:~w", [Port]); format_listen_on({Addr, Port}) when is_list(Addr) -> io_lib:format("~ts:~w", [Addr, Port]); -format_listen_on({Addr, Port}) when is_tuple(Addr) -> - io_lib:format("~ts:~w", [inet:ntoa(Addr), Port]). +format_listen_on({Addr, Port}) when is_tuple(Addr) andalso tuple_size(Addr) == 4 -> + io_lib:format("~ts:~w", [inet:ntoa(Addr), Port]); +format_listen_on({Addr, Port}) when is_tuple(Addr) andalso tuple_size(Addr) == 8 -> + io_lib:format("[~ts]:~w", [inet:ntoa(Addr), Port]). name(Filter) -> iolist_to_binary(["CLI-", Filter]).