27 RCSID(
"$Id: 2c31f0cda126ffa7b0a19de62eb0b712c6f6743f $")
29 #include <freeradius-devel/util/debug.h>
30 #include <freeradius-devel/util/syserror.h>
32 #include <freeradius-devel/util/socket.h>
33 #include <freeradius-devel/util/udp_queue.h>
48 struct sockaddr_storage sockaddr;
76 void *rctx = entry->
rctx;
107 if (fd < 0)
return NULL;
117 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on,
sizeof(on)) < 0) {
133 if (
config->send_buff_is_set) {
138 if (opt < 65536) opt = 65536;
139 if (opt > (1 << 30)) opt = 1<<30;
141 (void) setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt,
sizeof(
int));
155 (void) setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt,
sizeof(
int));
200 void *rctx = entry->rctx;
208 rcode = sendto(uq->
fd, entry->packet, entry->packet_len, 0, (
struct sockaddr *) &entry->sockaddr, entry->socklen);
210 void *rctx = entry->rctx;
218 if (errno == EINTR) {
223 #if EWOULDBLOCK != EAGAIN
224 if (!((errno == EWOULDBLOCK) || (errno == EAGAIN)))
return;
226 if (errno != EWOULDBLOCK)
return;
263 struct sockaddr_storage sockaddr;
269 if (!packet_len || !port)
return 1;
276 rcode = sendto(uq->
fd, packet, packet_len, 0, (
struct sockaddr *) &sockaddr, socklen);
277 if (rcode >= 0)
return 1;
280 if (errno == EINTR) {
285 #if EWOULDBLOCK != EAGAIN
286 if (!((errno == EWOULDBLOCK) || (errno == EAGAIN)))
return -1;
288 if (errno != EWOULDBLOCK)
return -1;
311 if (!entry)
return -1;
322 .packet_len = packet_len,
325 memcpy(entry->
packet, packet, packet_len);
fr_dcursor_eval_t void const * uctx
#define fr_dlist_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
static unsigned int fr_dlist_num_elements(fr_dlist_head_t const *head)
Return the number of elements in the dlist.
static int fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the tail of a list.
static void * fr_dlist_remove(fr_dlist_head_t *list_head, void *ptr)
Remove an item from the list.
#define fr_dlist_foreach_safe(_list_head, _type, _iter)
Iterate over the contents of a list allowing for removals.
Head of a doubly linked list.
Entry in a doubly linked list.
#define fr_event_fd_insert(...)
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
int fr_ipaddr_to_sockaddr(struct sockaddr_storage *sa, socklen_t *salen, fr_ipaddr_t const *ipaddr, uint16_t port)
Convert our internal ip address representation to a sockaddr.
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.
static const conf_parser_t config[]
int fr_socket_server_udp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *port_name, bool async)
Open an IPv4/IPv6 unconnected UDP socket.
int fr_socket_bind(int sockfd, char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port)
Bind a UDP/TCP v4/v6 socket to a given ipaddr src port, and interface.
#define fr_time()
Allow us to arbitrarily manipulate time.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_time_gteq(_a, _b)
#define fr_time_add(_a, _b)
Add a time/time delta together.
static void udp_queue_writable(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx)
If the socket is writable, then flush packets until either it returns EWOULDBLOCK,...
bool blocked
are we blocked?
int fr_udp_queue_write(TALLOC_CTX *ctx, fr_udp_queue_t *uq, uint8_t const *packet, size_t packet_len, fr_ipaddr_t const *ipaddr, int port, void *rctx)
Write packet to socket, OR enqueue it if we get EAGAIN.
static int _udp_queue_free(fr_udp_queue_t *uq)
struct sockaddr_storage sockaddr
fr_dlist_head_t queue
list of queued packets to write, ordered by time
fr_udp_queue_t * fr_udp_queue_alloc(TALLOC_CTX *ctx, fr_udp_queue_config_t const *config, fr_event_list_t *el, fr_udp_queue_resume_t resume)
Allocate an outbound UDP queue.
fr_udp_queue_resume_t resume
static int _udp_queue_entry_free(fr_udp_queue_entry_t *entry)
fr_udp_queue_config_t const * config
configuration
uint32_t max_queued_packets
maximum queued packets
void(* fr_udp_queue_resume_t)(bool written, void *rctx)
struct fr_udp_queue_s fr_udp_queue_t
fr_time_delta_t max_queued_time
maximum time a packet can be queued
static fr_event_list_t * el
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.