summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolger Weiss <holger@zedat.fu-berlin.de>2020-05-19 21:42:41 +0200
committerHolger Weiss <holger@zedat.fu-berlin.de>2020-05-19 21:42:41 +0200
commit83fa637569ad5242b940d3798bcb9a8dfbd450e5 (patch)
treeaf36ef6c6808d2a09f054e541c3a8564aa8ef626
parentLet ejabberd_stun listen on IPv6 sockets (diff)
ejabberd_stun: Support IPv6 for TURN
The stun application now supports RFC 6156: TURN Extension for IPv6, and therefore needs separate IPv4 and IPv6 relay addresses.
-rw-r--r--ejabberd.yml.example4
-rw-r--r--mix.exs2
-rw-r--r--rebar.config2
-rw-r--r--src/ejabberd_config_transformer.erl22
-rw-r--r--src/ejabberd_stun.erl15
-rw-r--r--src/mod_stun_disco.erl20
6 files changed, 44 insertions, 21 deletions
diff --git a/ejabberd.yml.example b/ejabberd.yml.example
index ba1a5a77..141b8f47 100644
--- a/ejabberd.yml.example
+++ b/ejabberd.yml.example
@@ -64,7 +64,9 @@ listen:
module: ejabberd_stun
use_turn: true
## The server's public IPv4 address:
- # turn_ip: 203.0.113.3
+ # turn_v4_ip: "203.0.113.3"
+ ## The server's public IPv6 address:
+ # turn_v6_ip: "2001:db8::3"
-
port: 1883
ip: "::"
diff --git a/mix.exs b/mix.exs
index 8cb2c097..c578b24c 100644
--- a/mix.exs
+++ b/mix.exs
@@ -90,7 +90,7 @@ defmodule Ejabberd.Mixfile do
{:stringprep, "~> 1.0"},
{:fast_yaml, "~> 1.0"},
{:fast_tls, "~> 1.1"},
- {:stun, git: "https://github.com/processone/stun", ref: "cb6549387e23737f39f44ba7656a351fd7b88c14", override: true},
+ {:stun, git: "https://github.com/processone/stun", ref: "481f4dbb8b5793659aedf44048d7c5fde968bfbb", override: true},
{:esip, "~> 1.0.32"},
{:p1_mysql, "~> 1.0"},
{:mqtree, "~> 1.0"},
diff --git a/rebar.config b/rebar.config
index 214ccc19..75ea5a7d 100644
--- a/rebar.config
+++ b/rebar.config
@@ -36,7 +36,7 @@
{mqtree, ".*", {git, "https://github.com/processone/mqtree", {tag, "1.0.7"}}},
{p1_acme, ".*", {git, "https://github.com/processone/p1_acme.git", {tag, "1.0.5"}}},
{base64url, ".*", {git, "https://github.com/dvv/base64url.git", {tag, "v1.0"}}},
- {if_var_true, stun, {stun, ".*", {git, "https://github.com/processone/stun", "cb6549387e23737f39f44ba7656a351fd7b88c14"}}},
+ {if_var_true, stun, {stun, ".*", {git, "https://github.com/processone/stun", "481f4dbb8b5793659aedf44048d7c5fde968bfbb"}}},
{if_var_true, sip, {esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.33"}}}},
{if_var_true, mysql, {p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql",
{tag, "1.0.15"}}}},
diff --git a/src/ejabberd_config_transformer.erl b/src/ejabberd_config_transformer.erl
index 26a475f3..2256d48c 100644
--- a/src/ejabberd_config_transformer.erl
+++ b/src/ejabberd_config_transformer.erl
@@ -245,8 +245,9 @@ filter(_, _, _, _) ->
%%%===================================================================
transform_listener(Opts, Acc) ->
Opts1 = transform_request_handlers(Opts),
- Opts2 = remove_inet_options(Opts1),
- collect_listener_certfiles(Opts2, Acc).
+ Opts2 = transform_turn_ip(Opts1),
+ Opts3 = remove_inet_options(Opts2),
+ collect_listener_certfiles(Opts3, Acc).
transform_request_handlers(Opts) ->
case lists:keyfind(module, 1, Opts) of
@@ -258,6 +259,14 @@ transform_request_handlers(Opts) ->
Opts
end.
+transform_turn_ip(Opts) ->
+ case lists:keyfind(module, 1, Opts) of
+ {_, ejabberd_stun} ->
+ replace_turn_ip(Opts);
+ _ ->
+ Opts
+ end.
+
replace_request_handlers(Opts) ->
Handlers = proplists:get_value(request_handlers, Opts, []),
Handlers1 =
@@ -322,6 +331,15 @@ remove_xmlrpc_access_commands(Opts) ->
true
end, Opts).
+replace_turn_ip(Opts) ->
+ lists:filtermap(
+ fun({turn_ip, Val}) ->
+ warn_replaced_option(turn_ip, turn_v4_ip),
+ {true, {turn_v4_ip, Val}};
+ (_) ->
+ true
+ end, Opts).
+
remove_inet_options(Opts) ->
lists:filter(
fun({Opt, _}) when Opt == inet; Opt == inet6 ->
diff --git a/src/ejabberd_stun.erl b/src/ejabberd_stun.erl
index 45969725..68e74d86 100644
--- a/src/ejabberd_stun.erl
+++ b/src/ejabberd_stun.erl
@@ -101,20 +101,20 @@ prepare_turn_opts(Opts, _UseTurn = false) ->
set_certfile(Opts);
prepare_turn_opts(Opts, _UseTurn = true) ->
NumberOfMyHosts = length(ejabberd_option:hosts()),
- TurnIP = case proplists:get_value(turn_ip, Opts) of
+ TurnIP = case proplists:get_value(turn_v4_ip, Opts) of
undefined ->
MyIP = misc:get_my_ip(),
case MyIP of
{127, _, _, _} ->
- ?WARNING_MSG("Option 'turn_ip' is undefined and "
- "the server's hostname doesn't "
+ ?WARNING_MSG("Option 'turn_v4_ip' is undefined "
+ "and the server's hostname doesn't "
"resolve to a public IPv4 address, "
"most likely the TURN relay won't be "
"working properly", []);
_ ->
ok
end,
- [{turn_ip, MyIP}];
+ [{turn_v4_ip, MyIP}];
_ ->
[]
end,
@@ -161,8 +161,10 @@ listen_opt_type(use_turn) ->
econf:bool();
listen_opt_type(ip) ->
econf:ip();
-listen_opt_type(turn_ip) ->
+listen_opt_type(turn_v4_ip) ->
econf:ipv4();
+listen_opt_type(turn_v6_ip) ->
+ econf:ipv6();
listen_opt_type(auth_type) ->
econf:enum([anonymous, user]);
listen_opt_type(auth_realm) ->
@@ -183,7 +185,8 @@ listen_opt_type(certfile) ->
listen_options() ->
[{shaper, none},
{use_turn, false},
- {turn_ip, undefined},
+ {turn_v4_ip, undefined},
+ {turn_v6_ip, undefined},
{auth_type, user},
{auth_realm, undefined},
{tls, false},
diff --git a/src/mod_stun_disco.erl b/src/mod_stun_disco.erl
index 377d2522..32b0cae9 100644
--- a/src/mod_stun_disco.erl
+++ b/src/mod_stun_disco.erl
@@ -602,8 +602,8 @@ parse_listener({{Port, _Addr, Transport}, ?STUN_MODULE, Opts}) ->
case get_listener_ip(Opts) of
{127, _, _, _} = Addr ->
?INFO_MSG("Won't auto-announce STUN/TURN service with loopback "
- "address: ~s:~B (~s), please specify a public 'turn_ip'",
- [misc:ip_to_list(Addr), Port, Transport]),
+ "address: ~s:~B (~s), please specify a public "
+ "'turn_v4_ip'", [misc:ip_to_list(Addr), Port, Transport]),
[];
Addr ->
Host = maybe_resolve(Addr),
@@ -632,16 +632,16 @@ parse_listener({_EndPoint, Module, _Opts}) ->
[].
-spec get_listener_ip(map()) -> inet:ip_address().
-get_listener_ip(#{ip := { 0, 0, 0, 0}} = Opts) -> get_turn_ip(Opts);
-get_listener_ip(#{ip := {127, _, _, _}} = Opts) -> get_turn_ip(Opts);
-get_listener_ip(#{ip := { 10, _, _, _}} = Opts) -> get_turn_ip(Opts);
-get_listener_ip(#{ip := {172, 16, _, _}} = Opts) -> get_turn_ip(Opts);
-get_listener_ip(#{ip := {192, 168, _, _}} = Opts) -> get_turn_ip(Opts);
+get_listener_ip(#{ip := { 0, 0, 0, 0}} = Opts) -> get_turn_v4_ip(Opts);
+get_listener_ip(#{ip := {127, _, _, _}} = Opts) -> get_turn_v4_ip(Opts);
+get_listener_ip(#{ip := { 10, _, _, _}} = Opts) -> get_turn_v4_ip(Opts);
+get_listener_ip(#{ip := {172, 16, _, _}} = Opts) -> get_turn_v4_ip(Opts);
+get_listener_ip(#{ip := {192, 168, _, _}} = Opts) -> get_turn_v4_ip(Opts);
get_listener_ip(#{ip := IP}) -> IP.
--spec get_turn_ip(map()) -> inet:ip_address().
-get_turn_ip(#{turn_ip := {_, _, _, _} = TurnIP}) -> TurnIP;
-get_turn_ip(#{turn_ip := undefined}) -> misc:get_my_ip().
+-spec get_turn_v4_ip(map()) -> inet:ip_address().
+get_turn_v4_ip(#{turn_v4_ip := {_, _, _, _} = TurnIP}) -> TurnIP;
+get_turn_v4_ip(#{turn_v4_ip := undefined}) -> misc:get_my_ip().
-spec is_restricted(map()) -> boolean().
is_restricted(#{auth_type := user}) -> true;