26RCSID(
"$Id: 23c34a82cf085a4570b3d63f01ab92fa520b588e $")
33#include <freeradius-devel/util/udp.h>
34#include <freeradius-devel/util/syserror.h>
64 if (ret != 0)
return ret;
76 request->
id = reply->
id;
101#define FNV_MAGIC_PRIME (0x01000193)
102#define MAX_SOCKETS (256)
103#define SOCKOFFSET_MASK (MAX_SOCKETS - 1)
104#define SOCK2OFFSET(_sockfd) ((_sockfd * FNV_MAGIC_PRIME) & SOCKOFFSET_MASK)
135 }
while (i != start);
163 if (!pl)
return false;
166 if (!ps)
return false;
177 if (!pl)
return false;
180 if (!ps)
return false;
198 struct sockaddr_storage src;
199 socklen_t sizeof_src;
202 if (!pl || !dst_ipaddr || (dst_ipaddr->
af == AF_UNSPEC)) {
222 }
while (i != start);
229 memset(ps, 0,
sizeof(*ps));
232 ps->
socket.
type = (proto == IPPROTO_TCP) ? SOCK_STREAM : SOCK_DGRAM;
241 sizeof_src =
sizeof(src);
242 memset(&src, 0, sizeof_src);
243 if (getsockname(
sockfd, (
struct sockaddr *) &src, &sizeof_src) < 0) {
253 ps->
socket.inet.dst_ipaddr = *dst_ipaddr;
254 ps->
socket.inet.dst_port = dst_port;
257 if (ps->
src_any < 0)
return false;
260 if (ps->
dst_any < 0)
return false;
262 if (proto == IPPROTO_TCP) {
264 if (ps->
buffer)
return false;
297 if (!pl)
return NULL;
321 if (!pl || !request)
return 0;
328 if (!pl || !request)
return 0;
343 if (!pl || !reply)
return NULL;
346 if (!ps)
return NULL;
358 my_request.
socket.inet.dst_ipaddr = reply->
socket.inet.src_ipaddr;
359 my_request.
socket.inet.dst_port = reply->
socket.inet.src_port;
369 my_request.
id = reply->
id;
370 request = &my_request;
378 if (!pl || !request)
return false;
413 int i, j, k, fd, id, start_i, start_j, start_k;
418 if ((request->
socket.inet.dst_ipaddr.
af == AF_UNSPEC) ||
419 (request->
socket.inet.dst_port == 0)) {
427 if (request->
socket.inet.src_ipaddr.
af == AF_UNSPEC) {
428 memset(&request->
socket.inet.src_ipaddr, 0,
sizeof(request->
socket.inet.src_ipaddr));
467 if (request->
id >= 0 && request->
id < 256)
471 type = (proto == IPPROTO_TCP) ? SOCK_STREAM : SOCK_DGRAM;
473#define ID_i ((i + start_i) & SOCKOFFSET_MASK)
496 if (ps->
socket.inet.src_ipaddr.
af != request->
socket.inet.dst_ipaddr.
af)
continue;
501 if ((ps->
socket.inet.dst_port != 0) &&
502 (ps->
socket.inet.dst_port != request->
socket.inet.dst_port))
continue;
507 if ((request->
socket.inet.src_port != 0) &&
508 (ps->
socket.inet.src_port != request->
socket.inet.src_port))
continue;
515 if (src_any && (ps->
socket.inet.src_ipaddr.
af == AF_INET) &&
516 (((ps->
socket.inet.src_ipaddr.addr.v4.s_addr >> 24) & 0xff) == 127) &&
517 (((request->
socket.inet.dst_ipaddr.addr.v4.s_addr >> 24) & 0xff) != 127))
continue;
523 if (ps->
src_any && !src_any)
continue;
530 if (!ps->
src_any && !src_any &&
532 &ps->
socket.inet.src_ipaddr) != 0))
continue;
546 &ps->
socket.inet.dst_ipaddr) != 0))
continue;
557 if ((ps->
id[(
id >> 3) & 0x1f] & (1 << (
id & 0x07))) != 0)
continue;
559 ps->
id[(
id >> 3) & 0x1f] |= (1 << (
id & 0x07));
568#define ID_j ((j + start_j) & 0x1f)
569 for (j = 0; j < 32; j++) {
570 if (ps->
id[
ID_j] == 0xff)
continue;
574#define ID_k ((k + start_k) & 0x07)
575 for (k = 0; k < 8; k++) {
576 if ((ps->
id[
ID_j] & (1 <<
ID_k)) != 0)
continue;
605 request->
socket.inet.src_ipaddr = ps->
socket.inet.src_ipaddr;
606 request->
socket.inet.src_port = ps->
socket.inet.src_port;
612 if (pctx) *pctx = ps->
ctx;
622 ps->
id[(request->
id >> 3) & 0x1f] &= ~(1 << (request->
id & 0x07));
626 request->
socket.inet.src_ipaddr.
af = AF_UNSPEC;
627 request->
socket.inet.src_port = 0;
641 if (!pl || !request)
return false;
646 if (!ps)
return false;
648 ps->
id[(request->
id >> 3) & 0x1f] &= ~(1 << (request->
id & 0x07));
654 request->
socket.inet.src_ipaddr.
af = AF_UNSPEC;
655 request->
socket.inet.src_port = 0;
664 if (!pl || !set)
return 0;
676 if (maxfd < 0)
return -1;
692 if (!pl || !set)
return 0;
710 &ps->
used, max_attributes, require_message_authenticator);
711 if (rcode <= 0)
return rcode;
716 if (!packet)
return -1;
718 packet->
data = talloc_memdup(packet, ps->
buffer, rcode);
727 if (ps->
used == (
size_t) rcode) {
738 max_attributes, require_message_authenticator);
740 if (!packet)
continue;
763 if (num_elements < pl->num_outgoing)
return 0;
#define CMP_RETURN(_a, _b, _field)
Return if the comparison is not 0 (is unequal)
int fr_ipaddr_from_sockaddr(fr_ipaddr_t *ipaddr, uint16_t *port, struct sockaddr_storage const *sa, socklen_t salen)
Convert sockaddr to our internal ip address representation.
int fr_ipaddr_is_inaddr_any(fr_ipaddr_t const *ipaddr)
Determine if an address is the INADDR_ANY address for its address family.
int8_t fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
Compare two ip addresses.
fr_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
fr_packet_t * fr_packet_list_find_byreply(fr_packet_list_t *pl, fr_packet_t *reply)
uint32_t fr_packet_list_num_incoming(fr_packet_list_t *pl)
void fr_packet_list_free(fr_packet_list_t *pl)
uint32_t fr_packet_list_num_outgoing(fr_packet_list_t *pl)
int8_t fr_packet_cmp(void const *a_v, void const *b_v)
static fr_packet_socket_t * fr_socket_find(fr_packet_list_t *pl, int sockfd)
bool fr_packet_list_socket_del(fr_packet_list_t *pl, int sockfd)
fr_packet_socket_t sockets[MAX_SOCKETS]
bool fr_packet_list_socket_freeze(fr_packet_list_t *pl, int sockfd)
int fr_packet_list_recv(fr_packet_list_t *pl, fd_set *set, TALLOC_CTX *ctx, fr_packet_t **packet_p, uint32_t max_attributes, bool require_message_authenticator)
fr_packet_t * fr_packet_list_find(fr_packet_list_t *pl, fr_packet_t *request)
#define SOCK2OFFSET(_sockfd)
fr_packet_list_t * fr_packet_list_create(int alloc_id)
bool fr_packet_list_socket_thaw(fr_packet_list_t *pl, int sockfd)
bool fr_packet_list_id_alloc(fr_packet_list_t *pl, int proto, fr_packet_t *request, void **pctx)
bool fr_packet_list_yank(fr_packet_list_t *pl, fr_packet_t *request)
bool fr_packet_list_socket_add(fr_packet_list_t *pl, int sockfd, int proto, fr_ipaddr_t *dst_ipaddr, uint16_t dst_port, void *ctx)
void fr_request_from_reply(fr_packet_t *request, fr_packet_t const *reply)
bool fr_packet_list_insert(fr_packet_list_t *pl, fr_packet_t *request)
uint32_t fr_packet_list_num_elements(fr_packet_list_t *pl)
int fr_packet_list_fd_set(fr_packet_list_t *pl, fd_set *set)
bool fr_packet_list_id_free(fr_packet_list_t *pl, fr_packet_t *request, bool yank)
Constants for the RADIUS protocol.
#define RADIUS_HEADER_LENGTH
fr_packet_t * fr_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_message_authenticator)
Receive UDP client requests, and fill in the basics of a fr_packet_t structure.
#define RADIUS_MAX_PACKET_SIZE
uint32_t fr_rand(void)
Return a 32-bit random number.
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
The main red black tree structure.
fr_aka_sim_id_type_t type
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
ssize_t fr_tcp_read_packet(int sockfd, uint8_t *buffer, size_t size, size_t *total, uint32_t max_attributes, bool require_message_authenticator)
fr_socket_t socket
This packet was received on.
int id
Packet ID (used to link requests/responses).
uint8_t * data
Packet data (body).
size_t data_len
Length of packet data.
int af
AF_INET, AF_INET6, or AF_UNIX.
int fd
File descriptor if this is a live socket.
int type
SOCK_STREAM, SOCK_DGRAM, etc.
static void fr_socket_addr_swap(fr_socket_t *dst, fr_socket_t const *src)
Swap src/dst information of a fr_socket_t.
Holds information necessary for binding or connecting to a socket.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)