Radcli library 2.0.0
A simple radius library -- new API reference
Loading...
Searching...
No Matches
RADIUS messaging

Building a radcli_request, exchanging it with the server, and reading back the reply's code and attributes – or radcli_aaa() for the send-and-wait-for-reply case in one call. More...

Typedefs

typedef enum radcli_code radcli_code
typedef enum radcli_error_cause radcli_error_cause
typedef enum radcli_result radcli_result
typedef struct radcli_request_st radcli_request
typedef enum radcli_request_flags radcli_request_flags

Enumerations

enum  radcli_code {
  RADCLI_CODE_ACCESS_REQUEST = 1 , RADCLI_CODE_ACCESS_ACCEPT = 2 , RADCLI_CODE_ACCESS_REJECT = 3 , RADCLI_CODE_ACCOUNTING_REQUEST = 4 ,
  RADCLI_CODE_ACCOUNTING_RESPONSE = 5 , RADCLI_CODE_ACCESS_CHALLENGE = 11 , RADCLI_DISCONNECT_REQUEST = 40 , RADCLI_DISCONNECT_ACK = 41 ,
  RADCLI_DISCONNECT_NAK = 42 , RADCLI_COA_REQUEST = 43 , RADCLI_COA_ACK = 44 , RADCLI_COA_NAK = 45
}
enum  radcli_error_cause {
  RADCLI_ERROR_RESIDUAL_SESSION_CONTEXT_REMOVED = 201 , RADCLI_ERROR_INVALID_EAP_PACKET = 202 , RADCLI_ERROR_UNSUPPORTED_ATTRIBUTE = 401 , RADCLI_ERROR_MISSING_ATTRIBUTE = 402 ,
  RADCLI_ERROR_NAS_IDENTIFICATION_MISMATCH = 403 , RADCLI_ERROR_INVALID_REQUEST = 404 , RADCLI_ERROR_UNSUPPORTED_SERVICE = 405 , RADCLI_ERROR_UNSUPPORTED_EXTENSION = 406 ,
  RADCLI_ERROR_INVALID_ATTRIBUTE_VALUE = 407 , RADCLI_ERROR_ADMINISTRATIVELY_PROHIBITED = 501 , RADCLI_ERROR_REQUEST_NOT_ROUTABLE = 502 , RADCLI_ERROR_SESSION_CONTEXT_NOT_FOUND = 503 ,
  RADCLI_ERROR_SESSION_CONTEXT_NOT_REMOVABLE = 504 , RADCLI_ERROR_OTHER_PROXY_PROCESSING_ERROR = 505 , RADCLI_ERROR_RESOURCES_UNAVAILABLE = 506 , RADCLI_ERROR_REQUEST_INITIATED = 507 ,
  RADCLI_ERROR_MULTIPLE_SESSION_SELECTION_UNSUPPORTED = 508 , RADCLI_ERROR_LOCATION_INFO_REQUIRED = 509 , RADCLI_ERROR_RESPONSE_TOO_BIG = 601
}
enum  radcli_result { RADCLI_OK = 0 , RADCLI_ERROR = -1 , RADCLI_TIMEOUT = -2 , RADCLI_AGAIN = -3 }
enum  radcli_request_flags { RADCLI_REQUEST_NONE = 0 , RADCLI_REQUEST_SENDONLY = 1 << 0 }

Functions

int radcli_aaa (radcli_ctx *ctx, radcli_code code, const radcli_avp_list *send, radcli_code *out_code, radcli_avp_list **out_attrs)
 Perform an authentication or accounting exchange with Acct-Delay-Time autofill and fail-over across every configured server.
radcli_request * radcli_request_new (radcli_ctx *ctx, radcli_code code, const radcli_avp_list *send)
 Create a request to send.
int radcli_request_perform (radcli_request *r, unsigned flags)
 Send a request, optionally waiting for the reply.
