UDP#
User Datagram Protocol, the connectionless sibling of TCP. No
handshake, no retransmission, no congestion control: a UDP send is
fire-and-forget. Datagram boundaries are preserved (one send() =
one recv()), unlike TCP’s byte stream. It is the protocol that DNS,
NTP, DHCP, mDNS, SNMP, syslog, QUIC, VoIP, and most game traffic ride
on.
Header is eight bytes (source port, destination port, length, and checksum) on top of the IP header. That’s it.
packet-beta
title UDP Header
0-15: "Source Port"
16-31: "Destination Port"
32-47: "Length"
48-63: "Checksum"
64-127: "Payload ..."
Query / reply pattern#
Without a handshake, the application is responsible for matching replies to queries (often by a transaction ID inside the payload, as DNS does). A lost datagram is lost; the application retries or gives up.
sequenceDiagram
participant C as Client
participant S as Server
C->>S: UDP datagram, request, txid=42
S-->>C: UDP datagram, reply, txid=42
Note over C,S: No connection state. Lost packets are the application's problem.
TCP vs UDP#
Property |
TCP |
UDP |
|---|---|---|
Connection |
3-way handshake |
None |
Reliability |
Acks + retransmit |
None (app retries if it cares) |
Order |
Guaranteed |
Out-of-order possible |
Boundaries |
Byte stream |
Datagram (one send = one recv) |
Header |
20-60 bytes |
8 bytes |
Congestion |
Yes (cwnd, slow-start) |
None |
Use cases |
HTTP, SSH, SMTP, etc. |
DNS, NTP, DHCP, video, games, QUIC |
Tools#
Tool |
Use |
|---|---|
|
Send / listen on UDP (BSD or GNU netcat) |
|
Nmap’s netcat; better TLS / proxy / IPv6 support |
|
Bidirectional relay; UDP↔file, UDP↔stdio, UDP↔TCP |
|
List UDP listeners with PID |
|
Capture UDP traffic |
|
UDP port scan (slow; no positive close indicator) |
|
Craft arbitrary UDP packets for testing |
|
UDP throughput / loss test |
UDP scanning#
UDP scans are slow and ambiguous. TCP gets a fast SYN/ACK or RST; UDP gets a response only if the application answers, or an ICMP Port Unreachable if no socket is listening (and that ICMP is rate-limited by the target kernel).
Result |
Meaning |
|---|---|
Open |
App responded with a UDP payload |
Open|Filtered |
No response (could be either) |
Closed |
ICMP type 3 code 3 (Port Unreachable) returned |
Filtered |
ICMP type 3 with admin-prohibited / unreachable codes |
$ sudo nmap -sU -p 53,123,161,500,1900,5353 -sV target
$ sudo nmap -sU --top-ports 100 target
Common pitfalls#
No flow control, a busy receiver silently drops packets. For DNS / NTP that’s fine; for streaming you need application logic.
MTU and fragmentation, UDP datagrams larger than the path MTU (typically 1500 - IP/UDP overhead) get fragmented at the IP layer; some firewalls drop fragments. Keep DNS UDP responses < 512 bytes (or use EDNS / TCP fallback).
Source-port spoofing, trivial; basis for amplification attacks (DNS, NTP, memcached, SSDP). Egress filtering (BCP 38) and rate-limiting are the defenses.
NAT timeouts, UDP “connections” in NAT tables expire fast (often 30-180 s). Apps that need long-lived UDP flows (VPN, WireGuard, QUIC) send keep-alives.
See also#
TCP/IP, the IP layer below and TCP comparison.
Packets, header fields and crafting with Scapy.
Sockets and Ports, the socket API on Linux.
0X42 - Networks, TCP and UDP scanning techniques.
man 7 udp, Linux UDP socket reference.RFC 768 (UDP), RFC 8085 (UDP usage guidelines).