Radiator Server Documentation — v10.33.2

reply

Send RADIUS reply immediately without waiting for pipeline completion

Table of Contents
  • reply
  • Syntax
  • Example: Quick Accounting Acknowledgment
  • Example: Rejecting with reply
  • Example: Post-Reply Quota Enforcement with Dynamic Authorization
  • See Also

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
Navigation
  • accept

  • all

  • any

  • append

  • assert

  • backend

  • challenge

  • chap

  • conditions

  • copy

  • count

  • debug

  • discard

  • each

  • eap

  • error

  • filter

  • first

  • hotp

  • http-basic-auth

  • if

  • ignore

  • invoke

  • log

  • map

  • message

  • modify

  • mschap

  • mschapv2

  • none

  • pap

  • reason

  • reject

  • reject_errors

  • replace

  • reply

  • rewrite

  • set

  • sleep

  • sometimes

  • stop

  • totp

  • trace

  • try

  • until

  • while

  • with

  • yubikey