int radcli_request_done (radcli_request *r)
 Report r's outcome once radcli_ctx_dispatch() has resolved it – a pure state query, performing no I/O of its own.
radcli_code radcli_request_code (const radcli_request *r)
 Return the reply's RADIUS code.
const radcli_avp_list * radcli_request_attrs (const radcli_request *r)
 Return the reply's decoded attributes.
const char * radcli_request_server (const radcli_request *r)
 Return the name of the server a request was (or will be) sent to.
void radcli_request_free (radcli_request *r)
 Release a request.

Detailed Description

Building a radcli_request, exchanging it with the server, and reading back the reply's code and attributes – or radcli_aaa() for the send-and-wait-for-reply case in one call.

Typedef Documentation

◆ radcli_request

typedef struct radcli_request_st radcli_request

Definition at line 580 of file radcli2.h.

Enumeration Type Documentation

◆ radcli_code

RADIUS packet codes (RFC 2865 SS3).

Used both to construct a #radcli_request (RADCLI_CODE_ACCESS_REQUEST or RADCLI_CODE_ACCOUNTING_REQUEST) and to read back the code of the reply a successful radcli_request_perform() received, via radcli_request_code(). These are fixed protocol constants and match radcli.h's PW_* constants of the same name; radcli2.h does not include radcli.h (see this header's top comment), so they are restated here rather than shared.

Definition at line 506 of file radcli2.h.

◆ radcli_error_cause

RADIUS Error-Cause (attribute 101) values, per the IANA registry (RFC 5176 SS3.5, RFC 5580 SS3.3, RFC 7930 SS4).

Passed to radcli_dae_reply_error() to build a Disconnect-NAK/CoA-NAK. Matches etc/dictionary's Error-Cause VALUEs; restated here as typed constants for callers that build a NAK without touching the dictionary.

Definition at line 531 of file radcli2.h.

◆ radcli_request_flags

Flags for radcli_request_perform().

Enumerator
RADCLI_REQUEST_SENDONLY 

Transmit r once and return once the packet is handed to the network, without blocking for a reply. Two uses:

  • Fire-and-forget: call radcli_request_free() without ever calling radcli_ctx_dispatch(). A best-effort notification whose outcome the caller does not act on, e.g. an accounting stop sent during shutdown; radcli.h's rc_acct_async() is the equivalent call in the legacy API.
  • Poll-driven async request/reply: read the reply later with radcli_request_done(), driven by the caller's own radcli_ctx_get_poll()/radcli_ctx_dispatch() loop, e.g. from an application built around an event loop that cannot afford to block a thread on radcli_request_perform(r, RADCLI_REQUEST_NONE).

Either way, only the first address the server name resolves to is tried – no DNS-level fail-over, unlike RADCLI_REQUEST_NONE – but retransmission to that one address, up to the configured retry count, still happens for the poll-driven case.

Definition at line 583 of file radcli2.h.

◆ radcli_result

Outcome of radcli_request_perform().

RADCLI_OK is always 0 and every failure outcome is a distinct negative value. Test for success with result == RADCLI_OK; treat every other value – including ones not listed here yet – as failure. Do not test for a specific non-OK value (e.g. != RADCLI_ERROR) and assume anything else means success: that pattern silently treats an unhandled outcome (such as RADCLI_TIMEOUT) as a validated reply.

Enumerator
RADCLI_OK 

A validated reply was received; see radcli_request_code() for which one.

RADCLI_ERROR 

Malformed input, a verification failure, or no server configured.

RADCLI_TIMEOUT 

No reply from any address the server name resolved to.

RADCLI_AGAIN 

Only ever returned by radcli_request_done(): still waiting for a reply. Drive it via radcli_ctx_get_poll()/radcli_ctx_dispatch() and call radcli_request_done() again. Never returned by radcli_request_perform() itself.

Definition at line 562 of file radcli2.h.

Function Documentation

◆ radcli_aaa()

