How does a network access server match an arriving RADIUS reply to the request it is waiting on?
answer
- one octet is not much
- the sender is part of the key
- address, port and Identifier together
- verify before believing the reply
- Length wins over the datagram size
basics
~20 sOn the reply's source address and UDP port plus the one-octet Identifier copied from the request, after which the Response Authenticator must verify. Anything that fails those tests is discarded silently, because RADIUS has no error reply.
solid answer
~40 sEvery RADIUS packet opens with the same four header fields: `Code` (1 octet), `Identifier` (1 octet), `Length` (2 octets) and a 16-octet `Authenticator`. The device keeps a table of outstanding requests and looks an arriving reply up by **source IP address, source UDP port and `Identifier`** together — the Identifier alone is only one octet and is reused constantly, so it is meaningless without the address it came from. It then checks the Response Authenticator before believing the packet. `Length` is authoritative: octets beyond it are padding to ignore, and a datagram shorter than it is discarded. Any failure produces silence, never an error packet.
code
pseudocode · 14 linesRADIUS header, 20 octets, attributes follow
Code 1 octet 1 Access-Request, 2 Accept, 3 Reject, 11 Challenge
Identifier 1 octet matches a reply to one outstanding request
Length 2 octets whole packet, minimum 20, maximum 4096
Authenticator 16 octets Request on the way out, Response on the way back
function on_reply(packet, from_address, from_port):
pending = outstanding.lookup(from_address, from_port, packet.Identifier)
if pending is none: discard silently
if packet.Length < 20: discard silently
if response_authenticator_does_not_verify(packet, pending):
discard silently
outstanding.remove(pending)
return packetgo deeper
Know that every RADIUS packet begins with Code, Identifier, Length and a 16-octet Authenticator, and that the Identifier is what pairs a reply with its request.
Explain why the Identifier alone is not enough — one octet, reused, scoped to a sender — and that the match is on source address, source port and Identifier before the Response Authenticator is verified.
Show the operational consequences: the 256-outstanding ceiling per socket and how it is raised, retransmissions that must repeat the Identifier, and the fact that every failed check is a silent drop you can only see in a capture.
The design point worth owning is that identity of a request is carried in one octet plus the sender's address, so scaling a device-to-server pair is a socket question, and any load-sharing arrangement in between must preserve that tuple or replies stop matching.
## The twenty octets every RADIUS packet starts with Every packet in the protocol — request, accept, reject, challenge, accounting — opens with the same fixed header, and the whole matching story lives in it. | Field | Width | Purpose | |---|---|---| | `Code` | 1 octet | Which kind of packet this is: 1 Access-Request, 2 Access-Accept, 3 Access-Reject, 11 Access-Challenge | | `Identifier` | 1 octet | Ties a reply to one outstanding request from one sender | | `Length` | 2 octets | Length of the whole packet, **minimum 20, maximum 4096** | | `Authenticator` | 16 octets | The Request Authenticator on the way out, the Response Authenticator on the way back | Attributes follow the header, which is why the minimum is 20: a packet with no attributes at all is exactly the header. ## How a reply is matched The device keeps a table of requests it has sent and not yet had answered. When a datagram arrives it: 1. Looks up the tuple **(source IP address, source UDP port, `Identifier`)** against that table, and discards the packet if nothing matches. 2. Checks that `Code` is a reply it could plausibly be waiting for. 3. Validates the **Response Authenticator** against the request it thinks this answers, and discards the packet if it does not verify. 4. Only then treats the packet as the answer and retires the pending entry. The third step is the one that matters for trust: without it, anything able to reach the device's socket could forge a reply, since the first two steps test only fields an observer can read. ## Why the Identifier is not enough on its own The Identifier is **one octet**, so it holds 256 distinct values, and it is not globally unique in any sense: - It is scoped to one sender and one socket. Two different servers may legitimately have the same Identifier outstanding at the same instant. - It is reused constantly. The rule is that a value must not be reused for a *different* request until the previous one has been answered or has timed out. - A **retransmission is deliberately the opposite case**: it repeats the same Identifier and the same Request Authenticator, because it is the same request being sent again rather than a new one. That 256-value space is the real concurrency ceiling between one device and one server on one socket: 256 requests may be outstanding, and no more. A busy device escapes the limit by opening additional source ports, since the tuple that scopes the Identifier includes the port. For conversations that span several rounds, RFC 5080 §2.1.2 recommends keying the conversation on `State` and the source address rather than on the RADIUS Identifier, precisely because the Identifier changes on every round. ## Length is authoritative A surprisingly common bug lives here. The receiver trusts `Length`, not the size of the UDP datagram: - If the datagram is **longer** than `Length`, the extra octets are treated as padding and ignored. - If the datagram is **shorter** than `Length`, the packet is malformed and silently discarded. - `Length` also caps the packet at **4096** octets, which is the ceiling on everything a single request or reply can carry. ## Failure is always silence RADIUS defines no error or negative-acknowledgement packet for the access exchange. Every check above fails the same way: the packet is dropped and nothing is sent back. From the other end this is indistinguishable from a network loss. That single design choice is why: - a device configured against the wrong server sees timeouts rather than a complaint; - a reply that fails validation looks exactly like a reply that never arrived; - diagnosis usually means reading a capture on both sides, because neither side is going to say anything. ## What an interviewer is listening for Naming the four header fields is the floor. The answer lands when you say the Identifier is one octet and therefore only meaningful together with the source address and port, and that a reply is not believed until its Authenticator verifies — and that everything which fails is dropped in silence rather than refused.
- How many requests can one device have outstanding to one server, and how do you get past it?256 on a single socket, because the Identifier is one octet and the tuple that scopes it is source address, source port and Identifier. A busy device raises the ceiling by using more source ports, each of which carries its own Identifier space, rather than by changing anything in the protocol.
- Why must a retransmission keep the same Identifier?Because it is the same request sent again, not a new one. Repeating the Identifier and the Request Authenticator byte for byte is what lets the server recognise the duplicate and resend the answer it already computed, instead of authenticating a second time.
- A capture shows a reply with a valid Identifier that the device ignored. What is the likely cause?Either it arrived from an address or port the device was not expecting, so it never matched an outstanding entry, or its Response Authenticator did not verify. Both are dropped silently and look identical in the device's logs, which is why the diagnosis needs captures from both ends.
saying these in an interview costs you the question
- Thinks the Identifier is unique across clients or servers.
- Matches a reply on Identifier alone, ignoring source address and port.
- Believes the 16-octet Authenticator names the session.
- Trusts the UDP datagram size instead of the Length field.
- Assumes thousands of requests can be outstanding on one socket.
- Expects an error packet when a reply fails validation.