mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-20 17:27:00 +01:00
* src/ejabberd_config.erl: Option outgoing_s2s_options to define
s2s outgoing behaviour: IPv4, IPv6 and timeout (thanks to Stephan Maka)(EJAB-665) * src/ejabberd_s2s_out.erl: Likewise * src/ejabberd_socket.erl: Likewise * src/ejabberd.cfg.example: Likewise * doc/guide.tex: Likewise * doc/guide.html: Likewise SVN Revision: 1756
This commit is contained in:
parent
11825e7a33
commit
682909e0fc
13
ChangeLog
13
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
2008-12-26 Badlop <badlop@process-one.net>
|
||||||
|
|
||||||
|
* src/ejabberd_config.erl: Option outgoing_s2s_options to define
|
||||||
|
s2s outgoing behaviour: IPv4, IPv6 and timeout (thanks to Stephan
|
||||||
|
Maka)(EJAB-665)
|
||||||
|
* src/ejabberd_s2s_out.erl: Likewise
|
||||||
|
* src/ejabberd_socket.erl: Likewise
|
||||||
|
* src/ejabberd.cfg.example: Likewise
|
||||||
|
* doc/guide.tex: Likewise
|
||||||
|
* doc/guide.html: Likewise
|
||||||
|
|
||||||
2008-12-26 Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
2008-12-26 Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
|
||||||
* src/odbc/ejabberd_odbc.erl: get rid of SERIALIZABLE isolation
|
* src/odbc/ejabberd_odbc.erl: get rid of SERIALIZABLE isolation
|
||||||
@ -10,7 +21,7 @@
|
|||||||
2008-12-24 Badlop <badlop@process-one.net>
|
2008-12-24 Badlop <badlop@process-one.net>
|
||||||
|
|
||||||
* src/aclocal.m4: Fixes in configure script: fix
|
* src/aclocal.m4: Fixes in configure script: fix
|
||||||
disable-disable_zlib and disable-pam; in case of problems, PAM
|
disable-ejabberd_zlib and disable-pam; in case of problems, PAM
|
||||||
verification aborts with error instead of warning. (EJAB-787)
|
verification aborts with error instead of warning. (EJAB-787)
|
||||||
* src/configure.ac: Likewise
|
* src/configure.ac: Likewise
|
||||||
* src/configure: Likewise
|
* src/configure: Likewise
|
||||||
|
@ -745,6 +745,10 @@ use STARTTLS for s2s connections.
|
|||||||
file containing a SSL certificate.
|
file containing a SSL certificate.
|
||||||
</DD><DT CLASS="dt-description"><B><TT>{domain_certfile, Domain, Path}</TT></B></DT><DD CLASS="dd-description">
|
</DD><DT CLASS="dt-description"><B><TT>{domain_certfile, Domain, Path}</TT></B></DT><DD CLASS="dd-description">
|
||||||
Full path to the file containing the SSL certificate for a specific domain.
|
Full path to the file containing the SSL certificate for a specific domain.
|
||||||
|
</DD><DT CLASS="dt-description"><B><TT>{outgoing_s2s_options, Methods, Timeout}</TT></B></DT><DD CLASS="dd-description">
|
||||||
|
Specify which address families to try, in what order, and connect timeout in milliseconds.
|
||||||
|
By default it first tries connecting with IPv4, if that fails it tries using IPv6,
|
||||||
|
with a timeout of 10000 milliseconds.
|
||||||
</DD><DT CLASS="dt-description"><B><TT>{s2s_default_policy, allow|deny}</TT></B></DT><DD CLASS="dd-description">
|
</DD><DT CLASS="dt-description"><B><TT>{s2s_default_policy, allow|deny}</TT></B></DT><DD CLASS="dd-description">
|
||||||
The default policy for incoming and outgoing s2s connections to other Jabber servers.
|
The default policy for incoming and outgoing s2s connections to other Jabber servers.
|
||||||
The default value is <TT>allow</TT>.
|
The default value is <TT>allow</TT>.
|
||||||
@ -1032,6 +1036,10 @@ declarations of ACLs in the configuration file have the following syntax:
|
|||||||
</PRE></DD><DT CLASS="dt-description"><B><TT>{resource, <resource>}</TT></B></DT><DD CLASS="dd-description"> Matches any JID with a resource
|
</PRE></DD><DT CLASS="dt-description"><B><TT>{resource, <resource>}</TT></B></DT><DD CLASS="dd-description"> Matches any JID with a resource
|
||||||
<TT><resource></TT>. Example:
|
<TT><resource></TT>. Example:
|
||||||
<PRE CLASS="verbatim">{acl, mucklres, {resource, "muckl"}}.
|
<PRE CLASS="verbatim">{acl, mucklres, {resource, "muckl"}}.
|
||||||
|
</PRE></DD><DT CLASS="dt-description"><B><TT>{shared_group, <groupname>}</TT></B></DT><DD CLASS="dd-description"> Matches any member of a Shared Roster Group with name <TT><groupname></TT> in the virtual host. Example:
|
||||||
|
<PRE CLASS="verbatim">{acl, techgroupmembers, {shared_group, "techteam"}}.
|
||||||
|
</PRE></DD><DT CLASS="dt-description"><B><TT>{shared_group, <groupname>, <server>}</TT></B></DT><DD CLASS="dd-description"> Matches any member of a Shared Roster Group with name <TT><groupname></TT> in the virtual host <TT><server></TT>. Example:
|
||||||
|
<PRE CLASS="verbatim">{acl, techgroupmembers, {shared_group, "techteam", "example.org"}}.
|
||||||
</PRE></DD><DT CLASS="dt-description"><B><TT>{user_regexp, <regexp>}</TT></B></DT><DD CLASS="dd-description"> Matches any local user with a name that
|
</PRE></DD><DT CLASS="dt-description"><B><TT>{user_regexp, <regexp>}</TT></B></DT><DD CLASS="dd-description"> Matches any local user with a name that
|
||||||
matches <TT><regexp></TT> on local virtual hosts. Example:
|
matches <TT><regexp></TT> on local virtual hosts. Example:
|
||||||
<PRE CLASS="verbatim">{acl, tests, {user_regexp, "^test[0-9]*$"}}.
|
<PRE CLASS="verbatim">{acl, tests, {user_regexp, "^test[0-9]*$"}}.
|
||||||
|
@ -870,6 +870,10 @@ There are some additional global options:
|
|||||||
file containing a SSL certificate.
|
file containing a SSL certificate.
|
||||||
\titem{\{domain\_certfile, Domain, Path\}} \ind{options!domain\_certfile}
|
\titem{\{domain\_certfile, Domain, Path\}} \ind{options!domain\_certfile}
|
||||||
Full path to the file containing the SSL certificate for a specific domain.
|
Full path to the file containing the SSL certificate for a specific domain.
|
||||||
|
\titem{\{outgoing\_s2s\_options, Methods, Timeout\}} \ind{options!outgoing\_s2s\_options}
|
||||||
|
Specify which address families to try, in what order, and connect timeout in milliseconds.
|
||||||
|
By default it first tries connecting with IPv4, if that fails it tries using IPv6,
|
||||||
|
with a timeout of 10000 milliseconds.
|
||||||
\titem{\{s2s\_default\_policy, allow|deny\}}
|
\titem{\{s2s\_default\_policy, allow|deny\}}
|
||||||
The default policy for incoming and outgoing s2s connections to other Jabber servers.
|
The default policy for incoming and outgoing s2s connections to other Jabber servers.
|
||||||
The default value is \term{allow}.
|
The default value is \term{allow}.
|
||||||
|
@ -186,6 +186,13 @@
|
|||||||
%%{{s2s_host, "goodhost.org"}, allow}.
|
%%{{s2s_host, "goodhost.org"}, allow}.
|
||||||
%%{{s2s_host, "badhost.org"}, deny}.
|
%%{{s2s_host, "badhost.org"}, deny}.
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Outgoing S2S options
|
||||||
|
%%
|
||||||
|
%% Preferred address families (which to try first) and connect timeout
|
||||||
|
%% in milliseconds.
|
||||||
|
%%
|
||||||
|
%%{outgoing_s2s_options, [ipv4, ipv6], 10000}.
|
||||||
|
|
||||||
%%% ==============
|
%%% ==============
|
||||||
%%% AUTHENTICATION
|
%%% AUTHENTICATION
|
||||||
|
@ -330,6 +330,8 @@ process_term(Term, State) ->
|
|||||||
add_option(language, Val, State);
|
add_option(language, Val, State);
|
||||||
{outgoing_s2s_port, Port} ->
|
{outgoing_s2s_port, Port} ->
|
||||||
add_option(outgoing_s2s_port, Port, State);
|
add_option(outgoing_s2s_port, Port, State);
|
||||||
|
{outgoing_s2s_options, Methods, Timeout} ->
|
||||||
|
add_option(outgoing_s2s_options, {Methods, Timeout}, State);
|
||||||
{s2s_use_starttls, Port} ->
|
{s2s_use_starttls, Port} ->
|
||||||
add_option(s2s_use_starttls, Port, State);
|
add_option(s2s_use_starttls, Port, State);
|
||||||
{s2s_certfile, CertFile} ->
|
{s2s_certfile, CertFile} ->
|
||||||
|
@ -119,6 +119,8 @@
|
|||||||
-define(INVALID_XML_ERR,
|
-define(INVALID_XML_ERR,
|
||||||
xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
|
xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
|
||||||
|
|
||||||
|
-define(SOCKET_DEFAULT_RESULT, {error, badarg}).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
@ -206,7 +208,7 @@ open_socket(init, StateData) ->
|
|||||||
_ ->
|
_ ->
|
||||||
open_socket1(Addr, Port)
|
open_socket1(Addr, Port)
|
||||||
end
|
end
|
||||||
end, {error, badarg}, AddrList) of
|
end, ?SOCKET_DEFAULT_RESULT, AddrList) of
|
||||||
{ok, Socket} ->
|
{ok, Socket} ->
|
||||||
Version = if
|
Version = if
|
||||||
StateData#state.use_v10 ->
|
StateData#state.use_v10 ->
|
||||||
@ -239,34 +241,40 @@ open_socket(_, StateData) ->
|
|||||||
{next_state, open_socket, StateData}.
|
{next_state, open_socket, StateData}.
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
open_socket1(Addr, Port) ->
|
%% IPv4
|
||||||
?DEBUG("s2s_out: connecting to ~s:~p~n", [Addr, Port]),
|
open_socket1({_,_,_,_} = Addr, Port) ->
|
||||||
Res = case catch ejabberd_socket:connect(
|
open_socket2(inet, Addr, Port);
|
||||||
Addr, Port,
|
|
||||||
|
%% IPv6
|
||||||
|
open_socket1({_,_,_,_,_,_,_,_} = Addr, Port) ->
|
||||||
|
open_socket2(inet6, Addr, Port);
|
||||||
|
|
||||||
|
%% Hostname
|
||||||
|
open_socket1(Host, Port) ->
|
||||||
|
lists:foldl(fun(_Family, {ok, _Socket} = R) ->
|
||||||
|
R;
|
||||||
|
(Family, _) ->
|
||||||
|
Addrs = get_addrs(Host, Family),
|
||||||
|
lists:foldl(fun(_Addr, {ok, _Socket} = R) ->
|
||||||
|
R;
|
||||||
|
(Addr, _) ->
|
||||||
|
open_socket1(Addr, Port)
|
||||||
|
end, ?SOCKET_DEFAULT_RESULT, Addrs)
|
||||||
|
end, ?SOCKET_DEFAULT_RESULT, outgoing_s2s_families()).
|
||||||
|
|
||||||
|
open_socket2(Type, Addr, Port) ->
|
||||||
|
?DEBUG("s2s_out: connecting to ~p:~p~n", [Addr, Port]),
|
||||||
|
Timeout = outgoing_s2s_timeout(),
|
||||||
|
case (catch ejabberd_socket:connect(Addr, Port,
|
||||||
[binary, {packet, 0},
|
[binary, {packet, 0},
|
||||||
{active, false}]) of
|
{active, false}, Type],
|
||||||
|
Timeout)) of
|
||||||
{ok, _Socket} = R -> R;
|
{ok, _Socket} = R -> R;
|
||||||
{error, Reason1} ->
|
{error, Reason} = R ->
|
||||||
?DEBUG("s2s_out: connect return ~p~n", [Reason1]),
|
?DEBUG("s2s_out: connect return ~p~n", [Reason]),
|
||||||
catch ejabberd_socket:connect(
|
R;
|
||||||
Addr, Port,
|
|
||||||
[binary, {packet, 0},
|
|
||||||
{active, false}, inet6]);
|
|
||||||
{'EXIT', Reason1} ->
|
|
||||||
?DEBUG("s2s_out: connect crashed ~p~n", [Reason1]),
|
|
||||||
catch ejabberd_socket:connect(
|
|
||||||
Addr, Port,
|
|
||||||
[binary, {packet, 0},
|
|
||||||
{active, false}, inet6])
|
|
||||||
end,
|
|
||||||
case Res of
|
|
||||||
{ok, Socket} ->
|
|
||||||
{ok, Socket};
|
|
||||||
{error, Reason} ->
|
|
||||||
?DEBUG("s2s_out: inet6 connect return ~p~n", [Reason]),
|
|
||||||
{error, Reason};
|
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?DEBUG("s2s_out: inet6 connect crashed ~p~n", [Reason]),
|
?DEBUG("s2s_out: connect crashed ~p~n", [Reason]),
|
||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -1000,6 +1008,23 @@ test_get_addr_port(Server) ->
|
|||||||
end
|
end
|
||||||
end, [], lists:seq(1, 100000)).
|
end, [], lists:seq(1, 100000)).
|
||||||
|
|
||||||
|
get_addrs(Host, Family) ->
|
||||||
|
Type = case Family of
|
||||||
|
inet4 -> a;
|
||||||
|
ipv4 -> a;
|
||||||
|
inet6 -> aaaa;
|
||||||
|
ipv6 -> aaaa
|
||||||
|
end,
|
||||||
|
case inet_res:getbyname(Host, Type) of
|
||||||
|
{ok, #hostent{h_addr_list = Addrs}} ->
|
||||||
|
?DEBUG("~s of ~s resolved to: ~p~n", [Type, Host, Addrs]),
|
||||||
|
Addrs;
|
||||||
|
{error, Reason} ->
|
||||||
|
?DEBUG("~s lookup of '~s' failed: ~p~n", [Type, Host, Reason]),
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
outgoing_s2s_port() ->
|
outgoing_s2s_port() ->
|
||||||
case ejabberd_config:get_local_option(outgoing_s2s_port) of
|
case ejabberd_config:get_local_option(outgoing_s2s_port) of
|
||||||
Port when is_integer(Port) ->
|
Port when is_integer(Port) ->
|
||||||
@ -1008,6 +1033,36 @@ outgoing_s2s_port() ->
|
|||||||
5269
|
5269
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
outgoing_s2s_families() ->
|
||||||
|
case ejabberd_config:get_local_option(outgoing_s2s_options) of
|
||||||
|
{Families, _} when is_list(Families) ->
|
||||||
|
Families;
|
||||||
|
undefined ->
|
||||||
|
%% DISCUSSION: Why prefer IPv4 first?
|
||||||
|
%%
|
||||||
|
%% IPv4 connectivity will be available for everyone for
|
||||||
|
%% many years to come. So, there's absolutely no benefit
|
||||||
|
%% in preferring IPv6 connections which are flaky at best
|
||||||
|
%% nowadays.
|
||||||
|
%%
|
||||||
|
%% On the other hand content providers hesitate putting up
|
||||||
|
%% AAAA records for their sites due to the mentioned
|
||||||
|
%% quality of current IPv6 connectivity. Making IPv6 the a
|
||||||
|
%% `fallback' may avoid these problems elegantly.
|
||||||
|
[ipv4, ipv6]
|
||||||
|
end.
|
||||||
|
|
||||||
|
outgoing_s2s_timeout() ->
|
||||||
|
case ejabberd_config:get_local_option(outgoing_s2s_options) of
|
||||||
|
{_, Timeout} when is_integer(Timeout) ->
|
||||||
|
Timeout;
|
||||||
|
{_, infinity} ->
|
||||||
|
infinity;
|
||||||
|
undefined ->
|
||||||
|
%% 10 seconds
|
||||||
|
10000
|
||||||
|
end.
|
||||||
|
|
||||||
%% Human readable S2S logging: Log only new outgoing connections as INFO
|
%% Human readable S2S logging: Log only new outgoing connections as INFO
|
||||||
%% Do not log dialback
|
%% Do not log dialback
|
||||||
log_s2s_out(false, _, _) -> ok;
|
log_s2s_out(false, _, _) -> ok;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
%% API
|
%% API
|
||||||
-export([start/4,
|
-export([start/4,
|
||||||
connect/3,
|
connect/3,
|
||||||
|
connect/4,
|
||||||
starttls/2,
|
starttls/2,
|
||||||
starttls/3,
|
starttls/3,
|
||||||
compress/1,
|
compress/1,
|
||||||
@ -94,7 +95,10 @@ start(Module, SockMod, Socket, Opts) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
connect(Addr, Port, Opts) ->
|
connect(Addr, Port, Opts) ->
|
||||||
case gen_tcp:connect(Addr, Port, Opts) of
|
connect(Addr, Port, Opts, infinity).
|
||||||
|
|
||||||
|
connect(Addr, Port, Opts, Timeout) ->
|
||||||
|
case gen_tcp:connect(Addr, Port, Opts, Timeout) of
|
||||||
{ok, Socket} ->
|
{ok, Socket} ->
|
||||||
Receiver = ejabberd_receiver:start(Socket, gen_tcp, none),
|
Receiver = ejabberd_receiver:start(Socket, gen_tcp, none),
|
||||||
SocketData = #socket_state{sockmod = gen_tcp,
|
SocketData = #socket_state{sockmod = gen_tcp,
|
||||||
|
Loading…
Reference in New Issue
Block a user