2

I have been testing the SCTP support on Java + lksctp. I wrote a simple client in order to see just the inital setup of a SCTP association which is basically the "INIT" and "INIT ACK". I have tested 2 ways for a Client to send the "INIT" to a SERVER which is basically:

  • create the SctpChannel object with "open(SocketAddress)"

    try {
        InetSocketAddress socketAddress = new InetSocketAddress("192.168.52.197", 2905);
        SctpChannel sctpChannel = SctpChannel.open(socketAddress,1,1); 
        sctpChannel.bind(new InetSocketAddress("192.168.1.251",2906)); 
        sctpChannel.connect(socketAddress, 1 ,1);
    

so in this way, I can see in Wireshark that I have the "IPv4 Address parameter" for all my network interfaces (3 as you can see bellow), but the Source Port is getting a aleatory port number instead the 2906 as I would like to have and it's in the bind.

enter image description here


So... once the bind of local IP/Port is happening after the "open"... so I have changed the code to:

  • create the SctpChannel object which just "open()"

  • binding the local client IP and Port

  • "connect" to the remote Server IP and Port

    try {
        InetSocketAddress socketAddress = new InetSocketAddress("192.168.52.197", 2905);
        SctpChannel sctpChannel = SctpChannel.open(); 
        sctpChannel.bind(new InetSocketAddress("192.168.1.251",2906)); 
        sctpChannel.connect(socketAddress, 1 ,1);
    

In this way, I can see in wireshark that Source/Destination ports are expected (2906/2905), but the INIT does not have the "IPv4 Address parameter".

enter image description here

So does anyone know why the 2nd code I'm missing the "IPv4 address parameter" in the INIT ? Do I miss something?

Any help would be really welcome.

Thanks.

Helio Aymoto
  • 303
  • 2
  • 5
  • 16

1 Answers1

1

IP addresses within INIT/INIT_ACK chunks are optional parameters. In case your endpoints are signglehomed IP address might not be included in the INIT/INIT_ACK chunk. The remote end still can retrieve information about peer address from the IP header.

Fundamentally the reason of this behaviour is what parameters you pass to open(). Open() without any parameters and open() with remote address specified works in a different way.

If you call SctpChannel.open(socketAddress,1,1) with socket address for the remote end it effectively open channel and connects to remote end (see open documentation. Your bind() and connect() calls in this case are pretty useless. So since there were no bind() call prior to establishing the connection you are sort of using "default" endpoint with random port (56044) and IP addresses of all available interfaces.

In second case, when you don't specify socketAddress for open() it just open the channel but does not connect to remote end at this stage. So your bind() call successfully specify endpoint details (port and IP address) and when you call connect() it is actually using the endpoint you just created (192.168.1.251:2906) to setup connection with remote end.

  • Thanks Alexander. Yes, I got that IP Address is an optional parameter for the INIT... but even like this, would it be possible to make the application to send this Optional Parameter (IP Address)? Or it's really a limitation on the lksctp which will not send the IP Address as I'm already bind the local IP/Port? – Helio Aymoto Sep 13 '18 at 21:17
  • It isn't a limitation really. It is just the way it meant to work. RFC 4960 chapter 5.1.2 says "If there are no address parameters present in the received INIT or INIT ACK chunk, the endpoint shall take the source IP address from which the chunk arrives and record it, in combination with the SCTP source port number, as the only destination transport address for this peer." So when the endpoint creates a list of peer's IP addresses it always takes set of the source address from the IP header and IP addresses listed in INIT/INIT_ACK chunk. – Alexander Zinovyev Sep 13 '18 at 21:38