Skip to content

half-duplex TCP FIN not working with published ports #27539

@a-ba

Description

@a-ba

Description

The implementation of published ports (redirected TCP streams), when going through the socket bound by the docker engine (not through iptables nat) interferes with TCP's half-duplex close sequence. The connection is closed prematurely and reset.

TCP allows closing half of the stream only. When an endpoint sends a FIN message, it means that the endpoint will no longer send any data but it may still receive data from the other endpoint (until the other endpoint sends a FIN message too).

https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination

When the docker engine receives EOF (FIN) from the incoming connection, it closes immediately the two sockets with the system call close(), whereas it should only call shutdown(sock, SHUT_WR) on the outgoing socket. close() should be called only after the two sides of the channel are shut down and all the data is transmitted.

Steps to reproduce the issue:

  1. build the tcp-bug-server image from:
FROM debian:jessie
RUN apt-get -y -qq update && apt-get -y -qq install socat
CMD ["socat", "TCP-LISTEN:1234,fork", "EXEC:echo hello"]
  1. build the tcp-bug-client image from:
FROM debian:jessie
RUN apt-get -y -qq update && apt-get -y -qq install socat
CMD socat STDIO TCP:172.17.0.1:1234 </dev/null
  1. launch a capture
tcpdump -i docker0 -s 2000 -w /tmp/cap.dump
  1. run the server
docker run -d -p 1234:1234 tcp-bug-server
  1. run the client
docker run --rm tcp-bug-client
  1. open the capture in wireshark and select "Statistics" -> "Flow Graph" -> "TCP Flow"

Describe the results you received:

The client prints nothing on stdout

The wireshark flowgraph:

client          docker          server
        FIN
------------------>
     FIN, ACK
<------------------
        ACK
------------------>
                          FIN
                   ------------------>
                        PSH, ACK                       
                   <------------------
                          RST
                   ------------------>

Describe the results you expected:

The client prints "hello" on stdout

The wireshark flowgraph:

client          docker          server
        FIN
------------------>
        ACK
<------------------
                          FIN
                   ------------------>
                        PSH, ACK                       
                   <------------------
                          ACK
                   ------------------>
        PSH 
<------------------
        ACK
------------------>
                          FIN
                   <------------------
                          ACK
                   ------------------>
        FIN
<------------------
        ACK
------------------>

Additional information you deem important (e.g. issue happens only occasionally):

happens every time

Output of docker version:

Client:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   209592a
 Built:        Wed Aug  3 14:21:36 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   209592a
 Built:        Wed Aug  3 14:21:36 2016
 OS/Arch:      linux/amd64

Output of docker info:

Containers: 28
 Running: 10
 Paused: 0
 Stopped: 18
Images: 600
Server Version: 1.12.0
Storage Driver: overlay
 Backing Filesystem: extfs
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: null overlay bridge host
Swarm: active
 NodeID: 15jqcnhs5qwm3wiu6wvnpj2ph
 Is Manager: true
 ClusterID: 1yfrvoydx73ahwcuzoroo1nn3
 Managers: 1
 Nodes: 1
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot interval: 10000
  Heartbeat tick: 1
  Election tick: 3
 Dispatcher:
  Heartbeat period: 5 seconds
 CA configuration:
  Expiry duration: 3 months
 Node Address: 172.17.42.1
Runtimes: runc
Default Runtime: runc
Security Options: seccomp
Kernel Version: 4.4.0-0.bpo.1-amd64
Operating System: Debian GNU/Linux 8 (jessie)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.728 GiB
Name: halfoat
ID: DJOY:YSRX:QDV6:ZLD3:G7MH:SLXG:6MRI:K4Y5:MZ5W:XVYR:MMQN:ABKA
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No kernel memory limit support
Insecure Registries:
 false
 127.0.0.0/8

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/networkingNetworkingkind/bugBugs are bugs. The cause may or may not be known at triage time so debugging may be needed.version/1.12

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions