servers.diameter
Diameter server
Peer-group selection values accept both underscore and hyphen spellings. Prefer
underscores, such as round_robin and no_fallback.
A diameter server defines local Diameter identities, remote peers, peer
groups, and an incoming request policy. A local node advertises capabilities
and owns named listeners. Each peer adjacency chooses an incoming, outgoing,
or bidirectional connection to a local node.
Radiator Server keeps outgoing and bidirectional adjacencies connected. After a failed connection attempt it waits about one second before the next one, and doubles the wait after each further failure up to about thirty seconds. A connection that is lost less than 30 seconds after it opened counts as a failed attempt, so a peer that closes connections right after the capability exchange is not redialled every second. After the loss of a connection that stayed open longer, the wait starts again at about one second. In a bidirectional adjacency the peer's own connection can be the Open one; Radiator Server then reconnects only after that connection is lost. A configuration reload disconnects existing connections with a Disconnect-Peer-Request after their pending requests finish.
Set policy to send application requests directly through normal AAA policy
and handler processing. Handlers select requests using Diameter metadata and
AVPs. Advertised application IDs enable the corresponding command schemas.
Incoming peer adjacencies require a server policy. Outgoing-only servers
may omit it. Unsolicited application requests on a server without a policy
receive DIAMETER_UNABLE_TO_DELIVER (3002). Forward requests from handlers
through a Diameter backend with action proxy; and a configured peer group.
Diameter requires TLS unless you set compatibility_unprotected_tcp true on
the listener or outgoing adjacency. This setting permits authentication and
accounting over plain TCP, including PAP passwords, tunnel passwords, and EAP
master session keys. These values have no Diameter transport encryption in
compatibility mode. EAP-TTLS still encrypts its inner authentication exchange,
but the exported master session key follows the configured Diameter transport.
servers {
diameter "DIAMETER" {
local_node "CORE" {
identity "core.example.net";
realm "example.net";
capabilities {
vendor_id 9048;
product_name "Radiator";
host_ip_address "127.0.0.1";
auth_application_id 1;
}
listener "TCP" {
compatibility_unprotected_tcp true;
listen {
protocol tcp;
ip 127.0.0.1;
port 3868;
}
}
}
peer "NAS" {
identity "nas.example.net";
adjacency "CORE" {
direction incoming;
local_node "CORE";
accept_on "TCP";
}
}
peer_group "ACCESS" {
peer "NAS";
selection ordered;
}
policy "NASREQ";
}
}
Connection handling
Radiator Server sends a Device-Watchdog-Request (DWR) on an idle Open connection after about 30 seconds. Each interval has a random variation of up to +/-2 seconds. When the interval passes again without a Device-Watchdog-Answer (DWA), the connection becomes suspect. Peer selection then stops choosing it for new requests, and requests waiting for an answer on it fail over to another eligible peer. Any valid message from the peer returns the connection to normal use. If the next interval also passes without a DWA, Radiator Server closes the connection. These timers are not configurable.
Each peer adjacency processes at most 1024 incoming application requests at
the same time. Requests that arrived on an earlier connection of the adjacency
count until their processing ends, also after that connection closed. A request
that arrives while this limit is reached is answered immediately with
DIAMETER_TOO_BUSY (3004) when its Destination-Host names the local node,
and with DIAMETER_UNABLE_TO_DELIVER (3002) otherwise, as RFC 6733 reserves
3004 for requests addressed to a specific server. Both answers let the peer
send the request to another peer. Answers, watchdog messages, and disconnect
messages are always processed.
When a configuration reload or a server stop drains a connection, requests
that are already in policy processing complete and are answered. Requests that
arrive during the drain, or that are still waiting for policy processing when
it starts, are answered immediately with 3004 or 3002 by the same rule.
Radiator Server detects retransmitted requests by their Origin-Host and
End-to-End Identifier. A retransmission of a request that is still being
processed is not processed again. A retransmission of a request that was
answered within the last 60 seconds receives the earlier answer again, also
when it arrives through another Diameter agent. A request that reuses the same
Origin-Host and End-to-End Identifier with different contents receives
DIAMETER_UNABLE_TO_COMPLY (5012) and is not processed. Set
maximum_duplicate_responses and maximum_duplicate_response_bytes in
resource_limits to bound the retained answers.
A request that fails validation receives the RFC 6733 Result-Code for the
failure, such as DIAMETER_AVP_UNSUPPORTED (5001),
DIAMETER_INVALID_AVP_VALUE (5004), DIAMETER_MISSING_AVP (5005), or
DIAMETER_INVALID_AVP_LENGTH (5014). The answer names the offending or
missing AVP in Failed-AVP. The connection stays open as long as message
framing is intact. A Capabilities-Exchange-Request received on an Open
connection is answered and the connection stays open; one that fails
validation is answered with the Result-Code of its failure.
On a compatibility_unprotected_tcp connection, Radiator Server rejects a peer
whose Inband-Security-Id list is not empty and does not contain
NO_INBAND_SECURITY (0). An incoming Capabilities-Exchange-Request from such
a peer receives DIAMETER_NO_COMMON_SECURITY (5017), and an outgoing
connection to such a peer is closed.
Radiator Server logs connection open and close events at trace level, with the connection direction and the closing cause. Failures that close a connection are logged as separate events.
Destination-Host and realm
RFC 6733 section 6.1.4 lets a node process a request locally only when the
request's Destination-Host is absent or names that node. Radiator Server
compares Destination-Host with the identity of the local node that received
the request, without regard to letter case. Policy does not answer a request
that names any other host, including another local node of the same server:
- When the server has no
peer_group, nothing could forward the request, so it is answered withDIAMETER_UNABLE_TO_DELIVER(3002) before policy runs. - Otherwise policy runs and may forward the request through a Diameter backend
with
action proxy;. If policy completes without forwarding it, Radiator Server answers3002instead of the policy result. Ignore and discard results still send no answer. Actions such as backend lookups have already run by then, so select the requests to forward in handler conditions ondiameter.destination_host.
Destination-Realm is not compared with the local node's realm. Handler
conditions on diameter.destination_realm act as the realm routing table:
policy answers, forwards, or rejects the realms it selects. A request without
Destination-Host is processed by policy whatever its Destination-Realm.
Peer group selection
selection round_robin rotates the first eligible peer for each new request.
selection least_connections chooses the peer with the fewest pending transactions
and rotates among peers tied for the lowest load. Failover excludes previously
attempted connections and continues cyclically after the last attempted peer.
For least_connections, lower load takes precedence over cyclic tie-breaking.
Retries do not advance the rotation for new requests.
Policy and handler selection
An explicitly named server policy selects its handlers directly. Its policy conditions are not evaluated. Put realm, host, application, command, and peer selection conditions in the handlers:
aaa {
policy "NASREQ" {
conditions all {
aaa.protocol == protocol.DIAMETER;
}
handler "LOCAL_NASREQ" {
conditions all {
diameter.destination_realm == /^example\.net$/i;
diameter.application_id == diameter.APPLICATION_NASREQ;
diameter.command_code == diameter.COMMAND_AA;
}
@execute {
conditions any {
diameter.destination_host == none;
diameter.destination_host == /^core\.example\.net$/i;
}
backend { name "USERS"; query "FIND_USER"; }
pap;
}
}
handler "UNHANDLED" {
@execute {
reject;
}
}
}
}
Configure USERS and its FIND_USER query to load the password used by pap.
Use an anchored regular expression with the i flag for case-insensitive
identity matching. A final handler with reject returns a rejection for
requests not selected by earlier handlers. Without a matching handler,
normal policy processing does not produce a reply.
Routing metadata is read-only:
| Field | Value |
|---|---|
diameter.server | Receiving server name |
diameter.local_node | Local node name |
diameter.peer | Configured incoming peer name |
diameter.peer_identity | Negotiated remote peer identity |
diameter.adjacency | Incoming adjacency name |
diameter.destination_realm | Destination-Realm AVP, or none |
diameter.destination_host | Destination-Host AVP, or none |
diameter.origin_realm | Origin-Realm AVP |
diameter.origin_host | Origin-Host AVP |
diameter.application_id | Request Application-ID |
diameter.command_code | Request command code |
Read additional AVPs through diameter.request.<AVP-Name>. Stage answer AVPs
through diameter.answer.<AVP-Name> and set an explicit application result with
diameter.result_code.
Policy reads a Diameter Time AVP, such as Event-Timestamp, as a timestamp.
Assign a timestamp, now, or an integer number of seconds since 1970-01-01
00:00:00 UTC to a Time AVP. The value must be within the range that Diameter
Time can represent.
NASREQ CHAP
Use the chap action to authenticate CHAP-MD5 NASREQ requests against a user
backend. The request must contain one CHAP-Auth group with algorithm 5, a
one-octet CHAP-Ident, a 16-octet CHAP-Response, and a nonempty CHAP-Challenge.
Diameter has no implicit challenge when CHAP-Challenge is absent.
The NASREQ RADIUS bridge profiles preserve these credentials in both directions.
When a RADIUS/1.0 request omits CHAP-Challenge, its Request Authenticator becomes
the explicit Diameter challenge. RADIUS/1.1 requests require an explicit challenge.
Native NASREQ challenges
Use challenge; in a native NASREQ handler to return
DIAMETER_MULTI_ROUND_AUTH and resume the same handler on the next AAR.
The client retains Session-Id and sends its response in User-Password.
Each continuation retains the authenticated peer, routing identities, User-Name,
and Auth-Request-Type. A changed request mode cannot enter an active exchange.
Local challenges omit optional State unless policy explicitly stages
diameter.answer.State. When supplied, the next request must echo those exact
bytes. A later challenge can omit State again. This follows
RFC 7155 section 3.2.
Auth-Request-Type assignments accept the dictionary names "AUTHENTICATE_ONLY",
"AUTHORIZE_ONLY", and "AUTHORIZE_AUTHENTICATE".
Select native authentication-only or authorization-only policy using
diameter.request.Auth-Request-Type and the named constants below.
NASREQ RADIUS bridges
The nasreq profile maps non-EAP Access-Challenge responses to
DIAMETER_MULTI_ROUND_AUTH. A continuation uses the same Session-Id and carries
any State returned in the preceding Diameter answer. RADIUS-facing bridges issue
an opaque State token that recovers the Diameter session and the backend State.
Terminal answers omit State when the upstream omitted it.
The default authorization mappings include Acct-Interim-Interval, Prompt,
Password-Retry, and Login-IPv6-Host. NAS-Filter-Rule uses Diameter AVP 400 and
RADIUS attribute 92. Bridges reassemble RADIUS fragments before splitting rules
at NUL separators, and fragment translated RADIUS rules into at most 253 value
octets per attribute. Empty rules and embedded NUL in an individual Diameter rule
are rejected. Tunneling groups preserve binary Tunnel-Private-Group-Id and
Tunnel-Assignment-Id values, including non-UTF-8 bytes and trailing NULs.
Configuration-Token is available to Diameter policy as opaque data. The default
RADIUS mappings do not forward it to the NAS.
Accounting logging
Use a handler's final pipeline to log the accounting outcome. Capture any
diameter.request AVPs needed by the log into vars before invoking a backend.
The backend can consume request ownership, leaving those request AVPs unavailable
in @final_execute. Peer identity and the application ID remain available.
Record Session-Id, Accounting-Record-Type and Accounting-Record-Number with
usage counters and the final result. Preserve opaque Class and Acct-Session-Id
values as hex when logging them. The Diameter and RADIUS accounting example
includes capture and logging pipelines plus a sample NAS packet sender.
Native EAP sessions
Native Diameter EAP uses Session-Id to resume a pending authentication
conversation. Keep the same Session-Id throughout the exchange and select a
new value when starting a new EAP conversation, as specified by
RFC 4072 section 2.8.5.
A local EAP challenge does not require a State AVP in the next request.
Sessions belong to their Diameter server, local node, and application. Continuations must retain the authenticated peer and origin and destination identities, and answer the current EAP request identifier and retain Auth-Request-Type. Identity casing can change, and an absent Destination-Host can become the explicit identity of the receiving local node. The same authenticated peer can continue its session on another connection.
Local Diameter EAP challenges omit State. A Diameter EAP-to-RADIUS bridge keeps the backend's RADIUS State internally and also resumes by Session-Id without emitting Diameter State. Native Diameter proxies preserve remote State unchanged.
RADIUS clients still return their Access-Challenge State so a RADIUS-to-Diameter bridge can recover the corresponding Diameter session. Continuations retain the original destination realm, end server and next-hop peer. A continuation selected for another realm is rejected.
Policy constants
Use the read-only diameter constants in policy expressions and string
interpolation. They return unsigned numeric IDs and are available without a
Diameter request context. Names are case-sensitive; unknown names and
assignments to constants fail during configuration compilation.
| Application constant | Value |
|---|---|
diameter.APPLICATION_BASE | 0 |
diameter.APPLICATION_NASREQ | 1 |
diameter.APPLICATION_BASE_ACCOUNTING | 3 |
diameter.APPLICATION_EAP | 5 |
| Command constant | Value |
|---|---|
diameter.COMMAND_CAPABILITIES_EXCHANGE | 257 |
diameter.COMMAND_RE_AUTH | 258 |
diameter.COMMAND_AA | 265 |
diameter.COMMAND_EAP | 268 |
diameter.COMMAND_ACCOUNTING | 271 |
diameter.COMMAND_ABORT_SESSION | 274 |
diameter.COMMAND_SESSION_TERMINATION | 275 |
diameter.COMMAND_DEVICE_WATCHDOG | 280 |
diameter.COMMAND_DISCONNECT_PEER | 282 |
| Authentication request constant | Value |
|---|---|
diameter.AUTH_REQUEST_TYPE_AUTHENTICATE_ONLY | 1 |
diameter.AUTH_REQUEST_TYPE_AUTHORIZE_ONLY | 2 |
diameter.AUTH_REQUEST_TYPE_AUTHORIZE_AUTHENTICATE | 3 |
Request and answer messages share the same command code.
conditions all {
diameter.application_id == diameter.APPLICATION_EAP;
diameter.command_code == diameter.COMMAND_EAP;
}
Server configuration statements such as application_id and
auth_application_id accept numeric literals. These constants are available
where policy expressions are supported.
Authorization sessions
Locally answered NASREQ and Diameter EAP authorization requests retain an in-memory session after a successful answer. The session is scoped to the server, local node, application, and Session-Id, and bound to the authenticated peer and origin and destination identities. NASREQ also binds User-Name. A foreign owner receives DIAMETER_UNKNOWN_SESSION_ID before policy execution.
Auth-Session-State in the answer determines whether state is retained. Its absence means STATE_MAINTAINED. When policy omits the answer AVP and the request asks for NO_STATE_MAINTAINED, the answer explicitly selects NO_STATE_MAINTAINED. Authentication-only successes do not create authorization sessions. Native proxy forwarding does not create local authorization state.
Set answer timers through diameter.answer.Authorization-Lifetime,
diameter.answer.Auth-Grace-Period, and diameter.answer.Session-Timeout.
All three use integer seconds. Authorization-Lifetime zero requires immediate
reauthorization; an absent value or 4294967295 imposes no reauthorization deadline.
Grace defaults to zero. Resources expire at the lifetime plus grace deadline or
Session-Timeout, whichever is earlier. An absent or zero Session-Timeout means
unlimited service. A positive Session-Timeout must not be smaller than an
explicit finite Authorization-Lifetime. A requested Authorization-Lifetime is
used when policy omits it; policy cannot exceed the requested maximum. A positive
lifetime adds Re-Auth-Request-Type when policy omitted it, selecting authorization
only for an authorization-only request and combined authentication/authorization
otherwise.
Reauthorization uses normal policies and refreshes the session on success. A terminal authentication or authorization failure removes the observed session. A successful Session-Termination-Answer removes the session and invalidates pending initial authentication. Configure a policy handler for Session-Termination-Request to authorize that operation. STR may omit User-Name, but must retain the peer and origin identities. Late answers cannot recreate a terminated session or remove a newer authorization.
Read diameter.session_active and diameter.session_reauthorization_due in
policies. These booleans describe the session at the time of the read, before the
current answer updates it. Due sessions remain active during their grace period.
Expiry is inclusive at the exact monotonic deadline. A one-second maintenance
sweep reclaims idle records; policy reads and session transitions enforce expiry
without waiting for that sweep.
Set maximum_authorization_sessions in resource_limits to limit concurrent
local authorization sessions. The default is 100000, and the value must be a
positive integer. Pending initial authentication sessions have the same count
limit. Capacity exhaustion returns DIAMETER_UNABLE_TO_COMPLY without evicting
another live session.
Sessions survive policy and dictionary reloads when local nodes, peers, and resource limits are unchanged. Changing those settings starts an isolated store. Sessions are lost when the server is removed or the process restarts; they are not shared between processes. Server-initiated reauthorization and abort requests and RADIUS CoA/Disconnect interworking are not provided by this lifecycle store.