[erlang-questions] : : gen_sctp:connect/5 change

Raimo Niskanen <>
Thu Apr 3 15:04:36 CEST 2008


On Thu, Apr 03, 2008 at 07:10:03AM -0400, Serge Aleynikov wrote:
> Raimo Niskanen wrote:
> > On Wed, Apr 02, 2008 at 09:23:19PM -0400, Serge Aleynikov wrote:
> > But..(speculating, not tested).. for the current gen_sctp:connect/5;
> > if an association comes in on a (passive) listen socket just while 
> > connect/5 is called - it internally calls recv/2 and may receive
> > the unrelated #sctp_assoc_change{} for another IP:Port,
> > and regard this as an internal error (it assumes the
> > first message has to be the one it is waiting for).
> > I do not know how to work around this bug, if it exists.
> > One ugly way would to return all received unrelated events
> > with the {ok,...} or {error,...} value (shrug!).
> 
> I think logically it is not valid to use connect calls from the "server" 
> side (for the reason you mentioned) even though SCTP doesn't prohibit 
> this behavior there's no way to know whether the association change 
> message is for the prior connection setup request or for some incoming 
> "client" connection.  Therefore, it's better to use a separate SCTP 
> socket for listening and a separate one(s) for initiating client 
> connections to other SCTP servers to avoid this race.
> 

Very true but, if it is allowed by SCTP someone will want to do it.
Maybe we can just disallow connect on a listen socket and
call it a known limitation.

> > The code for active mode I have now does
> > receive {sctp,S,IP,Port,,..} if the socket is in active mode
> > so it is a selective receive, which would work better in this
> > scenario of competing incoming/outgoing #sctp_assoc_change{},
> > but this keeps the connect blocking. An option for non-blocking
> > connect is missing, or if the socket is active the connect
> > should be non-blocking and the caller should handle
> > the comm_up message...
> 
> Perhaps this analysis could be done in the driver code and split the 
> result in two messages #sctp_assoc_up{} and #sctp_assoc_change{}?

Sorry, you will have to elaborate. What should be analyzed
and what should be split?

If you mean the driver might check for correct IP andPort,
and that it is a #sctp_assoc_change{} while in state
connecting (that does not exist now), what will it do
with other recv() results?

I had a thought that prim_inet:connect/4 could return
the {active,true|false|once} state, which would make
that getopt atomic with respect to connect, but it
does still not help {active,false} and {active,once}
since if a message has been received it can not be undone.

> 
> > And, if the user sets a too short timeout in connect/5 the
> > #sctp_assoc_change{state=comm_up} may arrive just after
> > the timeout. For passive mode this will not be noticed
> > until recv/2 is called (much) later. For active mode
> > the comm_up message arrives instantly in the inbox.
> > A well written caller would have to be ready for
> > these late messages anyway.
> 
> Valid point.
> 
> > So, there are subtle semantic differences between 
> > connect/5 in passive vs active mode. And making connect/5
> > always non-blocking would remove the differences but
> > force the caller to handle the comm_up event the
> > right way... Which is the least bad alternative...?
> > 
> > Summary:
> > 1) There is probably a problem with the current
> >    passive connect/5 that may be solved by making
> >    it non-blocking but that will be unconvenient.
> >    There might be other ways to solve that problem
> >    and maybe ther is no problem.
> 
> The recommendation above on introducing #sctp_assoc_up{} would address 
> this issue, but would "break" the existing 1-to-1 mapping of SCTP C 
> structs to alike Erlang records.  The later may be a worthwhile sacrifice.
> 

Explain more.

I am a fan of keeping 1-1 mapping, generally.

> > 2) Should connect/5 for active socket be non-blocking
> >    or not, or selectable. If connect/5 for passive
> >    socket is made non-blocking it should be the
> >    same for active socket.
> 
> Agreed.
> 

But, should simply connect/5 for active socket be non-blocking?

And only allow connect/5 on listen socket that is {active,true}?

> Regards,
> 
> Serge
> 
:
:

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list