Transport Layer
Transport layer is the layer at end hosts, between the application and network layer.
Why is it needed?
- It's needed because IP packets are addressed to a host but end-to-end communication is between application processes at hosts. We need a way to decide which packets go to which applications (multiplexing/demultiplexing).
- IP provides a weak service model (best-effort). This means packets can be corrupted, delayed, dropped, reordered, or duplicated. There is no guidance on how much traffic to send and when. Dealing with this is tedious for application developers.
The role of the transport layer are as follows: (1) to communicate between processes.
- Mux and demux from/to application processes, implemented using ports
(2) to provide common end-to-end services for the app layer (optional).
- Reliable, in-order data delivery
- Well-paced data delivery. Too fast may overwhelm the network while too slow is inefficient
(3) TCP and UDP are the common transport protocols along with MPTCP, RDP, DCTP.
(4) UDP is a minimalist transport protocol, only providing mux/demux capabilities.
(5) TCP offers a reliable, in-order, byte stream abstraction with congestion control, but has no performance guarantees meaning there could be delays, b/w, etc.
Multiplexing and Demultiplexing
Multiplexing (mux) is when you gather and combine data chunks at the source host from different applications and deliver them to the network layer.
Demultiplexing (demux) is delivering correct data to corresponding sockets from a multiplexed stream.
Sockets
A socket is a software abstraction for an application process to exchange network messages with the transport layer in the operating system. I.e., its an endpoint/door that allows different nodes to communicate with each other. They are responsible for sending and receiving data.
There are two types of sockets
- UDP socket: TYPE is
SOCK_DGRAM - TCP socket: TYPE is
SOCK_STREAM
Ports
Ports are 16-bit numbers that help distinguish apps.
- Packets carry src/dst port number in transport header
- Well known (0-1023) and ephemeral ports
- You may need to open up a port so that the server can send a response
OS stores mapping between sockets and ports
- port in packets and sockets in OS
- For UDP ports (SOCK_DGRAM), the OS stores (local port, local IP address) <-> socket.
- For TCP ports (SOCK_STREAM), the OS stores (local port, local IP, remote port, and remote IP) <-> socket
User Diagram Protocol
UDP is a lightweight communication protocol between processes.
- avoids overhead and delays of order and reliability
- e.g., video streaming
UDP described in RFC768 in 1980
- destination IP address and port supports demultiplexing
User datagram header format from RFC768:
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
|
| data octets ...
+---------------- ...
Its header comprises of: SRC and DST port, length, and checksum.
- SRC port is optional because its not expecting a response. It's useful only when you need to respond back to the sender.
- length is the length of the data + the length of the header
There is an optional error checking on the packet contents
- checksum field = 0 means "don't verify checksum"
- checksum verifies if the packet has been corrupted or not.
Reliable Transport
Reliable transport means that packets are guaranteed to be delivered. Best-effort may have some negative consequences that include being: corrupted, lost, delayed, reordered, duplicated packet.
Some mechanisms for coping with these bad events:
- checksum: detect corruption; detects bit errors
- ACKs: receiver tells sender that it received the packet
- NACK: receiver tells sender it did not receive packet correctly
- Sequence numbers: a way to identify packets; this deals with duplicates
- Retransmission sender resends packet
- Timeouts: decide when to resend packets; detect loss
Steps in dealing with packet corruption:
- sender sends the receiver
- receiver checks the checksum
- Correct state: checksum is okay, and it sends an ACK.
- Incorrect state: checksum is not okay, and it sends an NACK.
- Sender resends the packet
But what if the ACK/NACK is corrupted? This causes the sender to not realize that a packet has already been acknowledged and it resends the same packet.
- The packet is sent with a sequence number. The receiver knows that the packet it receives was packet 1 and it will resend an ACK for 1.
What if a packet is lost when sent? Timer-driven loss detection can be used to detect this. It sets a timer when the packet is sent; and retransmits on timeout if there's no ACK/NACK when in the timeout period
When if the ACK packet is lost? Then you send again.
However, timer-driven retransmissions can lead to duplicates.
What do you do with a duplicate packet? (like if you receive ACK after the timeout). Nothing you can do about it.
In summary, strategies were created to address the problems:
- checksum detects bit errors
- timers detect loss
- acks (positive negative)
- sequence number deals with duplicates
Stop and Wait
One idea for a reliable transport solution, called Stop & Wait:
@SENDER
- send packet(i); (re)set timer; wait for ack
- if (ACK):
- i++; repeat
- if (NACK or TIMEOUT):
- repeat
@RECEIVER
- wait for packet
- if (packet OK): send ACK
- else: send NACK
- repeat
Although this is a correct, and reliable transport protocol that handles every situation. However, the problem is that its extremely slow:
If (TRANS << RTT) then Throughput ~ DATA/RTT
Transmission time for 10 Gbps link:
- ~microsecond for 1500 byte packet
RTT:
- 1,000 kilometers ~ milliseconds. This is really low.
Three design decisions:
- Which packets can senders send? (sliding window)
- How does receiver ack packets? the two well known proceedures are cumulative. You can give acknowledgement one at a time (selective), or say which range of packets was received (cumulative).
- which packets does sender resend? go-back N (GBM) or selective repeat (SR).
Sliding window
A window is a set of adjacent sequence numbers. The size of the set is the window size, . The general idea is to send up to packets at a time.
- Sender can send packets in its window, and receivers can accept packets in its window.
- Window of acceptable packets "slides" on successful reception/acknolwedgement.
- Window contains all packets that might still be in transit
The sliding window called "Packets in Flight".
The mechanism:
- Let be the sequence number of the last ack'd packet of sender without a gap; then the window of the sender is
- Let be the last received packet without a gap by receiver, then the window of receiver is
Throughput: If window size is , then throughput compared to stop and wait is roughly:
- Stop and wait:
- Sliding window:
When is too large, then the upper rate is bound by the link bandwidth:
Two common options for acknowledgments with sliding window:
- Cumulative ACKs: ACK caries next in-order sequence number that the receiver expects.
- Selective ACKs: ACK individually acknowledges correctly received packet. This is more precise, but requires more complicated book-keeping
Protocols for resending packets:
- Go-Back-N (GBN): sender transmit up to acknowledged packets. Receiver only accepts packets in order, and discards the out-of-order ones (). Receiver uses cumulative acknowledgments. Sender sets timer for 1st outstanding ack (), and if timeout, retransmit .
- Better when the error rate is low; wastes bandwidth otherwise
- Selective Repeat (SR): transmit up to unacknowledged packets. Assume packet is lost, is not. Receiver will indicate that was correctly received and buffered. Sender will retransmit only packet on timeout. There is efficient in retransmissions but complex book-keeping. We need a timer/flag per packet on the sender side.
- Better when error rate is high; otherwise, too complex
- Many other variants
Linked from Computer Networks