Search code examples
javadockerdocker-composesctp

SCTP connections between Docker containers hangs


I'm having a bit of trouble setting up Docker containers, communicating over SCTP. All the relevant files are below.

After running docker-compose up, here's the output:

$ docker-compose up
Starting server ... done
Starting client ... done 
Attaching to server, client
server    | Opening SctpServerChannel...
server    | Binding to: server/172.18.0.2:3868
server    | Waiting for new connection....
client    | Opening SctpChannel...
client    | Binding to: client/172.18.0.3:0
client    | Connecting to: server/172.18.0.2:3868

The client never successfully connects to the server (and likewise, the server never receives the client's connection).

src/SctpClient.java

import java.io.IOException;
import java.net.InetSocketAddress;

import com.sun.nio.sctp.SctpChannel;

public class SctpClient 
{
    public static void main(String[] args) throws IOException 
    {
        String[] parts = args[0].split(":");
        InetSocketAddress local = new InetSocketAddress(parts[0], Integer.parseInt(parts[1]));

        parts = args[1].split(":");
        InetSocketAddress remote = new InetSocketAddress(parts[0], Integer.parseInt(parts[1]));

        System.out.println("Opening SctpChannel...");
        SctpChannel client = SctpChannel.open();

        System.out.println("Binding to: "+local);
        client.bind(local);

        System.out.println("Connecting to: "+remote);
        if (client.connect(remote))
            System.out.println("Connected!");           
        else
            System.out.println("Connection failed!");
    }
}

src/SctpServer.java

import java.io.IOException;
import java.net.InetSocketAddress;

import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpServerChannel;

public class SctpServer 
{
    public static void main(String[] args) throws IOException 
    {
        String[] parts = args[0].split(":");
        InetSocketAddress local = new InetSocketAddress(parts[0], Integer.parseInt(parts[1]));

        System.out.println("Opening SctpServerChannel...");
        SctpServerChannel server = SctpServerChannel.open();

        System.out.println("Binding to: "+local);
        server.bind(local);

        System.out.println("Waiting for new connection....");
        while (true)
        {
            SctpChannel client = server.accept();
            if (client == null)
                System.out.println("Connection failed!");
            else
                System.out.println("Connected: "+client.getRemoteAddresses());
        }
    }
}

docker-compose.yml

version: '3.7'
services:

        server:
                build:
                        context: .
                        dockerfile: Dockerfile-Server
                image: server
                container_name: server
                restart: unless-stopped
                environment:
                        - LOCAL_IFACE=server:3868
                ports:
                        - "3868:3868/sctp"
                networks:
                        - sctp

        client:
                build:
                        context: .
                        dockerfile: Dockerfile-Client
                image: client
                container_name: client
                restart: unless-stopped
                environment:
                        - LOCAL_IFACE=client:0
                        - REMOTE_IFACE=server:3868
                networks:
                        - sctp
                depends_on:
                        - server
                stdin_open: true
                tty: true

networks:
        sctp:
                name: sctp

Dockerfile-Client

FROM openjdk:11-jdk
RUN apt-get update -y && apt-get install lksctp-tools -y && apt-get clean
WORKDIR /opt
COPY src/SctpClient.java .
CMD java SctpClient.java $LOCAL_IFACE $REMOTE_IFACE

Dockerfile-Server

FROM openjdk:11-jdk
RUN apt-get update -y && apt-get install lksctp-tools -y && apt-get clean
WORKDIR /opt
COPY src/SctpServer.java .
CMD java SctpServer.java $LOCAL_IFACE

Anyone have any suggestions?


Solution

  • I guess after all this time I should post how I got it working:

    Interestingly enough, removing the publishing of the ports from docker-compose.yml allows SCTP between containers to work. This is different compared to how TCP works.

    Also if you wish apps on the host network to communicate with the containers over SCTP, you have to use host networking. This is also different compared to how TCP works.

    At the time of the original post, it seems SCTP support is still primitive in docker.