Radiator Server Documentation — v10.34.2

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 with DIAMETER_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 answers 3002 instead 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 on diameter.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:

FieldValue
diameter.serverReceiving server name
diameter.local_nodeLocal node name
diameter.peerConfigured incoming peer name
diameter.peer_identityNegotiated remote peer identity
diameter.adjacencyIncoming adjacency name
diameter.destination_realmDestination-Realm AVP, or none
diameter.destination_hostDestination-Host AVP, or none
diameter.origin_realmOrigin-Realm AVP
diameter.origin_hostOrigin-Host AVP
diameter.application_idRequest Application-ID
diameter.command_codeRequest 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 constantValue
diameter.APPLICATION_BASE0
diameter.APPLICATION_NASREQ1
diameter.APPLICATION_BASE_ACCOUNTING3
diameter.APPLICATION_EAP5
Command constantValue
diameter.COMMAND_CAPABILITIES_EXCHANGE257
diameter.COMMAND_RE_AUTH258
diameter.COMMAND_AA265
diameter.COMMAND_EAP268
diameter.COMMAND_ACCOUNTING271
diameter.COMMAND_ABORT_SESSION274
diameter.COMMAND_SESSION_TERMINATION275
diameter.COMMAND_DEVICE_WATCHDOG280
diameter.COMMAND_DISCONNECT_PEER282
Authentication request constantValue
diameter.AUTH_REQUEST_TYPE_AUTHENTICATE_ONLY1
diameter.AUTH_REQUEST_TYPE_AUTHORIZE_ONLY2
diameter.AUTH_REQUEST_TYPE_AUTHORIZE_AUTHENTICATE3

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.