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