Subject: RE: Matching addresses in INIT and INIT ACK

From: <[email-masked]>
Date: Thu, 6 Mar 2003 15:22:42 +0200

Brian,

> Ivan.Arias-Rodriguez,
> 
> On Tue, 04 Mar 2003, [email-masked] wrote:
> 
> > 	Hi!
> > 
> > 	So this is the example of INIT collision. It is the 
> typical one, when
> > 	both peers start about at the same time. This is the 
> notation used:
> > 
> > 	- For all the chunks:
> > 		o In capital letters the NAME OF CHUNK.
> > 		o VT is the Verification Tag included in the 
> SCTP header.
> > 		o Source Address:Port->Destination Address:Port.
> > 
> > 	- For INIT and INIT ACK:
> > 		o IT is the Initiation Tag included in the 
> header of the chunk.
> > 
> > 	- For INIT ACK and COOKIE ECHO:
> > 		o VTloc and VTpeer are the values of the local 
> Verification
> > 		Tag (the one the INIT ACK sender expects in the 
> SCTP headers
> > 		of the peer) and the peer's Verification Tag 
> (the one the INIT
> > 		ACK senders includes in its SCTP headers) as 
> included in the
> > 		State Cookie. Note that those values are 
> directly copied from
> > 		the INIT ACK and included in the COOKIE ECHO.
> 
> > 		o TTloc and TTpeer are the values of the local 
> Tie Tag (the
> > 		value of VTloc at the moment of sending the 
> INIT ACK) and the
> > 		peer's Tie Tag (the value of VTpeer at the 
> moment of sending
> > 		the INIT ACK) as included in the State Cookie. 
> Note that those
> > 		values are directly copied from the INIT ACK 
> and included in
> > 		the COOKIE ECHO.
> > 
> > 	The TCBs are only shown when there is a change. They show:
> > 	- Source address/es:Source Port.
> > 	- Destination address/es: Destination Port.
> > 	- Local Verification Tag.
> > 	- Peers Verification Tag.
> > 	- State.
> > 
> > 	Let's see the scenario.
> > 
> > 
> > Host A                                                      
>         Host B/C
> >                                                                     
> > TCB     \   INIT VT:0 IT:W                      INIT VT:0 
> IT:X   /  TCB
> > A:1000   \  A:1000->B:1000                      
> ?:1000->A:1000  /   B,C:1000
> > B:1000    \                                                 
>    /    A:1000
> > VTloc:W    \                                                
>   /     VTloc:X
> > VTpeer:0    \                                               
>  /      VTpeer:0
> > C-WAIT       \                                              
> /       C-WAIT
> >               \--------------------\  /--------------------/
> >                                     \/
> >                                     /\
> >                                    /  \
> >    (1)  <-------------------------/    \------------------------->
> > 
> >         \   INIT ACK VT:X IT:Y              INIT ACK VT:W IT:X   /
> >          \  A:1000->C:1000                      B:1000->A:1000  /
> >           \ VTloc:Y VTpeer:X                  VTloc:X VTpeer:W /
> >            \TTloc:0 TTpeer:0                  TTloc:X TTpeer:0/
> >             \                                                /
> >              \                                              /
> >               \--------------------\  /--------------------/
> >                                     \/
> >                                     /\
> >                                    /  \
> >         <-------------------------/    \------------------------->
> > 
> > TCB     \   COOKIE ECHO VT:X                  COOKIE ECHO 
> VT:Y   /  TCB
> > A:1000   \  A:1000->B:1000                      
> C:1000->A:1000  /   B,C:1000
> > B,C:1000  \ VTloc:X VTpeer:W                  VTloc:Y 
> VTpeer:W /    A:1000
> > VTloc:W    \TTloc:X TTpeer:0                  TTloc:0 
> TTpeer:0/     VTloc:X
> > VTpeer:X    \                                               
>  /      VTpeer:Y
> > C-ECHOED     \                                              
> /       C-ECHOED
> >               \--------------------\  /--------------------/
> >                                     \/
> >                                     /\
> >                                    /  \
> >    (2) X<-------------------------/    
> \------------------------->  (3)
> > 
> >                                                COOKIE ACK 
> VT:W   /  TCB
> >                                                             
>     /   B,C:1000
> >                                                             
>    /    A:1000
> >                                                             
>   /     VTloc:X
> >                                                             
>  /      VTpeer:W
> >                                                             
> /       ESTABLISH
> >                                       /--------------------/
> >                                      /                     
> >                                     / 
> >                                    /   
> >    (4) X<-------------------------/                               
> > 
> > 
> > 
> > 	Some remarks:
> > 
> > 	(1) At this point, Host A doesn't recognize the INIT as 
> coming from
> > 	the same association it is trying to establish. The VT 
> is completely
> > 	different. Thus, it goes in the normal (and wrong) establishment
> > 	procedure, creates a new IT and set the Tie Tags to 0.
> > 
> > 	(2) The received COOKIE ECHO is discarded, since the VT 
> is wrong (Host
> > 	A is expecting VT set to W).
> > 
> > 	(3) Host B,C recognizes the collision due to the Tie 
> Tags, recognize
> > 	it as situation B of section 5.2.4 and updates the VTpeer to W.
> > 
> > 	(4) The COOKIE ACK is discarded, since Host A is in the 
> C-ECHOED state.
> > 
> > 
> > 	And now?
> > 
> > 	Host A will retransmit the COOKIE ECHO, Host B,C will 
> answer again,
> > 	and the COOKIE ACK is discarded again.
> > 
> > 	Conclusion: Host A cannot establish an association with 
> Host B,C in
> > 	this situation.
> > 
> > 	Brian, did I make any mistake? I hope I didn't... :-/
> 
> In both our STREAMS and Sockets implementations you cannot bind to a
> static port when another STREAM/Socket is bound to that port as a
> listener.  That's just how STREAMS/Socket semantics work.

	I don't understand this... Do you mean that the address/port that sent the INIT is not listening? I think that since the very moment it sent the INIT it should be listening for the INIT ACK... But, what a pity, it receives an INIT instead of the expected INIT ACK...

	I'm sorry, I'm missing something... :-/

