Consider the three way handshake of TCP. It is explained here.
Now the article above mentions that two sides may try to connect simultaneously and the three way handshake works fine in this case.
Can we simulate this situation using the sockets api. what we usually code using sockets is a passive open(server) and an active open(client)?
@FernandoGonzalezSanchez: A single client can have multiple TCP sockets bound to the same local IP/Port pair as long as they are connected to different remote IP/Port pairs. That is not specific to Windows, that is part of how TCP works in general.
On the TCP level the tuple (source ip, source port, destination ip, destination port) must be unique for each simultaneous connection. That means a single client cannot open more than 65535 simultaneous connections to a single server. But a server can (theoretically) serve 65535 simultaneous connections per client.
TCP is always 2-way. There is no 'send and forget' as with UDP. The first Program would have to open a Server Socket. This means, that it listens on port 25 for a TCP SYN (A flag, that signals that a connection is being opened).
The client application creates a socket and asks the client OS to connect it to the server. The client OS allocates a random local port, chooses a local IP (normally based on which interface the packet will be sent out on) and fills in the remote IP and port requested by the client application.
It is possible to cause a simultaneous TCP open using the sockets API. As Nikolai mentions, it is a matter of executing the following sequence with a timing such that the initial SYNs cross each other.
bind addr1, port1
connect addr2, port2
bind addr2, port2
connect addr1, port1
Here's how I achieved a simultaneous open using a single Linux host.
Slow down the loopback interface using netem
tc qdisc add dev lo root handle 1:0 netem delay 5sec
Run netcat
twice
netcat -p 3000 127.0.0.1 2000
netcat -p 2000 127.0.0.1 3000
The two netcat processes connect to each other resulting in a single TCP connection
$ lsof -nP -c netcat -a -i # some columns removed
COMMAND PID NAME
netcat 27911 127.0.0.1:2000->127.0.0.1:3000 (ESTABLISHED)
netcat 27912 127.0.0.1:3000->127.0.0.1:2000 (ESTABLISHED)
Here's what tcpdump showed me (output edited for clarity)
127.0.0.1.2000 > 127.0.0.1.3000: Flags [S], seq 1139279069
127.0.0.1.3000 > 127.0.0.1.2000: Flags [S], seq 1170088782
127.0.0.1.3000 > 127.0.0.1.2000: Flags [S.], seq 1170088782, ack 1139279070
127.0.0.1.2000 > 127.0.0.1.3000: Flags [S.], seq 1139279069, ack 1170088783
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With