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
            }
        }
    }
}

See Also

  • accept - Accept a request (sets result without sending reply)
  • stop - Halt pipeline execution
  • ignore - Continue without setting result