> If Host A is our implementation, the INIT from Host B/C for A:1000
> will be refused because there is no STREAM/Socket listening on that
> port and only one association will form.

	Then the situation is even more obvious... If Host B/C also uses the same implementation, no INIT will ever be read -> no association formed...

	What am I missing?

> If Host B/C is our implemenataion, the INIT from Host A for B/C:1000
> will be refused because there is no listening socket.

	I don't understand... Well, Yes... I imagine that the point is that nobody will send an INIT to a non-static port... ok...

	But this is a limitation... Otherwise, why caring at all about collisions?

	So far in all the interoperability test sessions I have been, I have tested successfully the collision scenario, i.e., other implementations where also able to send an INIT from a static port... :-/

> This is no different in TCP/Sockets.  TCP sockets do not allow you
> to bind to a static port and address if there is a socket listening
> on that port.  You cannot even make two TCP sockets implementations
> do what you describe here.

	I don't know about TCP implementations. I just know that my implementation (and most of all of the other ones) are able to do it... We were both able to tell the other, ok, to which port are you going to send the INIT? ... alright, I will be listening there... And then we managed to test the INIT collision scenario...

> Because our implementation follows standard XTI/XNS and Sockets
> semantics at most one association will form and there will be none of
> the problems you describe.

	Again, you are talking about your specific implementation...

	If you start putting special conditions, such as this one, that you know in advance the peer's addresses... then there will be a moment in which you don't even need to check the VT...

> You seem to focus on collisions (which are not possible using Sockets)
> and Caitlin focusses on two ULPs launching from the same 
> static address
> (which is heavily discouraged in Sockets with SO_REUSEADDR and is not
> possible unless the flag is set on ALL sockets using the address and
> NO listening sockets).

	There are several different scenarios... INIT collision, the one Caitlin says, restart with more addresses... Ok, they won't happen everyday, but they are there...

> You both dig down into the little unused corner case of static port
> assignment to justify a SHOULD on "how to search"?

	I think you have just said that we are right...

	Do we want the test to be changed to say  "you SHOULD do that unless:

	a) You know all the addresses of all the peers that might connect to you.

	b) You never send an INIT to a non-static port and you expect your peers to do the same.

	c) Any Brian's implementation special features...

	? :-0...

	BR Iván Arias Rodríguez

> --brian
> 
> 
> 
> 
> > 
> > 	BR Iván Arias Rodríguez
> 
> -- 
> Brian F. G. Bidulock    ¦ The reasonable man adapts himself to the ¦
> [email-masked]    ¦ world; the unreasonable one persists in  ¦
> http://www.openss7.org/ ¦ trying  to adapt the  world  to himself. ¦
>                         ¦ Therefore  all  progress  depends on the ¦
>                         ¦ unreasonable man. -- George Bernard Shaw ¦
>

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Thu, 6 Mar 2003 08:09:57 -0700

Ivan.Arias-Rodriguez,

On Thu, 06 Mar 2003, [email-masked] wrote:

