Transmission of Data Packets
Data are transferred between computers once a connection has been set up as described above. This process is sometimes quite tricky because TCP has several features that call for comprehensive control and security procedures between the communicating hosts:
□ Byte streams are transmitted in a guaranteed order.
□ Lost packets are retransmitted by automated mechanisms.
□ Data flow is controlled separately in each direction and is matched to the speeds of the hosts.
Even though initially these requirements may not appear to be very complex, a relatively large number of procedures and tricks are needed to satisfy them. Because most connections are TCP-based, the speed and efficiency of the implementation are crucial. The Linux kernel therefore resorts to tricks and optimizations, and unfortunately these don't necessarily make the implementation any easier to understand.
Before turning our attention to how data transmission is implemented over an established connection, it is necessary to discuss some of the underlying principles. We are particularly interested in the mechanisms that come into play when packets are lost.
The concept of packet acknowledgment based on sequence numbers is also adopted for normal data packets. However, sequence numbers reveal more about data transmission than mentioned above. According to which scheme are sequence numbers assigned? When a connection is set up, a random number is generated (by the kernel using secure_tcp_sequence_number from drivers/char/random.c). Thereafter a system supporting the strict acknowledgment of all incoming data packets is used.
A unique sequence number that builds on the number initially sent is assigned to each byte of a TCP transmission. Let us assume, for example, that the initial random number of the TCP system is 100. The first 16 bytes sent therefore have the sequence numbers 100,101,... ,115.
TCP uses a cumulative acknowledgment scheme. This means that an acknowledgment covers a contiguous range of bytes. The number sent in the ack field acknowledges all bytes between the last and the current ACK number of a data stream. (The initial sequence number is used as the starting point if an acknowledgment has not yet been sent and there is therefore no last number.) The ACK number confirms receipt of all data up to and including the byte that is 1 less than the number and therefore indicates which byte is expected next. For instance, ACK number 166 acknowledges all bytes up to and including 165 and expects bytes from 166 upward in the next packet.
This mechanism is used to trace lost packets. Note that TCP does not feature an explicit re-request mechanism; in other words, the receiver cannot request the sender to retransmit lost packets. The onus is on the sender to retransmit the missing segment automatically if it does not receive an acknowledgment within a certain time-out period.
How are these procedures implemented in the kernel? We assume that the connection was established as described above so that the two sockets (on the different systems) both have the ESTABLISHED state.
Continue reading here: Receiving Packets
Was this article helpful?