int radcli_aaa ( radcli_ctx * ctx,
radcli_code code,
const radcli_avp_list * send,
radcli_code * out_code,
radcli_avp_list ** out_attrs )

Perform an authentication or accounting exchange with Acct-Delay-Time autofill and fail-over across every configured server.

The new API's counterpart to radcli.h's rc_aaa()/rc_auth()/rc_acct(), layered on top of the single-server radcli_request_new()/_perform() building block the same way lib/aaa_ctx.c layers over rc_auth() today – added as a separate wrapper rather than as an extension of radcli_request_perform(), so that function's single-server contract is untouched. Unlike radcli_request_new(), which uses only the first configured "authserver"/"acctserver" entry (REQ-NET2-INIT-003), this tries every configured entry in order, moving to the next on a timeout or unreachable-network result, exactly as rc_aaa()/rc_aaa_ctx() do.

Unlike the legacy rc_aaa(), this has no NAS-Port autofill parameters: NAS-Port is a value the caller already knows before calling, exactly like any other attribute (NAS-IP-Address, Called-Station-Id, ...), so it belongs in send via radcli_avp_add_uint32_by_num(), not as a special-cased parameter here. Acct-Delay-Time remains the one attribute radcli_aaa() computes itself, since only it can see the fail-over timing: if code is #RADCLI_CODE_ACCOUNTING_REQUEST, an Acct-Delay-Time attribute is always added (replacing any in send), measuring elapsed time from the first attempt – continuing to accumulate across a fail-over retry, not resetting – folding in any Acct-Delay-Time already in send as an initial offset, matching rc_fill_acct_pairs()'s (lib/buildreq.c) semantics.

Parameters
ctxa context with configuration loaded.
codeRADCLI_CODE_ACCESS_REQUEST or RADCLI_CODE_ACCOUNTING_REQUEST.
sendthe attributes to send; copied in per attempt – send may be freed or reused by the caller immediately after this call returns.
out_codeif non-NULL, receives the final reply's RADIUS code on RADCLI_OK.
out_attrsif non-NULL, receives the final reply's decoded attributes on RADCLI_OK (owned by the caller, free with radcli_avp_list_free()); left unset otherwise. Pass NULL for an Accounting-Request caller uninterested in the (typically empty) reply.
Returns
RADCLI_OK if any configured server produced a validated reply (check out_code for Access-Accept/Access-Reject/Access-Challenge), RADCLI_TIMEOUT if every configured server timed out or was unreachable, RADCLI_ERROR on failure (NULL ctx/send, an invalid code, no server configured for that code's type, or an allocation/encoding failure).

Definition at line 160 of file aaa2.c.

◆ radcli_request_attrs()

const radcli_avp_list * radcli_request_attrs ( const radcli_request * r)

Return the reply's decoded attributes.

Parameters
ra request radcli_request_perform() returned RADCLI_OK for.
Returns
the attribute list, owned by r and valid for its lifetime; NULL if r has not yet been successfully performed, or the reply carried no attributes.

Definition at line 486 of file request.c.

◆ radcli_request_code()

radcli_code radcli_request_code ( const radcli_request * r)

Return the reply's RADIUS code.

Parameters
ra request radcli_request_perform() returned RADCLI_OK for.
Returns
the code (e.g. RADCLI_CODE_ACCESS_ACCEPT), or 0 if r has not yet been successfully performed.

Definition at line 473 of file request.c.

◆ radcli_request_done()

int radcli_request_done ( radcli_request * r)

Report r's outcome once radcli_ctx_dispatch() has resolved it – a pure state query, performing no I/O of its own.

Since REQ-NET2-SEND-016/013, r shares ctx's request socket/session with every other concurrently in-flight RADCLI_REQUEST_SENDONLY request, and radcli_ctx_dispatch() is what actually drives it to completion (draining replies, retransmitting, expiring on timeout) – this call never performs I/O itself, so calling it any number of times between radcli_ctx_dispatch() calls is free.

Parameters
ra request radcli_request_perform(r, RADCLI_REQUEST_SENDONLY) returned RADCLI_OK for.
Returns
RADCLI_AGAIN if still waiting (call radcli_ctx_get_poll()/ radcli_ctx_dispatch() and try again), RADCLI_OK if a validated reply was received (read it with radcli_request_code()/_attrs(), same as radcli_request_perform()), RADCLI_TIMEOUT if retries are exhausted, or RADCLI_ERROR on failure or if r was never sent with RADCLI_REQUEST_SENDONLY.

Definition at line 444 of file request.c.

◆ radcli_request_free()

void radcli_request_free ( radcli_request * r)

Release a request.

If r was sent with RADCLI_REQUEST_SENDONLY and radcli_request_done() never reached a terminal result (the fire-and-forget case: nothing ever drives it via radcli_ctx_dispatch() at all), releases r's still-reserved registry slot first – this is what makes fire-and-forget just "perform() then free()", with no separate close step for the caller to remember.

Parameters
ra request from radcli_request_new(); NULL is accepted and ignored.

Definition at line 517 of file request.c.

◆ radcli_request_new()

radcli_request * radcli_request_new ( radcli_ctx * ctx,
radcli_code code,
const radcli_avp_list * send )

Create a request to send.

Reads the destination server, its shared secret, and the timeout/retry counts from ctx's configuration – the same "authserver"/"acctserver", "radius_timeout", and "radius_retries" settings rc_auth()/rc_acct() (radcli.h) use. Unlike rc_auth()/rc_acct(), which fail over across every configured entry, this uses only the first: the new API carries one server per context, with redundancy delegated to DNS (several A/AAAA records for one name, tried in order within the request's timeout by radcli_transport_exchange()) rather than a configured list of distinct servers. A warning is logged, not an error, if more than one entry is configured, so a caller migrating one entry point at a time from the legacy API isn't broken by the leftover entries.

