Chapter 10. User Datagram Protocol (UDP) and IP Fragmentation

Introduction

UDP is a simple, datagram-oriented, transport-layer protocol that preserves message boundaries:

[RFC0768] is the official specification of UDP, and it has remained as a standard without significant revisions for more than 30 years.

Advantages of UDP *

Given this lack of reliability and protection, we might be tempted to conclude that there are no benefits to using UDP at all. This is not true, however. UDP has the following advantages:

Encapsulation of a UDP datagram *

The following figure shows the encapsulation of a UDP datagram as a single IPv4 datagram.

Figure 10-1 Encapsulation of a UDP datagram in a single IPv4 datagram (the typical case with no IPv4 options). The IPv6 encapsulation is similar; the UDP header follows the header chain.

UDP Header

THe following figure shows UDP datagram, including the payload and UDP header (which is always 8 bytes in size):

Figure 10-2 The UDP header and payload (data) area. The Checksum field is end-to-end and is computed over the UDP pseudo-header, which includes the Source and Destination IP Address fields from the IP header. Thus, any modification made to those fields (e.g., by NAT) requires a modification to the UDP checksum

Transport protocols such as TCP and UDP, and SCTP [RFC4960] use the destination port number to help demultiplex incoming data from IP. Because IP demultiplexes the incoming IP datagram to a particular transport protocol based on the value of the Protocol field in the IPv4 header or Next Header field in the IPv6 header, this means that the port numbers can be made independent among the transport protocols. That is, TCP port numbers are used only by TCP, and the UDP port numbers only by UDP, and so on. A straightforward consequence of this separation is that two completely distinct servers can use the same port number and IP address, as long as they use different transport protocols.

Despite this independence, if a well-known service is provided (or can conceivably be provided) by both TCP and UDP, the port number is normally allocated to be the same for both transport protocols. This is purely for convenience and is not required by the protocols. See [IPORT] for details on how port numbers are formally assigned.

UDP Checksum

Examples

UDP and IPv6

UDP-Lite

IP Fragmentation

IP employs fragmentation and reassembly. Fragmentation in IPv4 can take place at the original sending host and at any intermediate routers along the end-to-end path. Note that datagram fragments can themselves be fragmented. Fragmentation in IPv6 is somewhat different because only the source is permitted to perform fragmentation.

When an IP datagram is fragmented, it is not reassembled until it reaches its final destination, because:

  1. Not performing reassembly within the network alleviates the forwarding software (or hardware) in routers from implementing this feature
  2. Different fragments of the same datagram may follow different paths to their common destination

Example: UDP/IPv4 Fragmentation

An UDP application may wish to avoid IP fragmentation, because when the size of the resulting datagram exceeds the link’s MTU, the IP datagram is split across multiple IP packets, which can lead to performance issues because if any fragment is lost, the entire datagram is lost.

A single UDP datagram with 2992 UDP payload bytes is fragmented into three UDP/ IPv4 packets (no options).

A single UDP datagram with 2992 UDP payload bytes is fragmented into three UDP/ IPv4 packets (no options). The UDP header that contains the source and destination port numbers appears only in the first fragment (a complicating factor for firewalls and NATs). Fragmentation is controlled by the Identification, Fragment Offset, and More Fragments (MF) fields in the IPv4 header.

The original UDP datagram included 2992 bytes of application (UDP payload) data and 8 bytes of UDP header, resulting in an IPv4 Total Length field value of 3020 bytes (IP header is 20-byte). When this datagram was fragmented into three packets, 40 extra bytes were created (20 bytes for each of the newly created IPv4 fragment headers). Thus, the total number of bytes sent is 3060. [p489]

Fields:

If one fragment is lost, the entire datagram is lost, since IP itself has no error correction mechanism of its own. Mechanisms such as timeout and retransmission are left as the responsibility of the higher layers. For this reason, fragmentation is often avoided.

We can use our sock program and increase the size of the datagram until fragmentation occurs. On an Ethernet, the maximum amount of data in a frame is ordinarily 1500 bytes, which leaves at most 1472 bytes for application data to avoid fragmentation, assuming 20 bytes for the IPv4 header and 8 bytes for the UDP header.

We will run our sock program with data sizes of 1471, 1472, 1473, and 1474 bytes. We expect the last two to cause fragmentation:

[p490-492]

Linux% sock -u -i -n1 -w1471 10.0.0.3 discard
Linux% sock -u -i -n1 -w1472 10.0.0.3 discard
Linux% sock -u -i -n1 -w1473 10.0.0.3 discard
Linux% sock -u -i -n1 -w1474 10.0.0.3 discard
1 23:42:43.562452 10.0.0.5.46530 > 10.0.0.3.9:
        udp 1471 (DF) (ttl 64, id 61350, len 1499)
2 23:42:50.267424 10.0.0.5.46531 > 10.0.0.3.9:
        udp 1472 (DF) (ttl 64, id 62020, len 1500)
3 23:42:57.814555 10.0.0.5 > 10.0.0.3:
        udp (frag 37671:[email protected]) (ttl 64, len 21)
4 23:42:57.814715 10.0.0.5.46532 > 10.0.0.3.9:
        udp 1473 (frag 37671:[email protected]+) (ttl 64, len 1500)
5 23:43:04.368677 10.0.0.5 > 10.0.0.3:
        udp (frag 37672:[email protected]) (ttl 64, len 22)
6 23:43:04.368838 10.0.0.5.46535 > 10.0.0.3.9:
        udp 1474 (frag 37672:[email protected]+) (ttl 64, len 1500)

One observation that may be surprising is that the fragments with larger offsets are delivered prior to the first fragments. In effect, the sender has intentionally reordered the fragments. This behavior can be beneficial. If the last fragment is delivered first, the receiving host is able to ascertain the maximum amount of buffer space it will require in order to reassemble the entire datagram.