reply
Send RADIUS reply immediately without waiting for pipeline completion
reply
Sends the RADIUS reply immediately without waiting for the rest of the pipeline to complete. The pipeline continues executing after the reply is sent, allowing post-reply processing such as logging, dynamic authorization requests, or other asynchronous tasks.
Syntax
reply;
Example: Quick Accounting Acknowledgment
@execute {
# Accept the accounting request
accept;
# Send reply immediately to acknowledge the accounting request
reply;
# Do something after the reply has been sent.
}
Example: Rejecting with reply
Since reject action immediately stops the execution pipeline the reject reponse must be set with modify
modify radius.response.code = radius.ACCESS_REJECT;
reply;
This pattern may be used to set any response codes.
Example: Post-Reply Quota Enforcement with Dynamic Authorization
This example demonstrates using reply to acknowledge an Accounting-Request immediately, then performing a quota check and sending a Disconnect-Request to the NAS device's dedicated DynAuth port (UDP/3799) if the quota is exceeded.
The backend configuration connects to the NAS device's DynAuth port:
backends {
radius "DYNAUTH_BACKEND" {
server "NAS_DYNAUTH" {
secret "dynauth_secret";
connect {
protocol udp;
ip 203.0.113.10;
port 3799;
}
}
query "DISCONNECT_USER" {
bindings {
radius.request.code = radius.DISCONNECT_REQUEST;
radius.request.attr.Acct-Session-Id = radius.request.attr.Acct-Session-Id;
}
}
}
}
The handler acknowledges the accounting request, checks the quota in the backend, and disconnects the user if the quota is exceeded:
policy "ACCOUNTING" {
conditions all {
radius.request.code == radius.ACCOUNTING_REQUEST;
}
handler "QUOTA_CHECK" {
conditions all {
radius.request.attr.Acct-Status-Type == radius.dict.Acct-Status-Type.Alive;
}
@execute {
# Acknowledge the Accounting-Request and send the Accounting-Response.
accept;
reply;
# The backend checks the radius.request.attr.Acct-Input-Octets and
# radius.request.attr.Acct-Output-Octets against the user's quota.
backend {
name "SESSION_DATABASE";
query "QUOTA_CHECK";
}
if all {
# Variable set in the backend query mappings
vars.quota_exceeded == true;
} then {
# Quota exceeded. Send a Disconnect-Request to the NAS
# device's dedicated DynAuth port
backend {
name "DYNAUTH_BACKEND";
query "DISCONNECT_USER";
}
# Disconnect-Ack received
}
}
}
}