radcli_ctx_get_poll(3)

๐Ÿ“ฆ version 2.0.1, in arch rolling

๐Ÿ’… radcli_ctx_get_poll(3) โ€” the radcli manual, bestie edition ๐ŸŽ€

okay so this is a page from the radcli manual, and it's about radcli_ctx_get_poll โ€” the little function that tells your event loop what to watch. โœจ


๐ŸŒธ NAME ๐ŸŒธ

radcli_ctx_get_poll โ€” reports what to wait for on ctx's behalf, so the caller can run its own event loop. and like, <rainbow>radcli never calls poll()/select()/epoll_wait()` itself ๐Ÿ’… periodt, that's your job, not hers.


โœจ SYNOPSIS โœจ

#include <radcli/>

int radcli_ctx_get_poll(
    radcli_ctx     *ctx,
    struct pollfd  *pfds,
    size_t          max_pfds,
    size_t         *nfds,
    int            *timeout_ms
);

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

so first thing's first: there is no per-object descriptor accessor. like, none. no radcli_dae_fd(), and no per-radcli_request one either โ€” net2.md's REQ-NET2-SEND-013, iykyk. every descriptor this function reports belongs to ctx, not to any one radcli_dae or radcli_request. why does that matter? because a transport that shares one descriptor between dynamic authorization and ordinary requests (which is already true for TLS/DTLS, no cap) would otherwise leave an application holding a watcher on a descriptor that has quietly started meaning something else ๐Ÿ˜ญ the audacity. not on our watch.

For TLS/DTLS, or for a UDP ctx with no active radcli_dae, this is always exactly one descriptor:

  • the session fd (TLS/DTLS โ€” and it's also carrying any in-flight RADCLI_REQUEST_SENDONLY traffic), or
  • the request-registry socket (UDP, REQ-NET2-SEND-016).

A UDP ctx with an active radcli_dae reports a second, independent descriptor for the DAE listener alongside it. and no, you can't merge them โ€” the two are genuinely different local sockets/ports and cannot be combined into one without changing the wire protocol. RADCLI_CTX_MAX_POLLFDS (2) is the maximum this API ever needs. ๐Ÿ‘‘

*timeout_ms folds together every deadline source that applies โ€” DAE queued-work, RadSec watchdog, and any in-flight RADCLI_REQUEST_SENDONLY exchange's own retransmit/timeout โ€” into one single caller-facing value. so the caller never has to compute a min() itself. she did the math so you don't have to ๐Ÿงฎ๐Ÿ’–

โš ๏ธ A descriptor is closed or replaced only during a call the application itself makes (radcli_ctx_dispatch(), radcli_dae_free(), radcli_request_perform(), rc_destroy()) โ€” never asynchronously. but re-query after any of those regardless, because one of them may have replaced it. main character energy means always checking again ๐Ÿซถ

๐Ÿ’œ PARAMETERS ๐Ÿ’œ

  • ctx โ€” a context, with or without an active radcli_dae. either way, she's ready.
  • pfds โ€” filled with up to RADCLI_CTX_MAX_POLLFDS entries (fd/events; revents is left for the caller's poll() to fill in, that part's on you bestie).
  • max_pfds โ€” pfds's capacity. MUST be at least RADCLI_CTX_MAX_POLLFDS. like, mandatory. non-negotiable.
  • nfds โ€” set to how many of pfds were filled in (0 if there's nothing to watch yet ๐Ÿฆ—).
  • timeout_ms โ€” milliseconds after which to call radcli_ctx_dispatch() even without I/O readiness; -1 for "no timeout needed".

๐Ÿ”ฅ RETURN VALUE ๐Ÿ”ฅ

  • 0 on success โœจ
  • -1 if ctx or an out-parameter is NULL, or if max_pfds is too small ๐Ÿ’€

๐ŸŒˆ SEE ALSO ๐ŸŒˆ

radcli_ctx_dispatch(3), radcli_dae_free(3), radcli_dae_new(3), radcli_dae_process(3), radcli_dae_reply(3), radcli_dae_reply_error(3), radcli_dae_reply_to_buffer(3), radcli_dae_req_attrs(3), radcli_dae_req_code(3), radcli_dae_req_framed_ip(3), radcli_dae_req_nas_port(3), radcli_dae_req_session_id(3), radcli_dae_req_user_name(3), radcli_dae_request_free(3), radcli_dae_set_handler(3), radcli_dae_start(3)


that's the whole page, bestie ๐Ÿ“ this drop is from the radcli manual, dated 2026-10-10, and the page is radcli_ctx_get_poll(3) โ€” go be iconic with your event loop ๐Ÿ’–๐Ÿฆ‹๐ŸŒธ

๐Ÿ“ฆ where this page comes from