26RCSID(
"$Id: ab15108eea328b709a49969ad465ce5d3a491efb $")
 
   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;
 
 
   97#define FNV_MAGIC_PRIME (0x01000193) 
   98#define MAX_SOCKETS (256) 
   99#define SOCKOFFSET_MASK (MAX_SOCKETS - 1) 
  100#define SOCK2OFFSET(_sockfd) ((_sockfd * FNV_MAGIC_PRIME) & SOCKOFFSET_MASK) 
  131        } 
while (i != start);
 
 
  159        if (!pl) 
return false;
 
  162        if (!ps) 
return false;
 
 
  173        if (!pl) 
return false;
 
  176        if (!ps) 
return false;
 
 
  192        struct sockaddr_storage src;
 
  193        socklen_t               sizeof_src;
 
  196        if (!pl || !dst_ipaddr || (dst_ipaddr->
af == AF_UNSPEC)) {
 
  216        } 
while (i != start);
 
  223        memset(ps, 0, 
sizeof(*ps));
 
  225        ps->
socket.
type = (proto == IPPROTO_TCP) ? SOCK_STREAM : SOCK_DGRAM;
 
  234        sizeof_src = 
sizeof(src);
 
  235        memset(&src, 0, sizeof_src);
 
  236        if (getsockname(
sockfd, (
struct sockaddr *) &src, &sizeof_src) < 0) {
 
  246        ps->
socket.inet.dst_ipaddr = *dst_ipaddr;
 
  247        ps->
socket.inet.dst_port = dst_port;
 
  250        if (ps->
src_any < 0) 
return false;
 
  253        if (ps->
dst_any < 0) 
return false;
 
 
  282        if (!pl) 
return NULL;
 
 
  306        if (!pl || !request) 
return 0;
 
 
  313        if (!pl || !request) 
return 0;
 
 
  328        if (!pl || !reply) 
return NULL;
 
  331        if (!ps) 
return NULL;
 
  343                my_request.
socket.inet.dst_ipaddr = reply->
socket.inet.src_ipaddr;
 
  344                my_request.
socket.inet.dst_port = reply->
socket.inet.src_port;
 
  354        my_request.
id = reply->
id;
 
  355        request = &my_request;
 
 
  363        if (!pl || !request) 
return false;
 
 
  398        int i, j, k, fd, id, start_i, start_j, start_k;
 
  403        if ((request->
socket.inet.dst_ipaddr.
af == AF_UNSPEC) ||
 
  404            (request->
socket.inet.dst_port == 0)) {
 
  412        if (request->
socket.inet.src_ipaddr.
af == AF_UNSPEC) {
 
  413                memset(&request->
socket.inet.src_ipaddr, 0, 
sizeof(request->
socket.inet.src_ipaddr));
 
  452        if (request->
id >= 0 && request->
id < 256)
 
  456        type = (proto == IPPROTO_TCP) ? SOCK_STREAM : SOCK_DGRAM;
 
  458#define ID_i ((i + start_i) & SOCKOFFSET_MASK) 
  481                if (ps->
socket.inet.src_ipaddr.
af != request->
socket.inet.dst_ipaddr.
af) 
continue;
 
  486                if ((ps->
socket.inet.dst_port != 0) &&
 
  487                    (ps->
socket.inet.dst_port != request->
socket.inet.dst_port)) 
continue;
 
  492                if ((request->
socket.inet.src_port != 0) &&
 
  493                    (ps->
socket.inet.src_port != request->
socket.inet.src_port)) 
continue;
 
  500                if (src_any && (ps->
socket.inet.src_ipaddr.
af == AF_INET) &&
 
  501                    (((ps->
socket.inet.src_ipaddr.addr.v4.s_addr >> 24) & 0xff) == 127) &&
 
  502                    (((request->
socket.inet.dst_ipaddr.addr.v4.s_addr >> 24) & 0xff) != 127)) 
continue;
 
  508                if (ps->
src_any && !src_any) 
continue;
 
  515                if (!ps->
src_any && !src_any &&
 
  517                                   &ps->
socket.inet.src_ipaddr) != 0)) 
continue;
 
  531                                   &ps->
socket.inet.dst_ipaddr) != 0)) 
continue;
 
  542                        if  ((ps->
id[(
id >> 3) & 0x1f] & (1 << (
id & 0x07))) != 0) 
continue;
 
  544                        ps->
id[(
id >> 3) & 0x1f] |= (1 << (
id & 0x07));
 
  553#define ID_j ((j + start_j) & 0x1f) 
  554                for (j = 0; j < 32; j++) {
 
  555                        if (ps->
id[
ID_j] == 0xff) 
continue;
 
  559#define ID_k ((k + start_k) & 0x07) 
  560                        for (k = 0; k < 8; k++) {
 
  561                                if ((ps->
id[
ID_j] & (1 << 
ID_k)) != 0) 
continue;
 
  590        request->
socket.inet.src_ipaddr = ps->
socket.inet.src_ipaddr;
 
  591        request->
socket.inet.src_port = ps->
socket.inet.src_port;
 
  597                if (pctx) *pctx = ps->
ctx;
 
  607        ps->
id[(request->
id >> 3) & 0x1f] &= ~(1 << (request->
id & 0x07));
 
  611        request->
socket.inet.src_ipaddr.
af = AF_UNSPEC;
 
  612        request->
socket.inet.src_port = 0;
 
 
  626        if (!pl || !request) 
return false;
 
  631        if (!ps) 
return false;
 
  633        ps->
id[(request->
id >> 3) & 0x1f] &= ~(1 << (request->
id & 0x07));
 
  639        request->
socket.inet.src_ipaddr.
af = AF_UNSPEC; 
 
  640        request->
socket.inet.src_port = 0;
 
 
  649        if (!pl || !set) 
return 0;
 
  661        if (maxfd < 0) 
return -1;
 
 
  677        if (!pl || !set) 
return NULL;
 
  692                                                       max_attributes, require_message_authenticator);
 
  693                if (!packet) 
continue;
 
 
  715        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_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)
fr_packet_t * fr_packet_list_recv(fr_packet_list_t *pl, fd_set *set, uint32_t max_attributes, bool require_message_authenticator)
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)
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.
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.
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.
fr_packet_t * fr_tcp_recv(int sockfd, int flags)
fr_socket_t socket
This packet was received on.
int id
Packet ID (used to link requests/responses).
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)