diff options
author | Anders Svensson <[email protected]> | 2017-04-10 15:28:43 +0200 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2017-06-11 16:30:37 +0200 |
commit | 618acfe5dcb0aa3d8ec0101704cd8fc774ac6c90 (patch) | |
tree | d85e23ff6cb82501d25d926198d0fa3490cfbe21 /lib/diameter/test | |
parent | c02abb8185bc9c33b93d13cd720539e5bf5e2fad (diff) | |
download | otp-618acfe5dcb0aa3d8ec0101704cd8fc774ac6c90.tar.gz otp-618acfe5dcb0aa3d8ec0101704cd8fc774ac6c90.tar.bz2 otp-618acfe5dcb0aa3d8ec0101704cd8fc774ac6c90.zip |
Deal with SCTP association id quirk on Solaris
In particular, that the association id received in messages on a
one-to-one socket after peeloff may be different from the id received on
the listen socket at comm_up.
This seems odd, since it's then not possible to send until the id is
discovered by reception of an SCTP message containing it, but it's
unclear if this is a bug or a feature, or if it's specific to certain
platforms. Treat it as a feature in this commit, and get the association
id as mentioned, an incoming CER being expected before anything is sent.
Commit da3e5d67 has more history.
Diffstat (limited to 'lib/diameter/test')
-rw-r--r-- | lib/diameter/test/diameter_gen_sctp_SUITE.erl | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/lib/diameter/test/diameter_gen_sctp_SUITE.erl b/lib/diameter/test/diameter_gen_sctp_SUITE.erl index 457d9a0a85..d76d2bdbd3 100644 --- a/lib/diameter/test/diameter_gen_sctp_SUITE.erl +++ b/lib/diameter/test/diameter_gen_sctp_SUITE.erl @@ -228,33 +228,49 @@ accept_loop(Sock, MRef) -> %% Server process that answers incoming messages as long as the parent %% lives. -assoc(MRef, Id, OS) +assoc(MRef, _Id, OS) when is_reference(MRef) -> {peeloff, Sock} = receive T -> T end, - recv_loop(Sock, Id, sender(Sock, Id, OS), MRef). + recv_loop(Sock, false, sender(Sock, false, OS), MRef). %% recv_loop/4 recv_loop(Sock, Id, Pid, MRef) -> ok = inet:setopts(Sock, [{active, once}]), - receive - ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = I}], B}) - when is_binary(B) -> - T2 = diameter_lib:now(), - I = Id, %% assert - <<?MAGIC, Bin/binary>> = B, %% assert - {[_,_,_,Sz] = L, Bytes} = unmark(Bin), - Sz = size(Bin) - Bytes, %% assert - <<_:Bytes/binary, Body:Sz/binary>> = Bin, - send(Pid, [T2|L], Body), %% answer - recv_loop(Sock, Id, Pid, MRef); - ?SCTP(Sock, _) -> - recv_loop(Sock, Id, Pid, MRef); - {'DOWN', MRef, process, _, Reason} -> - Reason; - T -> - error(T) - end. + recv(Sock, Id, Pid, MRef, receive T -> T end). + +%% recv/5 + +%% Association id can change on a peeloff socket on some versions of +%% Solaris. +recv(Sock, + false, + Pid, + MRef, + ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], _}) + = T) -> + Pid ! {assoc_id, Id}, + recv(Sock, Id, Pid, MRef, T); + +recv(Sock, Id, Pid, MRef, ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = I}], B})) + when is_binary(B) -> + T2 = diameter_lib:now(), + Id = I, %% assert + <<?MAGIC, Bin/binary>> = B, %% assert + {[_,_,_,Sz] = L, Bytes} = unmark(Bin), + Sz = size(Bin) - Bytes, %% assert + <<_:Bytes/binary, Body:Sz/binary>> = Bin, + send(Pid, [T2|L], Body), %% answer + recv_loop(Sock, Id, Pid, MRef); + +recv(Sock, Id, Pid, MRef, ?SCTP(Sock, _)) -> + recv_loop(Sock, Id, Pid, MRef); + +recv(_, _, _, MRef, {'DOWN', MRef, process, _, Reason}) -> + Reason; + +recv(_, _, _, _, T) -> + error(T). %% send/3 @@ -273,6 +289,8 @@ sender(Sock, Id, OS) -> send_loop(Sock, Id, OS, N, MRef) -> receive + {assoc_id, I} -> + send_loop(Sock, I, OS, N, MRef); {send, L, Body} -> Stream = N rem OS, ok = send(Sock, Id, Stream, mark(Body, [N, Stream | L])), |