English French
A closer look at TCP
Another example is the simultaneous establishment of a TCP connection. The TCP stack sends a ``SYN`` and receives a ``SYN`` in response instead of a ``SYN+ACK``. It then acknowledges the received ``SYN`` and retransmits its own ``SYN``. The connection becomes established upon reception of the fourth segment. This script is available from :download:`/exercises/packetdrill_scripts/dual.pkt`.
Another interesting features of packetdrill_ is that it is possible to inspect the state maintained by the Linux kernel for the underlying connection using the ``TCP_INFO`` socket option. This makes it possible to retrieve the value of some variables of the TCP control block.
Another interesting scenario is when the loss happens early in the data transfer. This is shown in the script below where the second segment is lost. We observe that by triggering transmissions of unacknowledged data, the :rfc:`3042` rule speeds up the recovery since a fast retransmit happens. This script is available from :download:`/exercises/packetdrill_scripts/slow-start-frr2.pkt`.
Another usage of packetdrill_ is to explore how a TCP connection ends. The scripts below show how a TCP stack closes a TCP connection. The first example shows a local host that connects to a remote host and then closes the connection. The remote host acknowledges the ``FIN`` and later closes its direction of data transfer. This script is available from :download:`/exercises/packetdrill_scripts/local-close.pkt`.
Another very interesting utilization of packetdrill_ is to explore how a TCP stack reacts to acknowledgments that would correspond to lost or reordered segments. For this analysis, we configure a very large initial congestion window to ensure that the connection does not start with a slow-start.
As for the establishment of a connection, it is also possible for the two communicating hosts to close the connection at the same time. This is shown in the example below where the remote host sends its own ``FIN`` when acknowledging the first one. This script is available from :download:`/exercises/packetdrill_scripts/local-close2.pkt`.
Assuming that there are no losses and that there is no congestion in the network. If the sender writes `x` bytes on a newly established TCP connection, derive a formula that computes the minimum time required to deliver all these `x` bytes to the receiver. For the derivation of this formula, assume that `x` is a multiple of the maximum segment size and that the receive window and the slow-start threshold are larger than `x`.
A TCP connection has been active for some time and has reached a congestion window of 4000 bytes. Four segments are sent, but the second (shown in red in the figure) is corrupted. Complete the time-sequence diagram.
A TCP stack uses both the fast retransmit technique and retransmission timers. A retransmission timer can fire after a fast retransmit when several segments are lost. The example below shows a loss of two consecutive segments. This script is available from :download:`/exercises/packetdrill_scripts/frr-rto.pkt`.
A third scenario for the termination of a TCP connection is that the remote hosts sends its ``FIN`` first. This script is available from :download:`/exercises/packetdrill_scripts/remote-close.pkt`.
At this point, the socket is ready to accept incoming TCP connections. packetdrill_ needs to inject a TCP segment in the instrumented Linux stack. This can be done with the line below.
By default, packetdrill_ uses port 8080 when creating TCP segments. You can thus capture the packets injected by packetdrill_ and the responses from the stack by using ``tcpdump -i any -n port 8080``
Can you explain why the congestion window is increased after the reception of the first acknowledgment ?
Can you explain why the sender only sends one segment first and then two successive segments (the delay between the two segments on the figure is due to graphical reasons) ?
Each line of a packetdrill_ script starts with a `timing` parameter that indicates at what time the event specified on this line should happen. packetdrill_ supports absolute and relative timings. An absolute timing is simply a number that indicates the delay in seconds between the start of the script and the event. A relative timing is indicated by using ``+`` followed by a number. This number is then the delay in seconds between the previous event and the current line. Additional information may be found in [CCB+2013]_.
For our first packetdrill_ script, we aim at reproducing the simple connection shown in the figure below.
For this first example, we program packetdrill_ to inject the segments that a client would send. The first step is thus to prepare a :manpage:`socket` that can be used to accept this connection. This socket can be created by using the four system calls below.
How long does it take for the sender to deliver 3 KBytes to the receiver ?
Injecting segments in the Linux TCP stack