mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
mod_stun_disco: Try to resolve listener address
In some IPv6-only networks, hostnames that have no AAAA record are resolved to an IPv6 address that's mapped to the host's IPv4 address. This allows the IPv6-only clients to communicate with IPv4-only services such as ejabberd's built-in STUN/TURN server. If STUN/TURN clients try to contact the IPv4 address directly rather than using the mapped IPv6 address, the connection will fail. Therefore, try to resolve the IP address of local ejabberd_stun services to the hostname and announce that hostname rather than the IP address if (and only if) the hostname resolves back to the original IP address, and not to any additional IPv4 or IPv6 address(es). This can (and should) be reverted once IPv6 support is added to ejabberd's built-in STUN/TURN server.
This commit is contained in:
parent
724d09a510
commit
e4de03f3df
@ -53,6 +53,8 @@
|
||||
%% gen_iq_handler callback.
|
||||
-export([process_iq/1]).
|
||||
|
||||
-include_lib("kernel/include/inet.hrl").
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("xmpp.hrl").
|
||||
@ -601,7 +603,8 @@ parse_listener({{Port, _Addr, Transport}, ?STUN_MODULE, Opts}) ->
|
||||
[misc:ip_to_list(Addr), Port, Transport]),
|
||||
[];
|
||||
Addr ->
|
||||
StunService = #service{host = Addr,
|
||||
Host = maybe_resolve(Addr),
|
||||
StunService = #service{host = Host,
|
||||
port = Port,
|
||||
transport = Transport,
|
||||
restricted = false,
|
||||
@ -610,7 +613,7 @@ parse_listener({{Port, _Addr, Transport}, ?STUN_MODULE, Opts}) ->
|
||||
#{use_turn := true} ->
|
||||
?DEBUG("Found STUN/TURN listener: ~s:~B (~s)",
|
||||
[misc:ip_to_list(Addr), Port, Transport]),
|
||||
[StunService, #service{host = Addr,
|
||||
[StunService, #service{host = Host,
|
||||
port = Port,
|
||||
transport = Transport,
|
||||
restricted = is_restricted(Opts),
|
||||
@ -641,6 +644,29 @@ get_turn_ip(#{turn_ip := undefined}) -> misc:get_my_ip().
|
||||
is_restricted(#{auth_type := user}) -> true;
|
||||
is_restricted(#{auth_type := anonymous}) -> false.
|
||||
|
||||
-spec maybe_resolve(inet:ip_address()) -> binary() | inet:ip_address().
|
||||
maybe_resolve(Addr) ->
|
||||
case lookup(Addr, ptr) of
|
||||
[Name] when is_list(Name) ->
|
||||
case {lookup(Name, a), lookup(Name, aaaa)} of
|
||||
{[Addr], []} ->
|
||||
?DEBUG("Resolved address ~s to hostname ~s",
|
||||
[misc:ip_to_list(Addr), Name]),
|
||||
list_to_binary(Name);
|
||||
{_, _} ->
|
||||
?DEBUG("Won't resolve address ~s to hostname ~s",
|
||||
[misc:ip_to_list(Addr), Name]),
|
||||
Addr
|
||||
end;
|
||||
_ ->
|
||||
?DEBUG("Cannot resolve address: ~s", [misc:ip_to_list(Addr)]),
|
||||
Addr
|
||||
end.
|
||||
|
||||
-spec lookup(string() | inet:ip_address(), a | aaaa | ptr) -> [any()].
|
||||
lookup(Name, Type) ->
|
||||
inet_res:lookup(Name, in, Type, [], timer:seconds(3)).
|
||||
|
||||
-spec call(host_or_hash(), term()) -> term().
|
||||
call(Host, Request) ->
|
||||
Proc = get_proc_name(Host),
|
||||
|
Loading…
Reference in New Issue
Block a user