24 RCSID(
"$Id: 26f9eafb631df2439ca2c9fcd322afabca535c37 $")
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/modules.h>
28 #include <freeradius-devel/rad_assert.h>
29 #include <freeradius-devel/process.h>
30 #include <freeradius-devel/protocol.h>
31 #include <freeradius-devel/modpriv.h>
32 #include <freeradius-devel/net.h>
34 #include <freeradius-devel/detail.h>
36 #include <freeradius-devel/udp.h>
38 #ifdef HAVE_SYS_RESOURCE_H
39 # include <sys/resource.h>
50 #ifdef HAVE_SYS_STAT_H
51 # include <sys/stat.h>
54 #ifdef DEBUG_PRINT_PACKET
57 char src[256], dst[256];
62 fprintf(stderr,
"ID %d: %s %d -> %s %d\n", packet->
id,
91 #ifdef WITH_COMMAND_SOCKET
121 if (!listen_ctx) listen_ctx = talloc_init(
"listen_config_t");
123 while (*last != NULL) last = &(*last)->
next;
133 cf_log_err_cs(cs,
"Invalid 'type' specified in listen section");
142 if ((strcmp(value,
"control") != 0) &&
143 (strcmp(value,
"proxy") != 0)) {
144 cf_log_err_cs(cs,
"Listeners of type '%s' MUST be defined in a server.", value);
149 if ((strcmp(value,
"control") == 0) ||
150 (strcmp(value,
"proxy") == 0)) {
151 cf_log_err_cs(cs,
"Listeners of type '%s' MUST NOT be defined in a server.", value);
162 if (!((strcmp(value,
"control") == 0) ||
163 (strcmp(value,
"status") == 0) ||
164 (strcmp(value,
"coa") == 0) ||
165 (strcmp(value,
"detail") == 0) ||
166 (strcmp(value,
"auth") == 0) ||
167 (strcmp(value,
"acct") == 0) ||
168 (strcmp(value,
"auth+acct") == 0))) {
170 static int max_listener = 256;
175 snprintf(buffer,
sizeof(buffer),
"proto_%s", value);
178 cf_log_err_cs(cs,
"Failed loading dynamic protocol %s", value);
186 proto = dlsym(handle, buffer);
189 "Failed linking to protocol %s : %s\n",
196 ERROR(
"Failed to load protocol '%s', it has the wrong version.", value);
206 if (
fr_dict_enum_add(NULL,
"Listen-Socket-Type", value, max_listener++) < 0) {
208 "Failed adding dictionary entry for protocol %s: %s",
221 cf_log_err_cs(cs,
"Failed finding dictionary entry for protocol %s",
227 if (!proto) proto = &master_listen[dv->
value];
248 if (strcmp(value,
"udp") == 0) {
251 }
else if (strcmp(value,
"tcp") == 0) {
255 cf_log_err_cs(cs,
"Unknown transport protocol 'proto = %s'", value);
264 cf_log_err_cs(cs,
"Invalid transport 'proto = %s' for listeners of 'type = %s'",
277 cf_log_err_cs(cs,
"Invalid transport 'proto = %s' for listeners of 'type = %s'",
293 cf_log_err_cs(cs,
"TLS transport is not available in this executable");
300 cf_log_err_cs(cs,
"TLS transport is not available for listeners with 'type = %s",
306 cf_log_err_cs(cs,
"TLS transport is not available for listeners with 'proto = udp'");
347 #ifdef WITH_DYNAMIC_CLIENTS
360 sock = listener->
data;
370 char name[256], buffer[INET6_ADDRSTRLEN];
372 #ifdef WITH_DYNAMIC_CLIENTS
382 static time_t last_printed = 0;
385 if (last_printed == now)
return NULL;
390 listener->
print(listener, name,
sizeof(name));
392 radlog(
L_ERR,
"Ignoring request to %s from unknown client %s port %d"
397 buffer,
sizeof(buffer)), src_port
399 , (sock->
proto == IPPROTO_UDP) ?
"udp" :
"tcp"
405 #ifndef WITH_DYNAMIC_CLIENTS
419 if (client->
dynamic && (src_port != 0)) {
420 # ifdef HAVE_SYS_STAT_H
421 char const *filename;
427 if (client->
lifetime == 0)
return client;
442 # ifdef HAVE_SYS_STAT_H
453 if ((stat(filename, &buf) >= 0) &&
454 (buf.st_mtime < client->
created)) {
476 if (!client)
goto unknown;
499 if (!request)
goto unknown;
505 talloc_free(request);
509 (void) talloc_steal(request, request->
packet);
511 if (!request->
reply) {
512 talloc_free(request);
544 ERROR(
"Virtual-Server %s returned %s, creating dynamic client failed", request->
server,
546 talloc_free(request);
553 DEBUG(
"Virtual-Server %s returned %s, ignoring client", request->
server,
555 talloc_free(request);
563 if (request->
client == client) {
566 created = request->
client;
575 exec_trigger(request, NULL,
"server.client.add",
false);
577 talloc_free(request);
579 if (!created)
goto unknown;
631 #ifdef WITH_ACCOUNTING
715 if (!sock->
packet)
return 0;
743 ERROR(
"Invalid packet from %s port %d, closing socket: %s",
754 DEBUG(
"Client has closed connection");
770 switch (packet->
code) {
777 # ifdef WITH_ACCOUNTING
788 WARN(
"Ignoring Status-Server request due to security configuration");
799 DEBUG(
"Invalid packet code %d sent from client %s port %d : IGNORED",
822 struct sockaddr_storage src;
829 DEBUG2(
" ... new connection request on TCP socket");
831 newfd = accept(listener->
fd, (
struct sockaddr *) &src, &salen);
837 if (errno == EWOULDBLOCK) {
842 DEBUG2(
" ... failed to accept connection");
848 DEBUG2(
" ... unknown address family");
857 &src_ipaddr, src_port)) == NULL) {
873 if (client->tls_required && !listener->tls) {
874 INFO(
"Ignoring connection to TLS socket from non-TLS client");
893 sock = listener->
data;
894 if ((sock->limit.max_connections != 0) &&
895 (sock->limit.max_connections == sock->limit.num_connections)) {
899 INFO(
"Ignoring new connection due to socket max_connections");
904 sock->limit.num_connections++;
912 if (!
this)
return -1;
919 memcpy(this->
data, listener->
data,
sizeof(*sock));
920 memcpy(
this, listener,
sizeof(*
this));
924 sock->parent = listener->
data;
925 sock->other_ipaddr = src_ipaddr;
926 sock->other_port = src_port;
927 sock->client = client;
928 sock->opened = sock->last_packet = time(NULL);
935 memcpy(&sock->limit, &sock->parent->limit,
sizeof(sock->limit));
938 ((sock->limit.idle_timeout == 0) ||
944 ((sock->limit.lifetime == 0) ||
952 this->parent = listener;
954 ERROR(
"Failed inserting TCP socket into parent list.");
957 # ifdef WITH_COMMAND_SOCKET
970 this->recv = dual_tls_recv;
971 this->send = dual_tls_send;
999 if (sock->
proto != IPPROTO_TCP)
return;
1015 # define common_socket_free NULL
1027 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
1028 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
1064 strlcpy(buffer,
"*", bufsize);
1088 if ((sock->
proto == IPPROTO_TCP) &&
1101 strlcpy(buffer,
"*", bufsize);
1122 strlcpy(buffer,
"*", bufsize);
1141 strlcpy(buffer, this->server, bufsize);
1157 #if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1158 char if_name[IFNAMSIZ];
1161 if (!packet)
return;
1172 #
if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1176 received ?
"Received" :
"Sent",
1187 #
if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1195 #
if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1199 received ?
"Received" :
"Sent",
1210 #
if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1259 if (one < two)
return -1;
1260 if (one > two)
return +1;
1277 uint16_t listen_port;
1281 char const *section_name = NULL;
1289 memset(&ipaddr, 0,
sizeof(ipaddr));
1290 ipaddr.
ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1293 if (rcode < 0)
return -1;
1296 if (rcode < 0)
return -1;
1299 if (rcode < 0)
return -1;
1304 memset(&ipaddr, 0,
sizeof(ipaddr));
1305 ipaddr.
af = INADDR_ANY;
1307 ipaddr.
ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
1311 if (rcode < 0)
return -1;
1314 if (rcode < 0)
return -1;
1320 sock->
proto = IPPROTO_UDP;
1324 cf_log_err_cs(cs,
"System does not support the TCP protocol. "
1325 "Delete this line from the configuration file");
1328 char const *
proto = NULL;
1335 if (rcode < 0)
return -1;
1337 if (!proto || strcmp(proto,
"udp") == 0) {
1338 sock->
proto = IPPROTO_UDP;
1340 }
else if (strcmp(proto,
"tcp") == 0) {
1341 sock->
proto = IPPROTO_TCP;
1356 this->tls = tls_server_conf_parse(tls);
1361 # ifdef HAVE_PTRHEAD_H
1380 performance_config);
1381 if (rcode < 0)
return -1;
1383 if (this->synchronous && sock->
max_rate) {
1384 WARN(
"Setting 'max_pps' is incompatible with 'synchronous'. Disabling 'max_pps'");
1388 if (!this->synchronous && this->workers) {
1389 WARN(
"Setting 'workers' requires 'synchronous'. Disabling 'workers'");
1398 if (rcode < 0)
return -1;
1402 "Invalid value for \"max_pps\"");
1408 WARN(
"Setting idle_timeout to 5");
1413 WARN(
"Setting lifetime to 5");
1418 WARN(
"Setting idle_timeout to 0");
1425 if (sock->
proto == IPPROTO_TCP) {
1451 ERROR(
"We have been asked to listen on %s port %d, which is also listed as a "
1452 "home server. This can create a proxy loop",
1470 "No interface name given");
1487 # if defined(SO_BINDTODEVICE) && !defined(SO_BROADCAST)
1489 "System does not support broadcast sockets. Delete this line from the configuration file");
1494 "Broadcast can only be set for DHCP listeners. Delete this line from the configuration file");
1501 "No broadcast value given");
1508 sock->
broadcast = (strcmp(value,
"yes") == 0);
1527 if (rcode < 0)
return -1;
1538 "Failed to find clients %s {...}",
1556 client_cs = server_cs;
1563 if (!client_cs) client_cs = parentcs;
1572 "Failed to load clients for this listen section");
1577 if (sock->
proto == IPPROTO_TCP) {
1585 if (!this->children) {
1586 cf_log_err_cs(cs,
"Failed to create child list for TCP socket.");
1605 if (sock->
interface && sock->pcap_type) {
1606 if (init_pcap(
this) < 0) {
1608 "Error initializing pcap.");
1622 "Error binding to port for %s port %d",
1639 if (request->
reply->
code == 0)
return 0;
1641 #ifdef WITH_UDPFROMTO
1655 RERROR(
"Failed sending reply: %s",
1664 #ifdef WITH_ACCOUNTING
1679 if (request->
reply->
code == 0)
return 0;
1681 # ifdef WITH_UDPFROMTO
1695 RERROR(
"Failed sending reply: %s",
1717 RERROR(
"Failed sending proxied request: %s",
1743 if (rcode < 0)
return 0;
1766 DEBUG(
"Ignoring packet code %d sent to Status-Server port",
1813 if (rcode < 0)
return 0;
1844 WARN(
"Ignoring Status-Server request due to security configuration");
1854 if (
DEBUG_ENABLED)
ERROR(
"Receive - Invalid packet code %d sent to authentication port from "
1855 "client %s port %d", code, client->
shortname, src_port);
1865 talloc_set_name_const(ctx,
"auth_listener_pool");
1879 #if defined(__APPLE__) && defined(WITH_UDPFROMTO)
1897 if (other) listener = other;
1911 #ifdef WITH_ACCOUNTING
1927 if (rcode < 0)
return 0;
1938 &src_ipaddr, src_port)) == NULL) {
1959 WARN(
"Ignoring Status-Server request due to security configuration");
1969 DEBUG(
"Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1980 talloc_set_name_const(ctx,
"acct_listener_pool");
2023 REDEBUG2(
"Cannot proxy to unknown pool %s",
2071 # define WAS_PROXIED (request->proxy)
2073 # define WAS_PROXIED (0)
2086 if (!vp || (vp->vp_length == 0)) {
2087 REDEBUG(
"CoA-Request with Service-Type = Authorize-Only MUST "
2088 "contain a State attribute");
2097 REDEBUG(
"Disconnect-Request MUST NOT contain a Service-Type attribute");
2122 if (proxy_status < 0) {
2213 if (rcode < 0)
return 0;
2222 &src_ipaddr, src_port)) == NULL) {
2246 DEBUG(
"Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
2257 talloc_set_name_const(ctx,
"coa_socket_recv_pool");
2300 switch (packet->
code) {
2306 # ifdef WITH_ACCOUNTING
2323 ERROR(
"Invalid packet code %d sent to a proxy port from home server %s port %d - ID %d : IGNORED",
2335 sock = listener->
data;
2372 switch (packet->
code) {
2378 # ifdef WITH_ACCOUNTING
2387 ERROR(
"Invalid packet code %d sent to a proxy port "
2388 "from home server %s port %d - ID %d : IGNORED",
2461 if (sock->tls_session && sock->tls_session->ssl) {
2462 # ifdef PSK_MAX_IDENTITY_LEN
2463 const char *
identity = SSL_get_psk_identity(sock->tls_session->ssl);
2465 RDEBUG(
"Retrieved psk identity: %s", identity);
2508 #define NO_LISTENER { .name = "undefined", }
2542 #ifdef WITH_ACCOUNTING
2568 #ifdef WITH_COMMAND_SOCKET
2605 char const * pcap_filter;
2607 sock->pcap = fr_pcap_init(
this, sock->
interface, sock->pcap_type);
2617 if (fr_pcap_open(sock->pcap) < 0) {
2623 pcap_filter = sock->pcap_filter_builder(
this);
2626 ERROR(
"Failed building filter for interface %s: %s",
2631 if (fr_pcap_apply_filter(sock->pcap, pcap_filter) < 0) {
2632 ERROR(
"Failed setting filter for interface %s: %s",
2636 DEBUG(
"Using PCAP filter '%s'", pcap_filter);
2639 this->fd = sock->pcap->fd;
2653 char const *port_name = NULL;
2661 switch (this->type) {
2663 port_name =
"radius";
2666 #ifdef WITH_ACCOUNTING
2668 port_name =
"radius-acct";
2684 #ifdef WITH_COMMAND_SOCKET
2692 port_name =
"radius-dynauth";
2698 port_name =
"bootps";
2703 WARN(
"Internal sanity check failed in binding to socket. Ignoring problem");
2715 (sock->
proto == IPPROTO_TCP) &&
2717 cf_log_err_cs(this->cs,
"You must not specify a port for proxy sockets over TCP");
2737 if (sock->
proto == IPPROTO_TCP) {
2745 #
if defined(WITH_PROXY) && defined(WITH_TLS)
2754 DEBUG4(
"[FD XX] Opening socket -- socket(%s, %s, 0)",
2766 this->print(
this, buffer,
sizeof(buffer));
2777 DEBUG4(
"[FD %i] Setting recv_buff -- setsockopt(%i, SOL_SOCKET, SO_RCVBUF, %i, %zu)", this->fd,
2778 this->fd, sock->
recv_buff,
sizeof(
int));
2779 if (setsockopt(this->fd, SOL_SOCKET, SO_RCVBUF, (
int *)&sock->
recv_buff,
sizeof(
int)) < 0) {
2799 this->print(
this, buffer,
sizeof(buffer));
2808 if ((sock->
proto == IPPROTO_TCP)
2813 DEBUG4(
"[FD %i] Listening -- listen(%i, 8)", this->fd, this->fd);
2814 if (listen(this->fd, 8) < 0) {
2836 if (this->fd >= 0) close(this->fd);
2838 if (this->
proto->free) {
2839 this->
proto->free(
this);
2850 #ifdef WITH_COMMAND_SOCKET
2870 if (this->children) {
2881 rad_assert(!sock->tls_session || (talloc_parent(sock->tls_session) == sock));
2882 rad_assert(!sock->request || (talloc_parent(sock->request) == sock));
2883 #ifdef HAVE_PTHREAD_H
2905 this->proto =
proto;
2906 this->recv = proto->
recv;
2907 this->send = proto->
send;
2908 this->print = proto->
print;
2909 this->debug = proto->
debug;
2910 this->encode = proto->
encode;
2911 this->decode = proto->
decode;
2915 this->
data = talloc_zero_array(
this, uint8_t, proto->
inst_size);
2934 if (!home)
return NULL;
2940 RATE_LIMIT(
INFO(
"Home server %s has too many open connections (%d)",
2947 WARN(
"Suppressing attempt to open socket to 'down' home server");
2965 this->print(
this, buffer,
sizeof(buffer));
2970 if (home->
proto == IPPROTO_TCP) {
2988 this->print(
this, buffer,
sizeof(buffer));
2989 ERROR(
"Failed opening new proxy socket '%s' : %s",
2997 #if defined(WITH_TCP) && defined(WITH_TLS)
2998 if ((home->
proto == IPPROTO_TCP) && home->tls) {
2999 DEBUG(
"Trying SSL to port %d\n", home->
port);
3000 sock->tls_session = tls_session_init_client(sock, home->tls, this->fd);
3001 if (!sock->tls_session) {
3002 ERROR(
"Failed starting SSL to new proxy socket '%s'", buffer);
3008 this->recv = proxy_tls_recv;
3009 this->send = proxy_tls_send;
3016 struct sockaddr_storage src;
3017 socklen_t sizeof_src =
sizeof(src);
3019 memset(&src, 0, sizeof_src);
3020 if (getsockname(this->fd, (
struct sockaddr *) &src, &sizeof_src) < 0) {
3021 ERROR(
"Failed getting socket name for '%s': %s",
3030 ERROR(
"Socket has unsupported address family for '%s'", buffer);
3036 this->print(
this, buffer,
sizeof(buffer));
3040 DEBUG(
"Opened new proxy socket '%s'", buffer);
3055 char const *listen_type;
3063 if (rcode < 0)
return NULL;
3077 if (strchr(listen_type,
'+') != NULL) {
3096 #ifdef HAVE_PTHREAD_H
3101 static void *recv_thread(
void *arg)
3128 bool incoming_sockets =
false;
3130 if (!listen_config) {
3131 ERROR(
"The server is not configured to listen on any ports. Cannot start");
3135 for (lc = listen_config; lc != NULL; lc = lc->
next) {
3139 incoming_sockets =
true;
3149 if (!incoming_sockets) {
3150 ERROR(
"The server is not configured to listen on any ports. Cannot start");
3166 for (lc = listen_config; lc != NULL; lc = lc->
next) {
3168 TALLOC_FREE(listen_ctx);
3174 last = &(this->next);
3181 for (
this = *head;
this != NULL;
this = this->next) {
3183 if (!spawn_workers && this->tls) {
3184 cf_log_err_cs(this->cs,
"Threading must be enabled for TLS sockets to function properly");
3185 cf_log_err_cs(this->cs,
"You probably need to do '%s -fxx -l stdout' for debugging",
3190 if (this->workers && !spawn_workers) {
3191 WARN(
"Setting 'workers' requires 'synchronous'. Disabling 'workers'");
3195 if (this->workers) {
3196 #ifdef HAVE_PTHREAD_H
3201 this->print(
this, buffer,
sizeof(buffer));
3203 for (i = 0; i < this->workers; i++) {
3209 rcode = pthread_create(&
id, 0, recv_thread,
this);
3215 DEBUG(
"Thread %d for %s\n", i, buffer);
3218 WARN(
"Setting 'workers' requires 'synchronous'. Disabling 'workers'");
3237 if (!head || !*head)
return;
3272 # ifdef WITH_ACCOUNTING
3282 if (sock->
my_port != port)
continue;
3283 if (sock->
proto != proto)
continue;
3311 if (sock->
my_port != port)
continue;
3312 if (sock->
proto != proto)
continue;
3326 if (sock->
my_port != port)
continue;
3327 if (sock->
proto != proto)
continue;
struct fr_command_socket_t fr_command_socket_t
#define COMMAND_SOCKET_MAGIC
int sockfd
Socket this packet was read from.
bool rate_limit
Where addition of clients should be rate limited.
fr_ipaddr_t src_ipaddr
Resolved version of src_ipaddr_str.
#define pthread_mutex_init(_x, _y)
struct listen_detail_t listen_detail_t
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
static int dual_tcp_recv(rad_listen_t *listener)
int id
Packet ID (used to link requests/responses).
static void command_socket_free(rad_listen_t *this)
int fr_radius_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, char const *secret)
Calculate/check digest, and decode radius attributes.
rad_listen_t * listener
created from this configuration
int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *data, char const *dflt, FR_TOKEN dflt_quote)
Parses a CONF_PAIR into a C data type, with a default value.
fr_socket_limit_t limit
Connections per client (TCP clients only).
FR_NAME_NUMBER const fr_net_af_table[]
Strings for address families.
rlm_rcode_t process_authorize(int type, REQUEST *request)
FR_NAME_NUMBER const fr_net_ip_proto_table[]
Strings for L4 protocols.
Only displayed when debugging is enabled.
#define FR_STATS_TYPE_INC(_x)
int fr_socket_client_tcp(fr_ipaddr_t *src_ipaddr, fr_ipaddr_t *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
fr_uint_t total_packets_dropped
RADCLIENT_LIST * client_list_parse_section(CONF_SECTION *section, bool tls_required)
RFC2865 - Access-Challenge.
Main server configuration.
static int command_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
RADIUS_PACKET * proxy_reply
Incoming response from proxy server.
static int listen_bind(rad_listen_t *this)
bool rbtree_deletebydata(rbtree_t *tree, void const *data)
Delete a node from the tree, based on given data, which MUST have come from rbtree_finddata().
static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
The module is OK, continue.
static int listener_unlink(UNUSED void *ctx, UNUSED void *data)
void exec_trigger(REQUEST *request, CONF_SECTION *cs, char const *name, bool quench) CC_HINT(nonnull(3))
Execute a trigger - call an executable to process an event.
uint32_t lifetime
How long before the client is removed.
int radlog(log_type_t lvl, char const *fmt,...) CC_HINT(format(printf
int fr_ipaddr_from_sockaddr(struct sockaddr_storage const *sa, socklen_t salen, fr_ipaddr_t *ipaddr, uint16_t *port)
rlm_rcode_t process_send_coa(int type, REQUEST *request)
int rad_accounting(REQUEST *)
char const * cf_section_filename(CONF_SECTION const *section)
char const * fr_packet_codes[FR_MAX_PACKET_CODE]
lt_dlhandle lt_dlopenext(char const *name)
int fr_tcp_read_packet(RADIUS_PACKET *packet, int flags)
fr_ipaddr_t src_ipaddr
Src IP address of packet.
static listen_config_t * listen_config
uint8_t prefix
Prefix length - Between 0-32 for IPv4 and 0-128 for IPv6.
int fr_is_inaddr_any(fr_ipaddr_t *ipaddr)
Determine if an address is the INADDR_ANY address for its address family.
WiMAX IPv4 or IPv6 address depending on length.
uint32_t talloc_pool_size
Size of pool to allocate to hold each REQUEST.
static fr_protocol_t master_listen[]
#define RDEBUG_ENABLED
True if request debug level 1 messages are enabled.
int common_socket_print(rad_listen_t const *this, char *buffer, size_t bufsize)
rad_listen_encode_t encode
static int command_tcp_send(rad_listen_t *listener, REQUEST *request)
#define REDEBUG2(fmt,...)
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
#define CONF_PARSER_TERMINATOR
int detail_decode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
struct listen_config_t * next
the next listener
void request_stats_reply(REQUEST *request)
#define pair_make_request(_a, _b, _c)
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
char const * secret
Secret PSK.
static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
RADCLIENT RADCLIENT * client_find(RADCLIENT_LIST const *clients, fr_ipaddr_t const *ipaddr, int proto)
void void void cf_log_err_cp(CONF_PAIR const *cp, char const *fmt,...) CC_HINT(format(printf
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
static int proxy_socket_recv(rad_listen_t *listener)
int fr_radius_send(RADIUS_PACKET *, RADIUS_PACKET const *, char const *secret)
Reply to the request.
fr_stats_t auth
Authentication stats.
rad_listen_t * listener
The listener that received the request.
#define PW_AUTHORIZE_ONLY
struct listen_socket_t listen_socket_t
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
The module considers the request invalid.
char const * name
Name of the daemon, usually 'radiusd'.
static int command_tcp_recv(rad_listen_t *listener)
unsigned int number
Monotonically increasing request number. Reset on server restart.
RADCLIENT_LIST * listener_find_client_list(fr_ipaddr_t const *ipaddr, uint16_t port, int proto)
Find client list associated with a listener.
void listen_free(rad_listen_t **head)
Free a linked list of listeners.
VALUE_PAIR * fr_pair_list_copy_by_num(TALLOC_CTX *ctx, VALUE_PAIR *from, unsigned int vendor, unsigned int attr, int8_t tag)
Copy matching pairs.
rlm_rcode_t process_recv_coa(int type, REQUEST *request)
int rad_status_server(REQUEST *request)
RFC3575/RFC5176 - Disconnect-Ack (positive)
uint16_t dst_port
DST Port of packet.
uint16_t src_port
Src port of packet.
fr_ipaddr_t dst_ipaddr
Dst IP address of packet.
void common_packet_debug(REQUEST *request, RADIUS_PACKET *packet, bool received)
static int command_domain_accept(rad_listen_t *listener)
Defines a CONF_PAIR to C data type mapping.
fr_dict_enum_t * fr_dict_enum_by_name(fr_dict_t *dict, fr_dict_attr_t const *da, char const *val)
#define FR_STATS_INC(_x, _y)
CONF_PAIR * cf_pair_find(CONF_SECTION const *, char const *name)
char const * cf_pair_value(CONF_PAIR const *pair)
RFC2866 - Accounting-Response.
static char const * proto
bool client_add_dynamic(RADCLIENT_LIST *clients, RADCLIENT *master, RADCLIENT *c)
Add a dynamic client.
#define FR_IPADDR_STRLEN
Like INET6_ADDRSTRLEN but includes space for the textual Zone ID.
RADIUS_PACKET * proxy
Outgoing request to proxy server.
const FR_NAME_NUMBER mod_rcode_table[]
char const * server
For internal proxying.
main_config_t * root
Pointer to the main config hack to try and deal with hup.
RFC3575/RFC5176 - CoA-Ack (positive)
Reject the request (user is locked out).
static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
RFC2865 - Access-Request.
static TALLOC_CTX * listen_ctx
void client_delete(RADCLIENT_LIST *clients, RADCLIENT *client)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
static int proxy_socket_tcp_recv(rad_listen_t *listener)
Highest priority debug messages (-x).
int detail_print(rad_listen_t const *this, char *buffer, size_t bufsize)
int detail_socket_open(CONF_SECTION *cs, rad_listen_t *this)
static int listener_cmp(void const *one, void const *two)
static int command_domain_send(UNUSED rad_listen_t *listener, UNUSED REQUEST *request)
rad_listen_t * proxy_new_listener(TALLOC_CTX *ctx, home_server_t *home, uint16_t src_port)
rbtree_t * rbtree_create(TALLOC_CTX *ctx, rb_comparator_t compare, rb_free_t node_free, int flags)
Create a new RED-BLACK tree.
int fr_radius_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, char const *secret)
Verify the Request/Response Authenticator (and Message-Authenticator if present) of a packet...
int(* RAD_REQUEST_FUNP)(REQUEST *)
static void print_packet(FILE *fp, RADIUS_PACKET *packet)
#define PW_RADIUS_TLS_PORT
static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
static int command_socket_decode(UNUSED rad_listen_t *listener, UNUSED REQUEST *request)
void void void void cf_log_info(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
static int do_proxy(REQUEST *request)
int rad_authenticate(REQUEST *)
void fr_pair_add(VALUE_PAIR **head, VALUE_PAIR *vp)
Add a VP to the end of the list.
struct listen_config_t listen_config_t
RFC2866 - Accounting-Request.
RADCLIENT * client_afrom_request(RADCLIENT_LIST *clients, REQUEST *request)
Create a new client, consuming all attributes in the control list of the request. ...
RADIUS_PACKET * fr_radius_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new RADIUS_PACKET.
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
Immediately reject the request.
union fr_ipaddr_t::@1 ipaddr
RFC3575/RFC5176 - CoA-Nak (not willing to perform)
RADCLIENT * client_listener_find(rad_listen_t *listener, fr_ipaddr_t const *ipaddr, uint16_t src_port)
unsigned int code
Packet code (type).
int rbtree_walk(rbtree_t *tree, rb_order_t order, rb_walker_t compare, void *context)
static rad_listen_t * listen_alloc(TALLOC_CTX *ctx, RAD_LISTEN_TYPE type, fr_protocol_t *proto)
CONF_SECTION * cf_top_section(CONF_SECTION *cs)
int fr_dict_enum_add(fr_dict_t *dict, char const *attr, char const *alias, int value)
int lt_dlclose(lt_dlhandle handle)
rlm_rcode_t process_accounting(int type, REQUEST *request)
static int command_socket_open(CONF_SECTION *cs, rad_listen_t *this)
Stores an attribute, a value and various bits of other data.
static CONF_PARSER performance_config[]
RADIUS_PACKET * reply
Outgoing response.
static int command_socket_encode(UNUSED rad_listen_t *listener, UNUSED REQUEST *request)
static int dual_tcp_accept(rad_listen_t *listener)
CONF_SECTION * cs
CONF_SECTION that was parsed to generate the client.
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
static int command_write_magic(int newfd, listen_socket_t *sock)
CoA destination (NAS or Proxy)
rad_listen_decode_t decode
static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
Configuration AVP similar to a VALUE_PAIR.
static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
int rad_coa_recv(REQUEST *request)
RFC3575/RFC5176 - CoA-Request.
char const * fr_strerror(void)
Get the last library error.
char const * server_name
name of the virtual server (if any)
CONF_SECTION * cf_section_sub_find(CONF_SECTION const *, char const *name)
Find a sub-section in a section.
void radlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg,...) CC_HINT(format(printf
ssize_t fr_radius_len(uint8_t const *data, size_t data_len)
See how big of a packet is in the buffer.
void rdebug_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *)
Print a list of VALUE_PAIRs.
static int coa_socket_recv(rad_listen_t *listener)
int request_receive(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *packet, RADCLIENT *client, RAD_REQUEST_FUNP fun)
char const * log_name
The name used for log messages.
Module succeeded without doing anything.
int if_index
Index of receiving interface.
Describes a host allowed to send packets to the server.
time_t created
When the client was created.
void rdebug_proto_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *)
Print a list of protocol VALUE_PAIRs.
void detail_free(rad_listen_t *this)
struct listen_socket_t * parent
uint32_t dynamic
Whether the client was dynamically defined.
RADIUS_PACKET * fr_tcp_recv(int sockfd, int flags)
int detail_recv(rad_listen_t *listener)
int fr_socket_server_base(int proto, fr_ipaddr_t *ipaddr, int *port, char const *port_name, bool async)
Open an IPv4 / IPv6, and UDP / TCP socket, server side.
static bool spawn_workers
rad_listen_t * proxy_listener
Listener for outgoing requests.
Module failed, don't reply.
CONF_SECTION * config
Root of the server config.
int fr_socket(fr_ipaddr_t *ipaddr, uint16_t port)
#define FR_CONF_OFFSET(_n, _t, _s, _f)
log_lvl_t rad_debug_lvl
Global debugging level.
char const * name
The name of the protocol.
void fr_radius_free(RADIUS_PACKET **)
Free a RADIUS_PACKET.
static int _listener_free(rad_listen_t *this)
#define FR_ITEM_POINTER(_t, _p)
CONF_SECTION * server
encapsulating server configuratiuon
RADIUS_PACKET * fr_radius_alloc_reply(TALLOC_CTX *ctx, RADIUS_PACKET *)
Allocate a new RADIUS_PACKET response.
rad_listen_t * listener_find_byipaddr(fr_ipaddr_t const *ipaddr, uint16_t port, int proto)
Find a listener associated with an IP address/port/transport proto.
size_t data_len
Length of packet data.
bool rbtree_insert(rbtree_t *tree, void *data)
static int _listen_config_free(listen_config_t *lc)
ssize_t fr_radius_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, unsigned int *code)
Basic validation of RADIUS packet header.
RADIUS_PACKET * packet
Incoming request.
fr_ipaddr_t src_ipaddr
IPv4/IPv6 address to send responses from (family must match ipaddr).
fr_protocol_t * proto
same as Listen-Socket-Type
#define RATE_LIMIT(_x)
Rate limit messages.
int fr_radius_encode(RADIUS_PACKET *packet, RADIUS_PACKET const *original, char const *secret)
Encode a packet.
main_config_t main_config
Main server configuration.
rad_listen_t * listen
Head of a linked list of listeners.
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
home_server_t * home_server
static int acct_socket_recv(rad_listen_t *listener)
char * fr_inet_ntop(char out[FR_IPADDR_STRLEN], size_t outlen, fr_ipaddr_t *addr)
Print the address portion of a fr_ipaddr_t.
lt_dlhandle * handle
to dynamically loaded library (if any)
RFC2865/RFC5997 - Status Server (request)
int detail_encode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
bool status_server
Whether to respond to status-server messages.
static int command_socket_print(rad_listen_t const *this, char *buffer, size_t bufsize)
size_t strlcpy(char *dst, char const *src, size_t siz)
fr_stats_t acct
Accounting stats.
uint32_t recv_buff
Socket receive buffer size we only allow configuration of SO_RCVBUF, as SO_SNDBUF controls the maximu...
uint64_t magic
Used to validate loaded library.
char const * client_server
Virtual server associated with this dynamic client.
int common_socket_open(CONF_SECTION *cs, rad_listen_t *this)
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
int detail_send(rad_listen_t *listener, REQUEST *request)
static rad_listen_t * listen_parse(listen_config_t *lc)
static CONF_PARSER limit_config[]
RADIUS_PACKET * fr_radius_recv(TALLOC_CTX *ctx, int fd, int flags)
Receive UDP client requests, and fill in the basics of a RADIUS_PACKET structure. ...
int request_proxy_reply(RADIUS_PACKET *packet)
bool message_authenticator
Require RADIUS message authenticator in requests.
int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const *interface)
Bind to an IPv4 / IPv6, and UDP / TCP socket, server side.
home_pool_t * home_pool_byname(char const *name, int type)
home_server_t * home_server_find(fr_ipaddr_t *ipaddr, uint16_t port, int proto)
fr_dict_attr_t const * fr_dict_attr_by_num(fr_dict_t *dict, unsigned int vendor, unsigned int attr)
Lookup a fr_dict_attr_t by its vendor and attribute numbers.
String of printable characters.
static int stats_socket_recv(rad_listen_t *listener)
time_t last_new_client
Used for relate limiting addition and deletion of dynamic clients.
int detail_parse(CONF_SECTION *cs, rad_listen_t *this)
static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
CONF_SECTION * cf_section_sub_find_name2(CONF_SECTION const *, char const *name1, char const *name2)
Find a CONF_SECTION with both names.
RADCLIENT * client
The client that originally sent us the request.
RFC3575/RFC5176 - Disconnect-Nak (not willing to perform)
#define pthread_mutex_destroy(_x)
char const * server
Virtual server client is associated with.
fr_uint_t total_unknown_types
void radius_update_listener(rad_listen_t *listener)
static int auth_socket_recv(rad_listen_t *listener)
char const * fr_inet_ntoh(fr_ipaddr_t const *src, char *out, size_t outlen)
Perform reverse resolution of an IP address.
The module handled the request, so stop.
#define DEBUG_ENABLED
True if global debug level 1 messages are enabled.
int listen_init(rad_listen_t **head, bool spawn_workers)
Search for listeners in the server.
int fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
Compare two ip addresses.
static void common_socket_free(rad_listen_t *this)
#define is_radius_code(_x)
void udp_recv_discard(int sockfd)
Discard the next UDP packet.
Value of an enumerated attribute.
fr_ipaddr_t ipaddr
IP address of home server.
REQUEST * request_alloc(TALLOC_CTX *ctx)
Create a new REQUEST data structure.
char const * shortname
Client nickname.
RFC3575/RFC5176 - Disconnect-Request.
CONF_SECTION * cs
configuration for this listener
int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_name)
int fr_radius_sign(RADIUS_PACKET *packet, RADIUS_PACKET const *original, char const *secret)
Sign a previously encoded packet.