aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/transport
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/src/transport
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/src/transport')
-rw-r--r--lib/diameter/src/transport/diameter_sctp.erl22
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/diameter/src/transport/diameter_sctp.erl b/lib/diameter/src/transport/diameter_sctp.erl
index f9feb68874..2059a0e029 100644
--- a/lib/diameter/src/transport/diameter_sctp.erl
+++ b/lib/diameter/src/transport/diameter_sctp.erl
@@ -88,7 +88,9 @@
%% {RAs, RP, Errors}
| connect,
socket :: gen_sctp:sctp_socket() | undefined,
- assoc_id :: gen_sctp:assoc_id(), %% association identifier
+ assoc_id :: gen_sctp:assoc_id() %% association identifier
+ | undefined
+ | true,
peer :: {[inet:ip_address()], uint()} %% {RAs, RP}
| undefined,
streams :: {uint(), uint()} %% {InStream, OutStream} counts
@@ -676,7 +678,9 @@ recv({_, #sctp_assoc_change{state = comm_up,
= S) ->
Ref = getr(?REF_KEY),
publish(T, Ref, Id, Sock),
- up(S#transport{assoc_id = Id,
+ %% Deal with different association id after peeloff on Solaris by
+ %% taking the id from the first reception.
+ up(S#transport{assoc_id = T == accept orelse Id,
streams = {IS, OS}});
%% ... or not: try the next address.
@@ -691,16 +695,24 @@ recv({_, #sctp_assoc_change{} = E},
recv({_, #sctp_assoc_change{}}, _) ->
stop;
+%% First inbound on an accepting transport.
+recv({[#sctp_sndrcvinfo{assoc_id = Id}], _Bin}
+ = T,
+ #transport{assoc_id = true}
+ = S) ->
+ recv(T, S#transport{assoc_id = Id});
+
%% Inbound Diameter message.
-recv({[#sctp_sndrcvinfo{stream = Id}], Bin}, #transport{parent = Pid})
+recv({[#sctp_sndrcvinfo{stream = Id}], Bin}, #transport{parent = Pid} = S)
when is_binary(Bin) ->
diameter_peer:recv(Pid, #diameter_packet{transport_data = {stream, Id},
bin = Bin}),
- ok;
+ S;
recv({_, #sctp_shutdown_event{assoc_id = A}},
#transport{assoc_id = Id})
- when A == Id;
+ when Id;
+ A == Id;
A == 0 ->
stop;