---
name: "radcli_ctx_dispatch"
section: "3"
platform: "linux"
package: "radcli"
version: "2.0.1-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/radcli_ctx_dispatch"
---

# radcli\_ctx\_dispatch(3)

Read what is ready on ctx's descriptor(s), validate it, and invoke the registered handler for anything that passes see radcli\_dae\_set\_handler(). Also: drains any in-flight RADCLI\_REQUEST\_SENDONLY exchange's reply and services its retransmit/ timeout deadline (net2.md's REQ-NET2-SEND-013/016), and, once due, sends the RFC 5997 watchdog on an established RadSec session (watchdog.md's REQ-WATCHDOG-NET-001) all unconditionally, every call, regardless of whether an active radcli\_dae exists at all: this is now the single entry point radcli\_ctx\_get\_poll() drives, for everything ctx owns, not a DAE-only call.

## NAME

radcli\_ctx\_dispatch - Read what is ready on ctx's descriptor(s), validate it, and invoke the registered handler for anything that passes  see radcli\_dae\_set\_handler(). Also: drains any in-flight RADCLI\_REQUEST\_SENDONLY exchange's reply and services its retransmit/ timeout deadline (net2.md's REQ-NET2-SEND-013/016), and, once due, sends the RFC 5997 watchdog on an established RadSec session (watchdog.md's REQ-WATCHDOG-NET-001)  all unconditionally, every call, regardless of whether an active radcli\_dae exists at all: this is now the single entry point radcli\_ctx\_get\_poll() drives, for everything ctx owns, not a DAE-only call.

## SYNOPSIS

```
#include <radcli/>

int radcli_ctx_dispatch(
    radcli_ctx  *ctx
);
```

## DESCRIPTION

On the DAE side specifically, reads exactly one datagram per call (non-blocking), so a burst of requests re-arms the caller's loop rather than starving it, and runs it through process\_packet()'s validation pipeline before ever invoking the registered handler. Every rejection short of "authorized sender" is silent: no reply, no Error-Cause, no log of the secret or either authenticator (REQ-DAE-SEC-009).

Not reentrant: calling this, radcli\_dae\_start(), or radcli\_dae\_free() from within a handler radcli\_ctx\_dispatch() itself invoked is undefined.

## PARAMETERS

- **ctx**

  a context previously reported ready by radcli\_ctx\_get\_poll().

## RETURN VALUE

0 on success (including "nothing was ready"), -1 on failure (e.g. ctx is NULL, or called reentrantly).

## SEE ALSO

[*radcli\_ctx\_get\_poll*(3)](/radcli_ctx_get_poll/3.md), [*radcli\_dae\_free*(3)](/radcli_dae_free/3.md), [*radcli\_dae\_new*(3)](/radcli_dae_new/3.md), [*radcli\_dae\_process*(3)](/radcli_dae_process/3.md), [*radcli\_dae\_reply*(3)](/radcli_dae_reply/3.md), [*radcli\_dae\_reply\_error*(3)](/radcli_dae_reply_error/3.md), [*radcli\_dae\_reply\_to\_buffer*(3)](/radcli_dae_reply_to_buffer/3.md), [*radcli\_dae\_req\_attrs*(3)](/radcli_dae_req_attrs/3.md), [*radcli\_dae\_req\_code*(3)](/radcli_dae_req_code/3.md), [*radcli\_dae\_req\_framed\_ip*(3)](/radcli_dae_req_framed_ip/3.md), [*radcli\_dae\_req\_nas\_port*(3)](/radcli_dae_req_nas_port/3.md), [*radcli\_dae\_req\_session\_id*(3)](/radcli_dae_req_session_id/3.md), [*radcli\_dae\_req\_user\_name*(3)](/radcli_dae_req_user_name/3.md), [*radcli\_dae\_request\_free*(3)](/radcli_dae_request_free/3.md), [*radcli\_dae\_set\_handler*(3)](/radcli_dae_set_handler/3.md), [*radcli\_dae\_start*(3)](/radcli_dae_start/3.md)
