diff options
-rw-r--r-- | lib/diameter/doc/src/diameter.xml | 5 | ||||
-rw-r--r-- | lib/diameter/doc/src/diameter_tcp.xml | 20 | ||||
-rw-r--r-- | lib/diameter/doc/src/diameter_transport.xml | 30 | ||||
-rw-r--r-- | lib/diameter/examples/code/peer.erl | 28 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_peer.erl | 8 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_peer_fsm.erl | 13 | ||||
-rw-r--r-- | lib/diameter/src/transport/diameter_tcp.erl | 79 | ||||
-rw-r--r-- | lib/diameter/test/diameter_capx_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/diameter/test/diameter_event_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/diameter/test/diameter_examples_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/diameter/test/diameter_tls_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/diameter/test/diameter_transport_SUITE.erl | 34 | ||||
-rw-r--r-- | lib/diameter/test/diameter_util.erl | 29 | ||||
-rw-r--r-- | lib/diameter/test/diameter_watchdog_SUITE.erl | 2 |
14 files changed, 147 insertions, 109 deletions
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml index 7ea93d480b..97071ff323 100644 --- a/lib/diameter/doc/src/diameter.xml +++ b/lib/diameter/doc/src/diameter.xml @@ -343,8 +343,9 @@ Has one of the following types.</p> An address list is available to the start function of a &transport_module;, which can return a new list for use in the subsequent CER or CEA. -Host-IP-Address need not be specified if the transport start function -returns an address list.</p> +Host-IP-Address need not be specified if the transport module in +question communicates an address list as described in +&man_transport;</p> </item> <tag><c>{'Vendor-Id', &dict_Unsigned32;}</c></tag> diff --git a/lib/diameter/doc/src/diameter_tcp.xml b/lib/diameter/doc/src/diameter_tcp.xml index 01c781d553..8e509aa829 100644 --- a/lib/diameter/doc/src/diameter_tcp.xml +++ b/lib/diameter/doc/src/diameter_tcp.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="latin1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd" [ + <!ENTITY start '<seealso marker="#start-3">start/3</seealso>'> <!ENTITY gen_tcp_connect3 '<seealso marker="kernel:gen_tcp#connect-3">gen_tcp:connect/3</seealso>'> <!ENTITY gen_tcp_listen2 @@ -81,7 +82,9 @@ before configuring TLS capability on diameter transports.</p> <func> <name>start({Type, Ref}, Svc, [Opt]) - -> {ok, Pid, [LAddr]} | {error, Reason}</name> + -> {ok, Pid} + | {ok, Pid, [LAddr]} + | {error, Reason}</name> <fsummary>Start a transport process.</fsummary> <type> <v>Type = connect | accept</v> @@ -153,13 +156,14 @@ that will not be forthcoming, which will eventually cause the RFC 3539 watchdog to take down the connection.</p> <p> -If the <c>#diameter_service{}</c> record has more than one -<c>Host-IP-Address</c> and option <c>ip</c> is unspecified then the -first of the these addresses is used as the local address.</p> - -<p> -The returned local address list has length one.</p> - +If an <c>ip</c> option is not specified then the first element of a +non-empty <c>Host-IP-Address</c> list in <c>Svc</c> provides the local +IP address. +If neither is specified then the default address selected by &gen_tcp; +is used. +In all cases, the selected address is either returned from +&start; or passed in a <c>connected</c> message over the transport +interface.</p> </desc> </func> diff --git a/lib/diameter/doc/src/diameter_transport.xml b/lib/diameter/doc/src/diameter_transport.xml index 55b531155f..8bccf6521e 100644 --- a/lib/diameter/doc/src/diameter_transport.xml +++ b/lib/diameter/doc/src/diameter_transport.xml @@ -1,6 +1,8 @@ <?xml version="1.0" encoding="latin1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd" [ <!ENTITY message '<seealso marker="#message">message()</seealso>'> + <!ENTITY MESSAGES '<seealso marker="#MESSAGES">MESSAGES</seealso>'> + <!ENTITY start '<seealso marker="#Mod:start-3">start/3</seealso>'> <!ENTITY ip_address '<seealso marker="kernel:inet#type-ip_address">inet:ip_address()</seealso>'> <!ENTITY % also SYSTEM "seealso.ent" > @@ -12,7 +14,7 @@ <erlref> <header> <copyright> -<year>2011</year><year>2012</year> +<year>2011</year><year>2013</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -125,7 +127,7 @@ Ref is the value that was returned from the call to &mod_add_transport; that has lead to starting of a transport process.</p> <p> -<c>Svc</c> contains the capabilities passed to &mod_start_service; and +<c>Svc</c> contains capabilities passed to &mod_start_service; and &mod_add_transport;, values passed to the latter overriding those passed to the former.</p> @@ -134,13 +136,16 @@ passed to the former.</p> &mod_transport_opt; list passed to &mod_add_transport;.</p> <p> -The start function should use the <c>Host-IP-Address</c> list and/or -<c>Config</c> to select an appropriate list of local IP addresses, -and should return this list if different from the -<c>#diameter_service{}</c> addresses. -The returned list is used to populate <c>Host-IP-Address</c> AVPs in -outgoing capabilities exchange messages, the -<c>#diameter_service{}</c> addresses being used otherwise.</p> +The start function should use the <c>Host-IP-Address</c> list in +<c>Svc</c> and/or <c>Config</c> to select an appropriate list of local +IP addresses, and should return this list if different from the +<c>Svc</c> addresses. +In the connecting case, the local address list can instead be +communicated in a <c>connected</c> message (see &MESSAGES; below) +following connection establishment. +In either case, the local address list is used to populate +<c>Host-IP-Address</c> AVPs in outgoing capabilities exchange +messages.</p> <p> A transport process must implement the message interface documented below. @@ -230,13 +235,16 @@ Not sent if the transport process has <c>Type=connect</c>.</p> </item> <tag><c>{diameter, {self(), connected, Remote}}</c></tag> +<tag><c>{diameter, {self(), connected, Remote, [LocalAddr]}}</c></tag> <item> <p> Inform the parent that the transport process with <c>Type=connect</c> has established a connection with a peer. -Not sent if the transport process has <c>Type=accept</c>. +Not sent if the transport process has <c>Type=accept</c>. <c>Remote</c> is an arbitrary term that uniquely identifies the remote -endpoint to which the transport has connected.</p> +endpoint to which the transport has connected. +A <c>LocalAddr</c> list has the same semantics as one returned from +&start;.</p> </item> <tag><c>{diameter, {recv, &message;}}</c></tag> diff --git a/lib/diameter/examples/code/peer.erl b/lib/diameter/examples/code/peer.erl index 8fdeba57bf..b4ee17e4b7 100644 --- a/lib/diameter/examples/code/peer.erl +++ b/lib/diameter/examples/code/peer.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -51,7 +51,6 @@ | {protocol(), ip_address(), non_neg_integer()} | {protocol(), ip_address(), ip_address(), non_neg_integer()}. --define(DEFAULT_ADDR, {127,0,0,1}). -define(DEFAULT_PORT, 3868). %% --------------------------------------------------------------------------- @@ -111,7 +110,7 @@ server({T, Addr, Port}) -> {port, Port}]}]; server(T) -> - server({T, ?DEFAULT_ADDR, ?DEFAULT_PORT}). + server({T, loopback, ?DEFAULT_PORT}). %% client/1 %% @@ -124,21 +123,28 @@ client({all, LA, RA, RP}) -> client({T, LA, RA, RP}) -> [{transport_module, tmod(T)}, - {transport_config, [{ip, addr(LA)}, - {raddr, addr(RA)}, + {transport_config, [{raddr, addr(RA)}, {rport, RP}, - {reuseaddr, true}]}]; + {reuseaddr, true} + | ip(LA)]}]; -client({T, LA, RP}) -> - client({T, LA, LA, RP}); +client({T, RA, RP}) -> + client({T, default, RA, RP}); client(T) -> - client({T, ?DEFAULT_ADDR, ?DEFAULT_ADDR, ?DEFAULT_PORT}). + client({T, loopback, loopback, ?DEFAULT_PORT}). tmod(tcp) -> diameter_tcp; tmod(sctp) -> diameter_sctp. -addr(default) -> - ?DEFAULT_ADDR; +ip(default) -> + []; +ip(loopback) -> + [{ip, {127,0,0,1}}]; +ip(Addr) -> + [{ip, Addr}]. + +addr(loopback) -> + {127,0,0,1}; addr(A) -> A. diff --git a/lib/diameter/src/base/diameter_peer.erl b/lib/diameter/src/base/diameter_peer.erl index dfc76eb76e..0d2efd4d1f 100644 --- a/lib/diameter/src/base/diameter_peer.erl +++ b/lib/diameter/src/base/diameter_peer.erl @@ -24,7 +24,8 @@ %% Interface towards transport modules ... -export([recv/2, up/1, - up/2]). + up/2, + up/3]). %% ... and the stack. -export([start/1, @@ -180,7 +181,7 @@ start(Mod, Args) -> apply(Mod, start, Args). %%% --------------------------------------------------------------------------- -%%% # up/[12] +%%% # up/1-3 %%% --------------------------------------------------------------------------- up(Pid) -> %% accepting transport @@ -189,6 +190,9 @@ up(Pid) -> %% accepting transport up(Pid, Remote) -> %% connecting transport ifc_send(Pid, {self(), connected, Remote}). +up(Pid, Remote, LAddrs) -> %% connecting transport + ifc_send(Pid, {self(), connected, Remote, LAddrs}). + %%% --------------------------------------------------------------------------- %%% # recv/2 %%% --------------------------------------------------------------------------- diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl index bee3e507fd..6be4259510 100644 --- a/lib/diameter/src/base/diameter_peer_fsm.erl +++ b/lib/diameter/src/base/diameter_peer_fsm.erl @@ -351,10 +351,17 @@ transition({diameter, {TPid, connected, Remote}}, mode = M} = S) -> {'Wait-Conn-Ack', _} = PS, %% assert - connect = M, %% + connect = M, %% keep_transport(TPid), send_CER(S#state{mode = {M, Remote}}); +transition({diameter, {TPid, connected, Remote, LAddrs}}, + #state{transport = TPid, + service = Svc} + = S) -> + transition({diameter, {TPid, connected, Remote}}, + S#state{service = readdr(Svc, LAddrs)}); + %% Connection from peer. transition({diameter, {TPid, connected}}, #state{transport = TPid, @@ -363,7 +370,7 @@ transition({diameter, {TPid, connected}}, parent = Pid} = S) -> {'Wait-Conn-Ack', Tmo} = PS, %% assert - accept = M, %% + accept = M, %% keep_transport(TPid), Pid ! {accepted, self()}, start_timer(Tmo, S#state{state = recv_CER}); @@ -376,6 +383,8 @@ transition({diameter, {_, connected}}, _) -> {stop, connection_timeout}; transition({diameter, {_, connected, _}}, _) -> {stop, connection_timeout}; +transition({diameter, {_, connected, _, _}}, _) -> + {stop, connection_timeout}; %% Connection has timed out: start an alternate. transition({connection_timeout = T, TPid}, diff --git a/lib/diameter/src/transport/diameter_tcp.erl b/lib/diameter/src/transport/diameter_tcp.erl index 132088b514..cbbba714ac 100644 --- a/lib/diameter/src/transport/diameter_tcp.erl +++ b/lib/diameter/src/transport/diameter_tcp.erl @@ -100,6 +100,18 @@ %% # start/3 %% --------------------------------------------------------------------------- +-spec start({accept, Ref}, Svc, [Opt]) + -> {ok, pid(), [inet:ip_address()]} + when Ref :: diameter:transport_ref(), + Svc :: #diameter_service{}, + Opt :: diameter:transport_opt(); + ({connect, Ref}, Svc, [Opt]) + -> {ok, pid(), [inet:ip_address()]} + | {ok, pid()} + when Ref :: diameter:transport_ref(), + Svc :: #diameter_service{}, + Opt :: diameter:transport_opt(). + start({T, Ref}, #diameter_service{capabilities = Caps}, Opts) -> diameter_tcp_sup:start(), %% start tcp supervisors on demand {Mod, Rest} = split(Opts), @@ -172,7 +184,7 @@ i({T, Ref, Mod, Pid, Opts, Addrs}) OwnOpts, ?DEFAULT_FRAGMENT_TIMEOUT), ?IS_TIMEOUT(Tmo) orelse ?ERROR({fragment_timer, Tmo}), - Sock = i(T, Ref, Mod, Pid, SslOpts, Rest, Addrs), + Sock = init(T, Ref, Mod, Pid, SslOpts, Rest, Addrs), MPid ! {stop, self()}, %% tell the monitor to die M = if SslOpts -> ssl; true -> Mod end, setopts(M, Sock), @@ -199,14 +211,21 @@ i(#monitor{parent = Pid, transport = TPid} = S) -> i({listen, LRef, APid, {Mod, Opts, Addrs}}) -> {[LA, LP], Rest} = proplists:split(Opts, [ip, port]), - LAddr = get_addr(LA, Addrs), + LAddrOpt = get_addr(LA, Addrs), LPort = get_port(LP), - {ok, LSock} = Mod:listen(LPort, gen_opts(LAddr, Rest)), + {ok, LSock} = Mod:listen(LPort, gen_opts(LAddrOpt, Rest)), + LAddr = laddr(LAddrOpt, Mod, LSock), true = diameter_reg:add_new({?MODULE, listener, {LRef, {LAddr, LSock}}}), proc_lib:init_ack({ok, self(), {LAddr, LSock}}), erlang:monitor(process, APid), start_timer(#listener{socket = LSock}). +laddr([], Mod, Sock) -> + {ok, {Addr, _Port}} = sockname(Mod, Sock), + Addr; +laddr([{ip, Addr}], _, _) -> + Addr. + own(Opts) -> {Own, Rest} = proplists:split(Opts, [fragment_timer]), {lists:append(Own), Rest}. @@ -225,17 +244,19 @@ ssl_opts([{ssl_options, Opts}]) ssl_opts(L) -> ?ERROR({ssl_options, L}). -%% i/7 +%% init/7 %% Establish a TLS connection before capabilities exchange ... -i(Type, Ref, Mod, Pid, true, Opts, Addrs) -> - i(Type, Ref, ssl, Pid, [{cb_info, ?TCP_CB(Mod)} | Opts], Addrs); +init(Type, Ref, Mod, Pid, true, Opts, Addrs) -> + init(Type, Ref, ssl, Pid, [{cb_info, ?TCP_CB(Mod)} | Opts], Addrs); %% ... or not. -i(Type, Ref, Mod, Pid, _, Opts, Addrs) -> - i(Type, Ref, Mod, Pid, Opts, Addrs). +init(Type, Ref, Mod, Pid, _, Opts, Addrs) -> + init(Type, Ref, Mod, Pid, Opts, Addrs). + +%% init/6 -i(accept = T, Ref, Mod, Pid, Opts, Addrs) -> +init(accept = T, Ref, Mod, Pid, Opts, Addrs) -> {LAddr, LSock} = listener(Ref, {Mod, Opts, Addrs}), proc_lib:init_ack({ok, self(), [LAddr]}), Sock = ok(accept(Mod, LSock)), @@ -243,17 +264,28 @@ i(accept = T, Ref, Mod, Pid, Opts, Addrs) -> diameter_peer:up(Pid), Sock; -i(connect = T, Ref, Mod, Pid, Opts, Addrs) -> +init(connect = T, Ref, Mod, Pid, Opts, Addrs) -> {[LA, RA, RP], Rest} = proplists:split(Opts, [ip, raddr, rport]), - LAddr = get_addr(LA, Addrs), - RAddr = get_addr(RA, []), + LAddrOpt = get_addr(LA, Addrs), + RAddr = get_addr(RA), RPort = get_port(RP), - proc_lib:init_ack({ok, self(), [LAddr]}), - Sock = ok(connect(Mod, RAddr, RPort, gen_opts(LAddr, Rest))), + proc_lib:init_ack(init_rc(LAddrOpt)), + Sock = ok(connect(Mod, RAddr, RPort, gen_opts(LAddrOpt, Rest))), publish(Mod, T, Ref, Sock), - diameter_peer:up(Pid, {RAddr, RPort}), + up(Pid, {RAddr, RPort}, LAddrOpt, Mod, Sock), Sock. +init_rc([{ip, Addr}]) -> + {ok, self(), [Addr]}; +init_rc([]) -> + {ok, self()}. + +up(Pid, Remote, [{ip, _Addr}], _, _) -> + diameter_peer:up(Pid, Remote); +up(Pid, Remote, [], Mod, Sock) -> + {Addr, _Port} = ok(sockname(Mod, Sock)), + diameter_peer:up(Pid, Remote, [Addr]). + publish(Mod, T, Ref, Sock) -> true = diameter_reg:add_new({?MODULE, T, {Ref, Sock}}), putr(?INFO_KEY, {Mod, Sock}). %% for info/1 @@ -281,10 +313,17 @@ l([], LRef, T) -> {ok, _, AS} = diameter_tcp_sup:start_child({listen, LRef, self(), T}), AS. +%% get_addr/1 + +get_addr(As) -> + diameter_lib:ipaddr(addr(As, [])). + %% get_addr/2 +get_addr([], []) -> + []; get_addr(As, Def) -> - diameter_lib:ipaddr(addr(As, Def)). + [{ip, diameter_lib:ipaddr(addr(As, Def))}]. %% Take the first address from the service if several are unspecified. addr([], [Addr | _]) -> @@ -305,14 +344,10 @@ get_port(Ps) -> %% gen_opts/2 -gen_opts(LAddr, Opts) -> +gen_opts(LAddrOpt, Opts) -> {L,_} = proplists:split(Opts, [binary, packet, active]), [[],[],[]] == L orelse ?ERROR({reserved_options, Opts}), - [binary, - {packet, 0}, - {active, once}, - {ip, LAddr} - | Opts]. + [binary, {packet, 0}, {active, once}] ++ LAddrOpt ++ Opts. %% --------------------------------------------------------------------------- %% # ports/1 diff --git a/lib/diameter/test/diameter_capx_SUITE.erl b/lib/diameter/test/diameter_capx_SUITE.erl index 9e6619ecdd..8c9bb67e61 100644 --- a/lib/diameter/test/diameter_capx_SUITE.erl +++ b/lib/diameter/test/diameter_capx_SUITE.erl @@ -444,7 +444,7 @@ connect(Config, T, Opts) -> {CRef, LRef}. connect(LRef, Opts) -> - [PortNr] = ?util:lport(tcp, LRef, 20), + [PortNr] = ?util:lport(tcp, LRef), {ok, CRef} = diameter:add_transport(?CLIENT, {connect, opts(PortNr, Opts)}), CRef. diff --git a/lib/diameter/test/diameter_event_SUITE.erl b/lib/diameter/test/diameter_event_SUITE.erl index 18bdcb1f54..94b4967921 100644 --- a/lib/diameter/test/diameter_event_SUITE.erl +++ b/lib/diameter/test/diameter_event_SUITE.erl @@ -100,7 +100,7 @@ start_server(Config) -> ok = diameter:start_service(?SERVER, ?SERVICE(?SERVER, [?DICT_COMMON])), LRef = ?util:listen(?SERVER, tcp, [{capabilities_cb, fun capx_cb/2}, {capx_timeout, ?SERVER_CAPX_TMO}]), - [PortNr] = ?util:lport(tcp, LRef, 20), + [PortNr] = ?util:lport(tcp, LRef), ?util:write_priv(Config, portnr, PortNr), start = event(?SERVER). diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl index 6d797f6911..585fc9d3b8 100644 --- a/lib/diameter/test/diameter_examples_SUITE.erl +++ b/lib/diameter/test/diameter_examples_SUITE.erl @@ -283,7 +283,7 @@ start(server) -> ok = diameter:start(), ok = server:start(), {ok, Ref} = server:listen(tcp), - [_] = ?util:lport(tcp, Ref, 20), + [_] = ?util:lport(tcp, Ref), ok; start(client) -> diff --git a/lib/diameter/test/diameter_tls_SUITE.erl b/lib/diameter/test/diameter_tls_SUITE.erl index 77194a0f56..5a79c63d36 100644 --- a/lib/diameter/test/diameter_tls_SUITE.erl +++ b/lib/diameter/test/diameter_tls_SUITE.erl @@ -343,7 +343,7 @@ join(Strs) -> server(Host, {Caps, Opts}) -> ok = diameter:start_service(Host, ?SERVICE(Host, ?DICT_COMMON)), {ok, LRef} = diameter:add_transport(Host, ?LISTEN(Caps, Opts)), - {LRef, hd([_] = ?util:lport(tcp, LRef, 20))}. + {LRef, hd([_] = ?util:lport(tcp, LRef))}. sopts(?SERVER1, Dir) -> {inband_security([?TLS]), diff --git a/lib/diameter/test/diameter_transport_SUITE.erl b/lib/diameter/test/diameter_transport_SUITE.erl index 893b7ba2f9..dab0bc4215 100644 --- a/lib/diameter/test/diameter_transport_SUITE.erl +++ b/lib/diameter/test/diameter_transport_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -54,9 +54,6 @@ -define(RECV(Pat, Ret), receive Pat -> Ret end). -define(RECV(Pat), ?RECV(Pat, now())). -%% Or not. --define(WAIT(Ms), receive after Ms -> now() end). - %% Sockets are opened on the loopback address. -define(ADDR, {127,0,0,1}). @@ -209,7 +206,7 @@ init(accept, {Prot, Ref}) -> init(gen_connect, {Prot, Ref}) -> %% Lookup the peer's listening socket. - [PortNr] = ?util:lport(Prot, Ref, 20), + [PortNr] = ?util:lport(Prot, Ref), %% Connect, send a message and receive it back. {ok, Sock} = gen_connect(Prot, PortNr), @@ -230,7 +227,8 @@ init(gen_accept, {Prot, Ref}) -> init(connect, {Prot, Ref}) -> %% Lookup the peer's listening socket. - [{?TEST_LISTENER(_, PortNr), _}] = match(?TEST_LISTENER(Ref, '_')), + [{?TEST_LISTENER(_, PortNr), _}] + = diameter_reg:wait(?TEST_LISTENER(Ref, '_')), %% Start a connecting transport and receive notification of %% the connection. @@ -246,18 +244,6 @@ init(connect, {Prot, Ref}) -> MRef = erlang:monitor(process, TPid), ?RECV({'DOWN', MRef, process, _, _}). -match(Pat) -> - match(Pat, 20). - -match(Pat, T) -> - L = diameter_reg:match(Pat), - if [] /= L orelse 1 == T -> - L; - true -> - ?WAIT(50), - match(Pat, T-1) - end. - bin(sctp, #diameter_packet{bin = Bin}) -> Bin; bin(tcp, Bin) -> @@ -310,22 +296,18 @@ start_connect(tcp, T, Svc, Opts) -> %% start_accept/2 %% %% Start transports sequentially by having each wait for a message -%% from a job in a queue before commencing. Only one transport with -%% a pending accept is started at a time since diameter_sctp currently -%% assumes (and diameter currently implements) this. +%% from a job in a queue before commencing. Only one transport with a +%% pending accept is started at a time since diameter_{tcp,sctp} +%% currently assume (and diameter currently implements) this. start_accept(Prot, Ref) -> Pid = sync(accept, Ref), - - %% Configure the same port number for transports on the same - %% reference. - [PortNr | _] = ?util:lport(Prot, Ref) ++ [0], {Mod, Opts} = tmod(Prot), try {ok, TPid, [?ADDR]} = Mod:start({accept, Ref}, ?SVC([?ADDR]), - [{port, PortNr} | Opts]), + [{port, 0} | Opts]), ?RECV(?TMSG({TPid, connected})), TPid after diff --git a/lib/diameter/test/diameter_util.erl b/lib/diameter/test/diameter_util.erl index a9872f32e1..aa489fef5f 100644 --- a/lib/diameter/test/diameter_util.erl +++ b/lib/diameter/test/diameter_util.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -33,7 +33,6 @@ %% diameter-specific -export([lport/2, - lport/3, listen/2, listen/3, connect/3, connect/4, disconnect/4, @@ -251,27 +250,17 @@ path(Config, Name) -> filename:join([Dir, Name]). %% --------------------------------------------------------------------------- -%% lport/2-3 +%% lport/2 %% %% Lookup the port number of a tcp/sctp listening transport. -lport(M, Ref) -> - lport(M, Ref, 1). +lport(M, {Node, Ref}) -> + rpc:call(Node, ?MODULE, lport, [M, Ref]); -lport(M, {Node, Ref}, Tries) -> - rpc:call(Node, ?MODULE, lport, [M, Ref, Tries]); - -lport(M, Ref, Tries) -> - lp(tmod(M), Ref, Tries). - -lp(M, Ref, T) -> - L = [N || {listen, N, _} <- M:ports(Ref)], - if [] /= L orelse T =< 1 -> - L; - true -> - receive after 50 -> ok end, - lp(M, Ref, T-1) - end. +lport(Prot, Ref) -> + Mod = tmod(Prot), + [_] = diameter_reg:wait({'_', listener, {Ref, '_'}}), + [N || {listen, N, _} <- Mod:ports(Ref)]. %% --------------------------------------------------------------------------- %% listen/2-3 @@ -297,7 +286,7 @@ connect(Client, Prot, LRef) -> connect(Client, Prot, LRef, []). connect(Client, Prot, LRef, Opts) -> - [PortNr] = lport(Prot, LRef, 20), + [PortNr] = lport(Prot, LRef), Client = diameter:service_info(Client, name), %% assert true = diameter:subscribe(Client), Ref = add_transport(Client, {connect, opts(Prot, PortNr) ++ Opts}), diff --git a/lib/diameter/test/diameter_watchdog_SUITE.erl b/lib/diameter/test/diameter_watchdog_SUITE.erl index 704bf110c7..b6e8730ec2 100644 --- a/lib/diameter/test/diameter_watchdog_SUITE.erl +++ b/lib/diameter/test/diameter_watchdog_SUITE.erl @@ -524,7 +524,7 @@ cfg(listen, _) -> cfg(connect, Ref) -> [{{_, _, SvcName}, _Pid}] = diameter_reg:wait({listen, Ref, '_'}), [[{ref, LRef} | _]] = diameter:service_info(SvcName, transport), - [LP] = ?util:lport(tcp, LRef, 20), + [LP] = ?util:lport(tcp, LRef), [{raddr, ?ADDR}, {rport, LP}]. %% =========================================================================== |