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?
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.