> > > 	So this is the example of INIT collision. It is the typical one, when
> > > 	both peers start about at the same time. This is the notation used:
> > > 
> > > 	- For all the chunks:
> > > 		o VT is the Verification Tag included in the SCTP header.
> > > 		o IT is the Initiation Tag included in the header of the chunk.
> > > 
> > > 		o VTloc and VTpeer are the values of the local Verification
> > > 		Tag (the one the INIT ACK sender expects in the SCTP headers
> > > 		of the peer) and the peer's Verification Tag (the one the INIT
> > > 		ACK senders includes in its SCTP headers) as included in the
> > > 		State Cookie. Note that those values are directly copied from
> > > 		o TTloc and TTpeer are the values of the local Tie Tag (the
> > > 		value of VTloc at the moment of sending the INIT ACK) and the
> > > 		peer's Tie Tag (the value of VTpeer at the moment of sending
> > > 		the INIT ACK) as included in the State Cookie.  Note that those
> > > 		values are directly copied from the INIT ACK and included in
> > > 		the COOKIE ECHO.
> > > 
> > > Host A                                                              Host B/C
> > > TCB     \   INIT VT:0 IT:W                      INIT VT:0 IT:X   /  TCB
> > > A:1000   \  A:1000->B:1000                      ?:1000->A:1000  /   B,C:1000
> > > B:1000    \                                                    /    A:1000
> > > VTloc:W    \                                                  /     VTloc:X
> > > VTpeer:0    \                                                /      VTpeer:0
> > > C-WAIT       \                                              /       C-WAIT
> > > TCB     \   COOKIE ECHO VT:X                  COOKIE ECHO VT:Y   /  TCB
> > > A:1000   \  A:1000->B:1000                      C:1000->A:1000  /   B,C:1000
> > > B,C:1000  \ VTloc:X VTpeer:W                  VTloc:Y VTpeer:W /    A:1000
> > > VTloc:W    \TTloc:X TTpeer:0                  TTloc:0 TTpeer:0/     VTloc:X
> > > VTpeer:X    \                                                /      VTpeer:Y
> > > C-ECHOED     \                                              /       C-ECHOED
> > >    (2) X<-------------------------/    \------------------------->  (3)
> > > 
> > >                                                COOKIE ACK VT:W   /  TCB
> > >                                                                 /   B,C:1000
> > >                                                                /    A:1000
> > >                                                               /     VTloc:X
> > >                                                              /      VTpeer:W
> > >                                                             /       ESTABLISH
> > >                                       /--------------------/
> > >                                      /                     
> > >                                     / 
> > >                                    /   
> > > 	(1) At this point, Host A doesn't recognize the INIT as coming from
> > > 	the same association it is trying to establish. The VT is completely
> > > 	(2) The received COOKIE ECHO is discarded, since the VT is wrong (Host
> > > 	(3) Host B,C recognizes the collision due to the Tie Tags, recognize
> > > 	(4) The COOKIE ACK is discarded, since Host A is in the C-ECHOED state.

COOKIE-ACKs are not discarded in C-ECHOED state.  The association will form.

> > > 
> > > 
> > > 	And now?
> > > 
> > > 	Host A will retransmit the COOKIE ECHO, Host B,C will answer again,
> > > 	Conclusion: Host A cannot establish an association with Host B,C in
> > > 	this situation.
> > > 

My mistake...  Please ignore previous remarks.  Our implementation can both
generate and resolve collisions.

Walking through the code, let me describe what happens above, assuming
first our implementation is Host A.

At (1) Host A will look for listening sockets/streams.  As there is none,
it will check the TCB hashes with lookup by port and address pair from the
IP and SCTP headers.  If (as I believe you have drawn the diagram) the
INIT from Host B/C has a source address of C, this lookup will fail.  The
INIT will be treated as Out of the Blue and discarded.

So, the INIT-ACK and from HOST A at (1) will not occur.  Which is good,
because the COOKIE-ECHO would have ultimately been discarded.

When Host A receives the INIT-ACK it looks up the socket/stream by
verification tag from the VT hashes and sends the COOKIE-ECHO.

(2) will not occur because Host A did not send an INIT-ACK.

At (3) when Host B/C receives the COOKIE-ECHO with tie tags it will update
VTpeer to W and send the cookie ack.

When Host A receives the COOKIE-ACK the association is established.

When we are Host B/C:

When we receive Host A's INIT  we will look for a listening socket/stream
and find none.  We will then look up in TCB hashes (port pair and address
pair) and find the socket/stream that launched the INIT.  We will populate tie
tags and send the COOKIE-ECHO as described.

When we receive the INIT-ACK we look up the socket by VT in the VT hashes
and send the COOKIE-ECHO as you have shown.

If we receive Host A's COOKIE-ECHO we look up the socket by VT in the
VT hashes because there are no tie tags and find the TCB.  We perform
action B because of the population of tie tags.

Because we are in the COOKIE-ECHOED state we cancel our cookie timer
and send a COOKIE-ACK as shown.

The association forms if we are Host A, or Host B/C, or both Host A and
Host B/C.  We never looked in the source address list to find the TCB.
We did not need to know the addresses of the peer in advance.

This case does not require examining the addresses in the source address
list.

--brian