From 618acfe5dcb0aa3d8ec0101704cd8fc774ac6c90 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Mon, 10 Apr 2017 15:28:43 +0200 Subject: 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. --- lib/diameter/test/diameter_gen_sctp_SUITE.erl | 58 ++++++++++++++++++--------- 1 file changed, 38 insertions(+), 20 deletions(-) (limited to 'lib/diameter/test/diameter_gen_sctp_SUITE.erl') 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 - <> = 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 + <> = 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])), -- cgit v1.2.3