24 RCSID(
"$Id: bf8f14d3f7eeeb64e386faa04a6dc0d1a2e2e1d0 $")
26 #include <freeradius-devel/io/application.h>
27 #include <freeradius-devel/io/listen.h>
28 #include <freeradius-devel/io/pair.h>
29 #include <freeradius-devel/missing.h>
30 #include <freeradius-devel/server/connection.h>
31 #include <freeradius-devel/util/debug.h>
32 #include <freeradius-devel/util/heap.h>
33 #include <freeradius-devel/util/udp.h>
35 #include <sys/socket.h>
94 char const *module_name;
100 size_t send_buff_actual;
221 if ((h->
active == 0) && (h->
id > 255)) {
236 if (shutdown(h->
fd, SHUT_RDWR) < 0) {
237 DEBUG3(
"%s - Failed shutting down connection %s: %s",
242 DEBUG3(
"%s - Failed closing connection %s: %s",
295 h->
name =
fr_asprintf(h,
"proto tcp local %pV port %u remote %pV port %u",
306 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt,
sizeof(
int)) < 0) {
315 socklen_t socklen =
sizeof(int);
319 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt,
sizeof(
int)) < 0) {
320 WARN(
"%s - Failed setting 'SO_SNDBUF', write performance may be sub-optimal: %s",
325 if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt, &socklen) < 0) {
326 WARN(
"%s - Failed getting 'SO_SNDBUF', write performance may be sub-optimal: %s",
346 WARN(
"%s - Max coalesced outbound data will be %zu bytes", h->
module_name,
364 WARN(
"%s - Modifying 'SO_SNDBUF' value is not supported on this system, "
365 "write performance may be sub-optimal", h->
module_name);
366 WARN(
"%s - Max coalesced outbound data will be %zu bytes", h->
module_name, h->
inst->send_buff_actual);
415 DEBUG4(
"Freeing rlm_tacacs_tcp handle %p", handle);
423 char const *log_prefix,
void *
uctx)
524 if (ret != 0)
return ret;
560 REDEBUG(
"Session ID %08x does not match expected number %08x",
570 if (packet_len < 0) {
571 RPEDEBUG(
"Failed decoding TACACS+ reply packet");
576 RDEBUG(
"Received %s ID %d length %ld reply packet on connection %s",
580 *response_code = code;
609 if (!hdr) hdr = request->request_ctx;
624 inst->secret,
inst->secretlen, request->reply->code, &request->request_pairs);
625 if (packet_len < 0) {
626 RPERROR(
"Failed encoding packet");
663 INFO(
"%s - No replies during 'zombie_period', marking connection %s as dead", h->
module_name, h->
name);
677 ERROR(
"Failed inserting revive timeout for connection");
738 ERROR(
"Failed inserting zombie timeout for connection");
776 REDEBUG(
"Reached maximum_retransmit_duration (%pVs > %pVs), failing request",
781 REDEBUG(
"Reached maximum_retransmit_count (%u > %u), failing request",
806 for (i = 0, queued = 0; (i <
inst->max_send_coalesce); i++) {
840 request = treq->request;
875 RDEBUG(
"Sending %s ID %d length %ld over connection %s",
878 if (
encode(h, request, u) < 0) {
920 if (queued == 0)
return;
936 #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
943 WARN(
"%s - Failed sending data over connection %s: %s",
953 ERROR(
"%s - Failed sending data over connection %s: %s",
967 for (i = 0; i < queued; i++) {
977 request = treq->request;
989 RERROR(
"Failed inserting retransmit timeout for connection");
1011 if (u->
packet < written) {
1012 size_t skip = written - u->
packet;
1050 bool do_read =
true;
1056 size_t available,
used, packet_len;
1073 if (available < h->
inst->max_packet_size) {
1096 if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
return;
1098 ERROR(
"%s - Failed reading response from socket: %s",
1114 if (do_read)
continue;
1129 ERROR(
"%s - Packet is larger than max_packet_size",
1138 if (
used < packet_len) {
1139 if (do_read)
continue;
1151 WARN(
"%s - Ignoring reply with ID %i that arrived too late",
1159 request = treq->request;
1169 slen =
decode(request->reply_ctx, &reply, &code, h, request, u, h->
recv.
read, packet_len);
1182 treq->request->reply->code = code;
1325 case FR_SIGNAL_CANCEL:
1362 if (!r->
treq)
return 0;
1395 u->
code = request->packet->code;
1396 u->
priority = request->async->priority;
1397 u->
recv_time = request->async->recv_time;
1414 RDEBUG(
"All destinations are down - cannot send packet");
1435 .connection_notify = thread_conn_notify,
1437 .request_mux = request_mux,
1446 inst->trunk_conf = &
inst->parent->trunk_conf;
1448 inst->trunk_conf->req_pool_headers = 2;
1451 thread->
el = mctx->
el;
1454 inst->trunk_conf,
inst->parent->name, thread,
false);
1455 if (!thread->
trunk)
return -1;
1460 if (
inst->secret && !*
inst->secret) {
1462 inst->secret = NULL;
1465 if (
inst->secret)
inst->secretlen = talloc_array_length(
inst->secret) - 1;
1477 ERROR(
"IO module cannot be instantiated directly");
1486 if (
inst->max_send_coalesce == 0)
inst->max_send_coalesce = 1;
1491 if (
inst->dst_ipaddr.af == AF_UNSPEC) {
1500 if (
inst->src_ipaddr.af == AF_UNSPEC) {
1501 memset(&
inst->src_ipaddr, 0,
sizeof(
inst->src_ipaddr));
1503 inst->src_ipaddr.af =
inst->dst_ipaddr.af;
1505 if (
inst->src_ipaddr.af == AF_INET) {
1506 inst->src_ipaddr.prefix = 32;
1508 inst->src_ipaddr.prefix = 128;
1512 else if (
inst->src_ipaddr.af !=
inst->dst_ipaddr.af) {
1513 cf_log_err(
conf,
"The 'ipaddr' and 'src_ipaddr' configuration items must "
1514 "be both of the same address family");
1518 if (!
inst->dst_port) {
1530 if (
inst->recv_buff_is_set) {
1535 if (
inst->send_buff_is_set) {
1548 .name =
"tacacs_tcp",
1552 .thread_inst_type =
"udp_thread_t",
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_YIELD
Temporarily pause execution until an event occurs.
#define CMP_PREFER_SMALLER(_a, _b)
Evaluates to +1 for a > b, and -1 for a < b.
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
#define CONF_PARSER_TERMINATOR
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_IS_SET(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct,...
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
#define cf_log_err(_cf, _fmt,...)
@ CONNECTION_STATE_FAILED
Connection has failed.
@ CONNECTION_STATE_CONNECTING
Waiting for connection to establish.
@ CONNECTION_EXPIRED
Connection is being reconnected because it's at the end of its life.
@ CONNECTION_FAILED
Connection is being reconnected because it failed.
Holds a complete set of functions for a connection.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
fr_dcursor_eval_t void const * uctx
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
#define fr_event_fd_insert(...)
void(* fr_event_fd_cb_t)(fr_event_list_t *el, int fd, int flags, void *uctx)
Called when an IO event occurs on a file descriptor.
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
#define fr_event_timer_at(...)
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
#define RPEDEBUG(fmt,...)
#define RHEXDUMP3(_data, _len, _fmt,...)
int fr_event_timer_delete(fr_event_timer_t const **ev_p)
Delete a timer event from the event list.
int fr_event_fd_delete(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Remove a file descriptor from the event loop.
Stores all information relating to an event list.
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
void * rctx
Resume ctx that a module previously set.
fr_event_list_t * el
Event list to register any IO handlers and timers against.
void * thread
Thread instance data.
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
Temporary structure to hold arguments for thread_instantiation calls.
static uint32_t fr_nbo_to_uint32(uint8_t const data[static sizeof(uint32_t)])
Read an unsigned 32bit integer from wire format (big endian)
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
int8_t fr_pair_cmp_by_parent_num(void const *a, void const *b)
Order attributes by their parent(s), attribute number, and tag.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
char * fr_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Special version of asprintf which implements custom format specifiers.
char const * fr_tacacs_packet_names[FR_TACACS_CODE_MAX]
ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *vendor, uint8_t const *buffer, size_t buffer_len, const uint8_t *original, char const *const secret, size_t secret_len, int *code)
Decode a TACACS+ packet.
ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original_packet, char const *secret, size_t secret_len, unsigned int code, fr_pair_list_t *vps)
Encode VPS into a raw TACACS packet.
uint32_t fr_rand(void)
Return a 32-bit random number.
#define RETURN_MODULE_RCODE(_rcode)
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
fr_time_delta_t revive_interval
fr_retry_config_t retry[FR_RADIUS_CODE_MAX]
fr_time_delta_t response_window
fr_time_delta_t zombie_period
uint32_t recv_buff
How big the kernel's receive buffer should be.
uint16_t dst_port
Port of the home server.
fr_ipaddr_t dst_ipaddr
IP of the home server.
uint32_t send_buff
How big the kernel's send buffer should be.
bool send_buff_is_set
Whether we were provided with a send_buf.
fr_ipaddr_t src_ipaddr
IP we open our socket on.
rlm_radius_t * parent
rlm_radius instance.
uint32_t max_packet_size
Maximum packet size.
uint16_t max_send_coalesce
Maximum number of packets to coalesce into one mmsg call.
bool recv_buff_is_set
Whether we were provided with a recv_buf.
module_t common
Common fields to all loadable modules.
Public structure describing an I/O path for an outgoing socket.
fr_time_t last_reply
When we last received a reply.
static int8_t request_prioritise(void const *one, void const *two)
uint16_t src_port
Source port specific to this connection.
rlm_rcode_t rcode
from the transport
uint8_t * write
where we write data to
static bool check_for_zombie(fr_event_list_t *el, trunk_connection_t *tconn, fr_time_t now, fr_time_t last_sent)
See if the connection is zombied.
static fr_dict_attr_t const * attr_packet_type
fr_time_t first_sent
first time we sent a packet since going idle
fr_event_list_t * el
Event list.
bool send_buff_is_set
Whether we were provided with a send_buf.
static int _udp_result_free(udp_result_t *r)
Free a udp_result_t.
size_t secretlen
length of secret
static void request_demux(UNUSED fr_event_list_t *el, trunk_connection_t *tconn, connection_t *conn, UNUSED void *uctx)
static fr_dict_attr_t const * attr_session_id
char const * interface
Interface to bind to.
uint8_t * data
actual data
fr_time_t last_idle
last time we had nothing to do
size_t packet_len
Length of the packet.
static fr_dict_attr_t const * attr_packet_hdr
static void udp_request_reset(udp_handle_t *h, udp_request_t *u)
Clear out any connection specific resources from a udp request.
trunk_connection_t * tconn
trunk connection
rlm_tacacs_tcp_t const * inst
our instance
fr_dict_autoload_t rlm_tacacs_tcp_dict[]
uint8_t id
Last ID assigned to this packet.
fr_ipaddr_t src_ipaddr
Source IP address.
static void conn_error(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, int fd_errno, void *uctx)
Connection errored.
static ssize_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, udp_handle_t *h, request_t *request, udp_request_t *u, uint8_t *data, size_t data_len)
Decode response packet data, extracting relevant information and validating the packet.
static void mod_signal(module_ctx_t const *mctx, UNUSED request_t *request, fr_signal_t action)
static void conn_close(UNUSED fr_event_list_t *el, void *handle, UNUSED void *uctx)
Shutdown/close a file descriptor.
char const * secret
Shared secret.
static void request_conn_release(connection_t *conn, void *preq_to_reset, UNUSED void *uctx)
Clear out anything associated with the handle from the request.
uint32_t session_id
for TACACS+ "security".
uint16_t dst_port
Port of the home server.
fr_time_t recv_time
copied from request->async->recv_time
static fr_dict_t const * dict_tacacs
fr_event_timer_t const * ev
timer for retransmissions
uint32_t send_buff
How big the kernel's send buffer should be.
uint8_t * end
end of the buffer
fr_time_t last_sent
last time we sent a packet.
static void request_free(UNUSED request_t *request, void *preq_to_free, UNUSED void *uctx)
Explicitly free resources associated with the protocol request.
rlm_radius_udp_t const * inst
our instance
static void zombie_timeout(fr_event_list_t *el, fr_time_t now, void *uctx)
Mark a connection dead after "zombie_interval".
uint32_t recv_buff
How big the kernel's receive buffer should be.
size_t send_buff_actual
What we believe the maximum SO_SNDBUF size to be.
struct udp_request_s udp_request_t
rlm_tacacs_io_t rlm_tacacs_tcp
tcp_buffer_t recv
receive buffer
trunk_t * trunk
trunk handler
fr_ipaddr_t src_ipaddr
IP we open our socket on.
uint8_t * packet
Packet we write to the network.
static void revive_timeout(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
Revive a connection after "revive_interval".
char const * name
From IP PORT to IP PORT.
static void request_fail(request_t *request, NDEBUG_UNUSED void *preq, void *rctx, NDEBUG_UNUSED trunk_request_state_t state, UNUSED void *uctx)
Write out a canned failure.
uint32_t max_packet_size
Our max packet size. may be different from the parent.
udp_coalesced_t * coalesced
Outbound coalesced requests.
static unlang_action_t mod_enqueue(rlm_rcode_t *p_result, void **rctx_out, UNUSED void *instance, void *thread, request_t *request)
bool recv_buff_is_set
Whether we were provided with a recv_buf.
uint32_t max_packet_size
Maximum packet size.
fr_time_t mrs_time
Most recent sent time which had a reply.
trunk_request_t * tracking[UINT8_MAX]
all sequential!
rlm_radius_udp_t const * inst
Our module instance.
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Instantiate thread data for the submodule.
static unlang_action_t mod_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Resume execution of the request, returning the rcode set during trunk execution.
trunk_request_t ** coalesced
Outbound coalesced requests.
fr_event_timer_t const * zombie_ev
Zombie timeout.
rlm_tacacs_tcp_t const * inst
Our module instance.
static void request_retry(fr_event_list_t *el, fr_time_t now, void *uctx)
Handle retries.
uint8_t * read
where we read data from
trunk_conf_t * trunk_conf
trunk configuration
tcp_buffer_t send
send buffer
static int _udp_handle_free(udp_handle_t *h)
Free a connection handle, closing associated resources.
static connection_state_t conn_init(void **h_out, connection_t *conn, void *uctx)
Initialise a new outbound connection.
rlm_tacacs_t * parent
rlm_tacacs instance.
char const * module_name
the module that opened the connection
fr_dict_attr_autoload_t rlm_tacacs_tcp_dict_attr[]
static const conf_parser_t module_config[]
static int encode(udp_handle_t *h, request_t *request, udp_request_t *u)
bool outstanding
are we waiting for a reply?
fr_retry_t retry
retransmission timers
fr_ipaddr_t dst_ipaddr
IP of the home server.
static int mod_instantiate(module_inst_ctx_t const *mctx)
uint32_t priority
copied from request->async->priority
static void request_cancel(connection_t *conn, void *preq_to_reset, trunk_cancel_reason_t reason, UNUSED void *uctx)
Remove the request from any tracking structures.
static void request_complete(request_t *request, NDEBUG_UNUSED void *preq, void *rctx, UNUSED void *uctx)
Response has already been written to the rctx at this point.
uint16_t max_send_coalesce
Maximum number of packets to coalesce into one mmsg call.
Static configuration for the module.
Track the handle, which is tightly correlated with the FD.
Connect request_t to local tracking structure.
void connection_signal_reconnect(connection_t *conn, connection_reason_t reason)
Asynchronously signal the connection should be reconnected.
int connection_signal_on_fd(connection_t *conn, int fd)
Setup the connection to change states to connected or failed based on I/O events.
connection_t * connection_alloc(TALLOC_CTX *ctx, fr_event_list_t *el, connection_funcs_t const *funcs, connection_conf_t const *conf, char const *log_prefix, void const *uctx)
Allocate a new connection.
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
module_instance_t const * parent
Parent module's instance (if any).
int fr_socket_client_tcp(char const *ifname, fr_ipaddr_t *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
#define fr_time()
Allow us to arbitrarily manipulate time.
Stores an attribute, a value and various bits of other data.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define FR_TACACS_PACKET_CODE_VALID(_code)
#define FR_MAX_PACKET_SIZE
static int talloc_const_free(void const *ptr)
Free const'd memory.
#define fr_time_gteq(_a, _b)
static int64_t fr_time_unwrap(fr_time_t time)
#define fr_time_wrap(_time)
#define fr_time_lteq(_a, _b)
#define fr_time_delta_ispos(_a)
#define fr_time_eq(_a, _b)
#define fr_time_add(_a, _b)
Add a time/time delta together.
#define fr_time_gt(_a, _b)
#define fr_time_sub(_a, _b)
Subtract one time from another.
#define fr_time_lt(_a, _b)
void trunk_connection_callback_readable(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx)
Standard I/O read function.
void trunk_connection_callback_writable(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx)
Standard I/O write function.
void trunk_request_signal_partial(trunk_request_t *treq)
Signal a partial write.
void trunk_request_signal_fail(trunk_request_t *treq)
Signal that a trunk request failed.
uint64_t trunk_connection_requests_requeue(trunk_connection_t *tconn, int states, uint64_t max, bool fail_bound)
Move requests off of a connection and requeue elsewhere.
trunk_enqueue_t trunk_request_enqueue(trunk_request_t **treq_out, trunk_t *trunk, request_t *request, void *preq, void *rctx)
Enqueue a request that needs data written to the trunk.
trunk_enqueue_t trunk_request_requeue(trunk_request_t *treq)
Re-enqueue a request on the same connection.
int trunk_connection_pop_request(trunk_request_t **treq_out, trunk_connection_t *tconn)
Pop a request off a connection's pending queue.
void trunk_request_signal_cancel(trunk_request_t *treq)
Cancel a trunk request.
void trunk_request_free(trunk_request_t **treq_to_free)
If the trunk request is freed then update the target requests.
trunk_request_t * trunk_request_alloc(trunk_t *trunk, request_t *request)
(Pre-)Allocate a new trunk request
void trunk_connection_signal_inactive(trunk_connection_t *tconn)
Signal a trunk connection cannot accept more requests.
void trunk_request_signal_sent(trunk_request_t *treq)
Signal that the request was written to a connection successfully.
void trunk_request_signal_complete(trunk_request_t *treq)
Signal that a trunk request is complete.
void trunk_connection_signal_reconnect(trunk_connection_t *tconn, connection_reason_t reason)
Signal a trunk connection is no longer viable.
trunk_t * trunk_alloc(TALLOC_CTX *ctx, fr_event_list_t *el, trunk_io_funcs_t const *funcs, trunk_conf_t const *conf, char const *log_prefix, void const *uctx, bool delay_start)
Allocate a new collection of connections.
Associates request queues with a connection.
Main trunk management handle.
#define TRUNK_REQUEST_STATE_ALL
All request states.
trunk_connection_alloc_t connection_alloc
Allocate a new connection_t.
trunk_connection_event_t
What type of I/O events the trunk connection is currently interested in receiving.
@ TRUNK_CONN_EVENT_BOTH
Trunk should be notified if a connection is readable or writable.
@ TRUNK_CONN_EVENT_WRITE
Trunk should be notified if a connection is writable.
@ TRUNK_CONN_EVENT_NONE
Don't notify the trunk on connection state changes.
@ TRUNK_CONN_EVENT_READ
Trunk should be notified if a connection is readable.
trunk_cancel_reason_t
Reasons for a request being cancelled.
@ TRUNK_CANCEL_REASON_REQUEUE
A previously sent request is being requeued.
@ TRUNK_ENQUEUE_IN_BACKLOG
Request should be enqueued in backlog.
trunk_request_state_t
Used for sanity checks and to simplify freeing.
@ TRUNK_REQUEST_STATE_PARTIAL
Some of the request was written to the socket, more of it should be written later.
@ TRUNK_REQUEST_STATE_INIT
Initial state.
@ TRUNK_REQUEST_STATE_PENDING
In the queue of a connection and is pending writing.
@ TRUNK_REQUEST_STATE_SENT
Was written to a socket. Waiting for a response.
Common configuration parameters for a trunk.
I/O functions to pass to trunk_alloc.
static fr_event_list_t * el
void fr_pair_list_sort(fr_pair_list_t *list, fr_cmp_t cmp)
Sort a doubly linked list of fr_pair_ts using merge sort.
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
fr_retry_state_t fr_retry_next(fr_retry_t *r, fr_time_t now)
Initialize a retransmission counter.
void fr_retry_init(fr_retry_t *r, fr_time_t now, fr_retry_config_t const *config)
Initialize a retransmission counter.
fr_time_t start
when we started the retransmission
fr_time_delta_t rt
retransmit interval
uint32_t mrc
Maximum retransmission count.
fr_retry_config_t const * config
master configuration
@ FR_RETRY_MRC
reached maximum retransmission count
@ FR_RETRY_MRD
reached maximum retransmission duration
uint32_t count
number of sent packets
fr_time_delta_t mrd
Maximum retransmission duration.
fr_time_t next
when the next timer should be set
#define fr_box_ipaddr(_val)
#define fr_box_time_delta(_val)