SCTP client discarding INIT_ACK sent with different remote IP address from multihomed SCTP server

Pau Espin Pedrol <[email protected]>
Newsgroups org.kernel.vger.linux-sctp
Message-ID <[email protected]>
Hi all,

I recently re-enabled some osmocom tests which validate a multihomed 
connection scenario (see [1] regarding original issue) and I found out 
that they were failing in my system (Archlinux), which has a newer 
kernel (6.17.9-arch1-1) than our jenkins debian hosts which are running 
the same test successfully. I also tested on a local debian13 server 
(6.12.57+deb13-amd64) and it also works fine there.

And actually, Vadim (in CC) is using Archlinux LTS kernel 
(6.12.57-1-lts, which seems to be the same kernel version as the working 
debian13 above) and he's seeing the same problems as I.

The scenario boils down to having an SCTP server binding to 2 IP 
addresses on "lo" interface (127.0.0.1 and 127.0.0.2) on port 2905, and 
a client connecting to it.

* Working case: If the client connects (INIT) to 127.0.0.1, server 
answers (INIT ACK) it all works fine as expected.
* Failing case: If the client connects (SCTP INIT) to 127.0.0.2, server
  still answers (INIT ACK) with src IP address 127.0.01 (note how it's 
different from the IP address it received the SCTP INIT due to default 
route lookup), and the client seems to discard/ignore the  INIT_ACK, and 
retransmits INIT at some point, for a few times, after it decides the 
connect() failed.


So, in summary AFAICT the linux SCTP client stack seems to be discarding 
the INIT_ACK if it came from an IP address != to the one we sent the 
INIT to.

I have been reading a bit through the SCTP specs (RFC4960) and the only 
explicit limitation seems to be that the INIT_ACK dst IP address needs 
to be the same as the INIT src IP addr, but it doesn't mention 
explicitly anything about the INIT_ACK src IP address.

 From section 5.1.2 I one can infer that the INIT src IP address needs 
to be included in the announced SCTP "Addresses" section in INIT_ACK so 
that the client can figure out which connection it is for. That doesn't 
seem to be problem here though, since indeed the INIT_ACK is announcing 
both 127.0.0.1 and 127.0.0.2.

I confirm it's also not a problem about the client not knowing anything 
about 127.0.0.1, because if client does connectx("127.0.0.2", 
"127.0.0.1"), it will still discard the INIT_ACK answered from 
INIT-to-127.0.0.2 and then try with INIT-to-127.0.0.1 (next in list), 
which will then connect successfully.

This can all be reproduced with sctp_darn and monitoring with wireshark, 
see below.

Server:
$ sctp_darn -P 2905 -H 127.0.0.2 -B 127.0.0.1 -l

Client successfully connecting (notice how it sends the INIT to 
127.0.0.2 instead of 127.0.0.1):
$ echo "foobar" | sctp_darn -H 127.0.0.1 -P 8000 -c 127.0.0.1 -p 2905 -s

Client failing to connect:
$ echo "foobar" | sctp_darn -H 127.0.0.1 -P 8000 -c 127.0.0.2 -p 2905 -s

The client knowing the 2 peer addresses doesn't seem to help during 
connect. It won't still accept the INIT_ACK coming from IPaddr differnet 
than the one it sent the INIT too. It ends up connecting because it will 
retry an INIT with the other remote IP address:
$ echo "foobar" | sctp_darn -H 127.0.0.1 -P 8000 -c 127.0.0.2 -c 
127.0.0.1 -p 2905 -s

So this raises the question: Is the client expected to accept INIT_ACK 
coming from a src IP addr != than dst IP addr of the INIT?

* If yes, under which conditions? Why it seems to accept it under some 
kernels and not in others? Did the policy change on purpose or 
accidentally? is this controlled by some tunable I'm not aware of?

* If no, then it looks a bit weird that this simple scenario doesn't 
work out of the box, and I'd expect the server side to transmit the 
INIT_ACK using the same src IP address as the dst IP address of the INIT 
it answered to.


Best Regards,
Pau


[1] https://osmocom.org/issues/6893


-- 
- Pau Espin Pedrol <[email protected]>         http://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Siemensstr. 26a
* 10551 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschaeftsfuehrer / Managing Director: Harald Welte
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.