aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/test/diameter_gen_sctp_SUITE.erl
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2017-04-10 15:28:43 +0200
committerAnders Svensson <[email protected]>2017-06-11 16:30:37 +0200
commit618acfe5dcb0aa3d8ec0101704cd8fc774ac6c90 (patch)
treed85e23ff6cb82501d25d926198d0fa3490cfbe21 /lib/diameter/test/diameter_gen_sctp_SUITE.erl
parentc02abb8185bc9c33b93d13cd720539e5bf5e2fad (diff)
downloadotp-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/diameter_gen_sctp_SUITE.erl')
-rw-r--r--lib/diameter/test/diameter_gen_sctp_SUITE.erl58
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])),