Parameters
ctxa context with configuration loaded.
codeRADCLI_CODE_ACCESS_REQUEST or RADCLI_CODE_ACCOUNTING_REQUEST.
sendthe attributes to send; copied in – send may be freed or reused by the caller immediately after this call returns.
Returns
the new request, or NULL on allocation failure, an invalid code, or if ctx has no server configured for that code's type.

Definition at line 97 of file request.c.

◆ radcli_request_perform()

int radcli_request_perform ( radcli_request * r,
unsigned flags )

Send a request, optionally waiting for the reply.

By default (flags == RADCLI_REQUEST_NONE), sends r and waits for the reply. With RADCLI_REQUEST_SENDONLY, transmits r a single time and returns once the packet is handed to the network, without blocking for a reply – either as a pure fire-and-forget notification whose outcome the caller does not act on (call radcli_request_free() without ever calling radcli_ctx_dispatch(); radcli.h's rc_acct_async() is the equivalent call in the legacy API), or to read the reply later via radcli_request_done(), driven by the caller's own radcli_ctx_get_poll()/radcli_ctx_dispatch() loop (lib/dae.c).

May be called only once per request; construct a new radcli_request for a retransmission with different content.

Parameters
ra request from radcli_request_new().
flagsa bitwise OR of radcli_request_flags.
Returns
with RADCLI_REQUEST_NONE: RADCLI_OK if a validated reply was received (see radcli_request_code() for which one), RADCLI_TIMEOUT if none of the server's addresses replied, or RADCLI_ERROR on failure. With RADCLI_REQUEST_SENDONLY: RADCLI_OK once the packet is handed to the network, RADCLI_ERROR on failure (e.g. name resolution or encoding failed); never RADCLI_TIMEOUT.

Definition at line 364 of file request.c.

◆ radcli_request_server()

const char * radcli_request_server ( const radcli_request * r)

Return the name of the server a request was (or will be) sent to.

Parameters
ra request from radcli_request_new().
Returns
the server name, valid for r's lifetime; never NULL.

Definition at line 497 of file request.c.