27 RCSID(
"$Id: d6113a2d69fdf67fc1986664a34d6511452c722a $")
29 #include <freeradius-devel/radiusd.h>
30 #include <freeradius-devel/process.h>
31 #include <freeradius-devel/modules.h>
32 #include <freeradius-devel/state.h>
34 #include <freeradius-devel/rad_assert.h>
37 #include <freeradius-devel/detail.h>
43 #ifdef HAVE_SYS_WAIT_H
44 # include <sys/wait.h>
72 #ifdef DEBUG_STATE_MACHINE
73 # define TRACE_STATE_MACHINE \
74 if (rad_debug_lvl) do { \
75 struct timeval debug_tv; \
76 gettimeofday(&debug_tv, NULL); \
77 debug_tv.tv_sec -= fr_start_time; \
78 printf("(%u) %d.%06d ********\tSTATE %s action %s live M-%s C-%s\t********\n",\
79 request->number, (int) debug_tv.tv_sec, (int) debug_tv.tv_usec, \
80 __FUNCTION__, action_codes[action], master_state_names[request->master_state], \
81 child_state_names[request->child_state]); \
102 # define TRACE_STATE_MACHINE {}
107 ERROR(
"%s[%u]: %s", file, line, msg);
111 #define rad_panic(x) _rad_panic(__FILE__, __LINE__, x)
119 #define STATE_MACHINE_DECL(_x) static void _x(REQUEST *request, int action)
136 _rad_panic(file, line,
"Failed to insert event");
144 #define STATE_MACHINE_TIMER(_x) state_machine_timer(__FILE__, __LINE__, request, &when, _x)
152 #if defined(WITH_VERIFY_PTR) && defined(HAVE_PTHREAD_H)
153 # undef VERIFY_REQUEST
154 # define VERIFY_REQUEST(_x) if (pthread_equal(pthread_self(), _x->child_pid) != 0) verify_request(__FILE__, __LINE__, _x)
238 #ifdef HAVE_PTHREAD_H
240 static pthread_mutex_t proxy_mutex;
241 static bool proxy_no_new_sockets =
false;
244 # define PTHREAD_MUTEX_LOCK if (spawn_workers) pthread_mutex_lock
245 # define PTHREAD_MUTEX_UNLOCK if (spawn_workers) pthread_mutex_unlock
247 static pthread_t NO_SUCH_CHILD_PID;
248 # define NO_CHILD_THREAD request->child_pid = NO_SUCH_CHILD_PID
254 # define PTHREAD_MUTEX_LOCK(_x)
255 # define PTHREAD_MUTEX_UNLOCK(_x)
256 # define NO_CHILD_THREAD
259 #ifdef HAVE_PTHREAD_H
263 (pthread_equal(pthread_self(), NO_SUCH_CHILD_PID) == 0)) {
274 # define ASSERT_MASTER if (!we_are_master()) rad_panic("We are not master")
281 # define we_are_master(_x) (1)
284 #ifndef ASSERT_MASTER
285 # define ASSERT_MASTER
291 #define FINAL_STATE(_x) NO_CHILD_THREAD; request->component = "<" #_x ">"; request->module = ""; request->child_state = _x
300 #if defined (HAVE_PTHREAD_H) && (defined(WITH_PROXY) || defined(WITH_TCP))
303 static pthread_mutex_t fd_mutex;
304 # define FD_MUTEX_LOCK if (spawn_workers) pthread_mutex_lock
305 # define FD_MUTEX_UNLOCK if (spawn_workers) pthread_mutex_unlock
330 this->next = new_listeners;
331 new_listeners =
this;
346 # define FD_MUTEX_LOCK(_x)
347 # define FD_MUTEX_UNLOCK(_x)
381 # define COA_SEPARATE if (request->coa) coa_separate(request->coa);
383 # define COA_SEPARATE
386 #define CHECK_FOR_STOP do { if (request->master_state == REQUEST_STOP_PROCESSING) {request_done(request, FR_ACTION_DONE);return;}} while (0)
389 #define USEC (1000000)
391 #define INSERT_EVENT(_function, _ctx) if (!fr_event_insert(el, _function, _ctx, &((_ctx)->when), &((_ctx)->ev))) { _rad_panic(__FILE__, __LINE__, "Failed to insert event"); }
393 static void tv_add(
struct timeval *tv,
int usec_delay)
395 if (usec_delay >=
USEC) {
396 tv->tv_sec += usec_delay /
USEC;
399 tv->tv_usec += usec_delay;
401 if (tv->tv_usec >=
USEC) {
402 tv->tv_sec += tv->tv_usec /
USEC;
441 struct timeval half_response_window;
448 half_response_window.tv_usec =
451 if (timercmp(&half_response_window, &request->
root->
init_delay, <))
452 return (
int)half_response_window.tv_sec *
USEC +
453 (int)half_response_window.tv_usec;
472 request->
process(request, action);
489 talloc_free(request);
493 ptr = talloc_parent(request);
502 char buffer[INET6_ADDRSTRLEN];
504 RDEBUG2(
"Reply from home server %s port %d - ID: %d arrived too late. "
505 "Try increasing 'retry_delay' or 'max_request_time'",
508 buffer,
sizeof(buffer)),
530 struct timeval now, when;
554 #ifdef HAVE_PTHREAD_H
595 RDEBUG(
"No reply. Ignoring retransmit");
603 #ifdef HAVE_PTHREAD_H
612 #ifdef DEBUG_STATE_MACHINE
613 if (
rad_debug_lvl) printf(
"(%u) ********\tSTATE %s C-%s -> C-%s\t********\n",
614 request->
number, __FUNCTION__,
677 timercmp(&now, &when, <)) {
678 RDEBUG(
"Waiting for more responses from the home server");
689 #ifdef HAVE_PTHREAD_H
700 gettimeofday(&now, NULL);
706 tv_add(&when, request->
delay);
714 #ifdef HAVE_PTHREAD_H
715 rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
737 RDEBUG2(
"Cleaning up request packet ID %u with timestamp +%d",
739 (
unsigned int) (request->
timestamp.tv_sec - fr_start_time));
750 struct timeval now, when;
765 #ifdef WITH_ACCOUNTING
779 gettimeofday(&now, NULL);
785 when.tv_sec += request->
delay;
790 if (timercmp(&when, &now, >)) {
791 #ifdef DEBUG_STATE_MACHINE
792 if (
rad_debug_lvl) printf(
"(%u) ********\tNEXT-STATE %s -> %s\n", request->
number, __FUNCTION__,
"request_cleanup_delay");
805 #ifdef HAVE_PTHREAD_H
806 rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
825 struct timeval now, when;
827 #ifdef DEBUG_STATE_MACHINE
859 if (timercmp(&now, &when, >=)) {
860 #ifdef HAVE_PTHREAD_H
866 (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0)) {
867 ERROR(
"Unresponsive child for request %u, in component %s module %s",
871 exec_trigger(request, NULL,
"server.thread.unresponsive",
true);
886 tv_add(&when, request->
delay);
895 #ifdef DEBUG_STATE_MACHINE
908 #ifdef DEBUG_STATE_MACHINE
909 if (
rad_debug_lvl) printf(
"(%u) ********\tSTATE %s M-%s causes C-%s-> C-%s\t********\n",
910 request->
number, __FUNCTION__,
929 gettimeofday(&when, NULL);
930 tv_add(&when, request->
delay);
935 #ifdef HAVE_PTHREAD_H
940 if (request_enqueue(request))
return;
961 while (waitpid(-1, NULL, WNOHANG) > 0);
968 ERROR(
"(%u) Ignoring duplicate packet from "
969 "client %s port %d - ID: %u due to unfinished request "
970 "in component %s module %s",
1004 struct timeval when, now;
1018 RDEBUG(
"No reply. Ignoring retransmit");
1026 when.tv_sec += request->
delay;
1045 if (timercmp(&when, &now, >)) {
1046 #ifdef DEBUG_STATE_MACHINE
1047 if (
rad_debug_lvl) printf(
"(%u) ********\tNEXT-STATE %s -> %s\n", request->
number, __FUNCTION__,
"request_cleanup_delay");
1057 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
1084 struct timeval when, now;
1095 ERROR(
"(%u) Discarding duplicate request from "
1096 "client %s port %d - ID: %u due to delayed response",
1119 if (timercmp(&when, &now, >)) {
1120 #ifdef DEBUG_STATE_MACHINE
1121 if (
rad_debug_lvl) printf(
"(%u) ********\tNEXT-STATE %s -> %s\n", request->
number, __FUNCTION__,
"request_response_delay");
1127 RDEBUG2(
"Sending delayed response");
1138 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
1171 if (debug_condition) {
1232 if (vp->vp_integer == 256) {
1233 RDEBUG2(
"Not responding to request");
1245 if (!vp || (vp->vp_integer != 5)) {
1246 RDEBUG2(
"There was no response configured: "
1247 "rejecting request");
1307 RDEBUG(
"Finished internally proxied request.");
1337 RDEBUG(
"Not sending reply to client.");
1360 RDEBUG(
"Suppressing reply to client.");
1373 if (vp->vp_integer <= 10) {
1382 if (vp->vp_integer <= 10 *
USEC) {
1428 RDEBUG2(
"Delaying response for %d.%06d seconds",
1471 #ifdef DEBUG_STATE_MACHINE
1472 if (
rad_debug_lvl) printf(
"(%u) ********\tSTATE %s failed in pre-handler C-%s -> C-%s\t********\n",
1473 request->
number, __FUNCTION__,
1482 ret = request->
handle(request);
1493 #ifdef DEBUG_STATE_MACHINE
1506 #ifdef DEBUG_STATE_MACHINE
1518 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
1540 #ifdef WITH_ACCOUNTING
1544 sock = listener->
data;
1545 sock->last_packet = now.tv_sec;
1548 packet->
proto = sock->proto;
1555 if (listener->
nodup)
goto skip_dup;
1571 sizeof(packet->
vector)) == 0)) {
1574 switch (packet->
code) {
1579 #ifdef WITH_ACCOUNTING
1624 ERROR(
"Received conflicting packet from "
1625 "client %s port %d - ID: %u due to "
1626 "unfinished request. Giving up on old request.",
1644 RATE_LIMIT(
ERROR(
"Dropping request (%d is too many): from client %s port %d - ID: %d", count,
1647 WARN(
"Please check the configuration file.\n"
1648 "\tThe value for 'max_requests' is probably set too low.\n"));
1658 if (sock && sock->max_rate) {
1661 pps =
rad_pps(&sock->rate_pps_old, &sock->rate_pps_now, &sock->rate_time, &now);
1662 if (pps > sock->max_rate) {
1663 DEBUG(
"Dropping request due to rate limiting");
1666 sock->rate_pps_now++;
1675 talloc_set_name_const(ctx,
"request_receive_pool");
1681 (void) talloc_steal(ctx, packet);
1684 request =
request_setup(ctx, listener, packet, client, fun);
1698 if (!listener->
nodup) {
1700 RERROR(
"Failed to insert request in the list of live requests: discarding it");
1725 RDEBUG(
"Not sending reply");
1759 if (!request->
reply) {
1761 talloc_free(request);
1766 request->
client = client;
1767 request->
packet = talloc_steal(request, packet);
1768 request->
number = request_num_counter++;
1776 #ifdef DEBUG_STATE_MACHINE
1777 if (
rad_debug_lvl) printf(
"(%u) ********\tSTATE %s C-%s -> C-%s\t********\n",
1778 request->
number, __FUNCTION__,
1790 #ifdef WITH_ACCOUNTING
1808 }
else if (listener->
server) {
1871 switch (listener->
type) {
1879 #ifdef WITH_ACCOUNTING
1882 limit = &sock->
limit;
1896 if (timercmp(&end, now, <=)) {
1897 listener->
print(listener, buffer,
sizeof(buffer));
1898 DEBUG(
"Reached maximum lifetime on socket %s", buffer);
1936 struct timeval idle;
1942 if (timercmp(&idle, now, <=)) {
1943 listener->
print(listener, buffer,
sizeof(buffer));
1944 DEBUG(
"Reached idle timeout on socket %s", buffer);
1951 if (timercmp(&idle, &end, <)) {
1960 end.tv_usec =
USEC / 2;
1981 jitter ^= (jitter >> 10);
1982 jitter &= ((1 << 22) - 1);
1987 tv_add(when, jitter);
2029 if (request->
listener !=
this)
return 0;
2074 struct timeval when, now;
2080 gettimeofday(&now, NULL);
2089 if (timercmp(&now, &when, >)) {
2139 char buffer[INET6_ADDRSTRLEN];
2141 bool success =
false;
2142 void *proxy_listener;
2152 proxy_listener = NULL;
2156 for (tries = 0; tries < 2; tries++) {
2160 RDEBUG3(
"proxy: Trying to allocate ID (%d/2)", tries);
2163 &request->
proxy, &proxy_listener);
2166 if (tries > 0)
continue;
2168 #ifdef HAVE_PTHREAD_H
2169 if (proxy_no_new_sockets)
break;
2172 RDEBUG3(
"proxy: Trying to open a new listener to the home server");
2180 proxy_listener =
this;
2188 #ifdef HAVE_PTHREAD_H
2189 proxy_no_new_sockets =
true;
2199 ERROR(
"Failed adding proxy socket: %s",
2213 if (!proxy_listener || !success) {
2215 REDEBUG2(
"proxy: Failed allocating Id for proxied request");
2226 RDEBUG3(
"proxy: request is now in proxy hash");
2241 RDEBUG3(
"proxy: allocating destination %s port %d - Id %d",
2252 int post_proxy_type = 0;
2265 RDEBUG2(
"Clearing existing &reply: attributes");
2274 post_proxy_type = vp->vp_integer;
2286 switch (reply->
code) {
2289 if (dval) post_proxy_type = dval->
value;
2294 if (dval) post_proxy_type = dval->
value;
2299 if (dval) post_proxy_type = dval->
value;
2311 vp->vp_integer = dval->
value;
2315 if (post_proxy_type > 0)
RDEBUG2(
"Found Post-Proxy-Type %s",
2346 char const *old_server = request->
server;
2354 request->
server = old_server;
2398 char buffer[INET6_ADDRSTRLEN];
2410 RPROXY(
"Marking home server %s port %d alive",
2413 buffer,
sizeof(buffer)),
2423 char buffer[INET6_ADDRSTRLEN];
2432 PROXY(
"No outstanding request was found for %s packet from host %s port %d - ID %u",
2436 buffer,
sizeof(buffer)),
2454 DEBUG(
"Ignoring spoofed proxy reply. Signature is invalid");
2467 RDEBUG2(
"Ignoring conflicting proxy reply");
2471 gettimeofday(&now, NULL);
2488 RDEBUG2(
"Discarding duplicate reply from host %s port %d - ID: %d",
2491 buffer,
sizeof(buffer)),
2500 request->
proxy_reply = talloc_steal(request, packet);
2530 #ifdef WITH_ACCOUNTING
2598 WARN(
"Unknown packet type in Post-Proxy-Type Fail: ignoring");
2611 PW_POST_PROXY_TYPE, 0);
2612 vp->vp_integer = dval->
value;
2656 request->
handle(request);
2662 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
2701 request->
handle(request);
2707 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
2745 int rcode, pre_proxy_type = 0;
2746 char const *realmname = NULL;
2749 REALM *realm = NULL;
2762 if (request->
reply->
code != 0)
return 0;
2768 REDEBUG2(
"Cannot proxy to unknown realm %s",
2773 realmname = vp->vp_strvalue;
2781 #ifdef WITH_ACCOUNTING
2804 #ifdef WITH_ACCOUNTING
2831 memset(&dst_ipaddr, 0,
sizeof(dst_ipaddr));
2833 if (vp->
da->
attr == PW_PACKET_DST_IP_ADDRESS) {
2834 dst_ipaddr.
af = AF_INET;
2835 dst_ipaddr.
ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
2838 dst_ipaddr.
af = AF_INET6;
2839 memcpy(&dst_ipaddr.
ipaddr.ip6addr, &vp->vp_ipv6addr,
sizeof(vp->vp_ipv6addr));
2848 #ifdef WITH_ACCOUNTING
2863 dst_port = vp->vp_integer;
2871 char buffer[INET6_ADDRSTRLEN];
2873 WARN(
"No such home server %s port %u",
2875 (
unsigned int) dst_port);
2898 RWDEBUG2(
"Cancelling proxy as no home pool exists");
2903 WARN(
"Cannot proxy a request which is from a 'synchronous' socket");
2912 REDEBUG2(
"Failed to find live home server: Cancelling proxy");
3007 pre_proxy_type = vp->vp_integer;
3015 char const *old_server = request->
server;
3025 request->
server = old_server;
3058 WARN(
"Cannot proxy an internal request");
3062 DEBUG(
"Proxying to virtual server %s",
3076 talloc_free(request->
proxy);
3087 request->
proxy = talloc_steal(request, fake->
packet);
3107 request->
handle(request);
3116 char buffer[INET6_ADDRSTRLEN];
3127 RWDEBUG(
"Cannot proxy and originate CoA packets at the same time. Cancelling CoA request");
3149 RPROXY(
"Failed to insert request into the proxy list");
3156 struct timeval *response_window;
3162 RDEBUG2(
"Proxying request to home server %s port %d (TLS) timeout %d.%06d",
3165 buffer,
sizeof(buffer)),
3167 (
int) response_window->tv_sec, (
int) response_window->tv_usec);
3170 RDEBUG2(
"Proxying request to home server %s port %d timeout %d.%06d",
3173 buffer,
sizeof(buffer)),
3175 (
int) response_window->tv_sec, (
int) response_window->tv_usec);
3202 request->
component =
"<REQUEST_PROXIED>";
3238 REDEBUG2(
"Failed to find live home server for request");
3249 #ifdef WITH_ACCOUNTING
3259 PW_ACCT_DELAY_TIME, 0);
3263 gettimeofday(&now, NULL);
3276 TALLOC_FREE(request->
proxy);
3285 RPROXY(
"Failed to insert retransmission into the proxy list");
3286 goto post_proxy_fail;
3308 char buffer[INET6_ADDRSTRLEN];
3317 ERROR(
"No response to status check %d ID %u for home server %s port %d",
3322 buffer,
sizeof(buffer)),
3330 RPROXY(
"Received response to status check %d ID %u (%d in current sequence)",
3366 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
3385 struct timeval when;
3389 (home->
proto == IPPROTO_TCP) ||
3391 (home->
ev != NULL)) {
3404 if (timercmp(&when, now, <)) {
3405 DEBUG(
"PING: Zombie period is over for home server %s", home->
log_name);
3436 if (!request)
return;
3437 request->
number = request_num_counter++;
3447 "Message-Authenticator",
"0x00",
T_OP_SET);
3458 "Service-Type",
"Authenticate-Only",
T_OP_SET);
3460 "Message-Authenticator",
"0x00",
T_OP_SET);
3462 #ifdef WITH_ACCOUNTING
3469 "Acct-Status-Type",
"Stop",
T_OP_SET);
3471 "Acct-Session-Id",
"00000000",
T_OP_SET);
3474 vp->vp_date = now->tv_sec;
3481 talloc_free(request);
3499 #ifdef DEBUG_STATE_MACHINE
3500 if (
rad_debug_lvl) printf(
"(%u) ********\tSTATE %s C-%s -> C-%s\t********\n", request->
number, __FUNCTION__,
3503 if (
rad_debug_lvl) printf(
"(%u) ********\tNEXT-STATE %s -> %s\n", request->
number, __FUNCTION__,
"request_ping");
3505 #ifdef HAVE_PTHREAD_H
3506 rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
3514 RPROXY(
"Failed to insert status check %d into proxy list. Discarding it.",
3520 talloc_free(request);
3530 DEBUG(
"PING: Waiting %u seconds for response to ping",
3559 my_request = talloc_zero(NULL,
REQUEST);
3566 talloc_free(my_request);
3572 char buffer[INET6_ADDRSTRLEN];
3580 if (home->
proto == IPPROTO_TCP) {
3581 WARN(
"Not marking TCP server %s zombie", home->
log_name);
3597 DEBUG(
"Received reply from home server %d seconds ago. Might not be zombie.",
3617 PROXY(
"Marking home server %s port %d as zombie (it has not responded in %d.%06d seconds).",
3619 buffer,
sizeof(buffer)),
3620 home->
port, (
int) response_window->tv_sec, (
int) response_window->tv_usec);
3629 char buffer[INET6_ADDRSTRLEN];
3647 PROXY(
"Marking home server %s port %d alive again... we have no idea if it really is alive or not.",
3654 int previous_state = home->
state;
3655 char buffer[INET6_ADDRSTRLEN];
3658 if (home->
proto == IPPROTO_TCP) {
3659 WARN(
"Not marking TCP server dead");
3664 PROXY(
"Marking home server %s port %d as dead",
3666 buffer,
sizeof(buffer)),
3681 gettimeofday(&now, NULL);
3684 DEBUG(
"PING: Already pinging home server %s", home->
log_name);
3722 struct timeval now, when;
3723 struct timeval *response_window = NULL;
3725 char buffer[INET6_ADDRSTRLEN];
3735 gettimeofday(&now, NULL);
3771 if (home->
proto == IPPROTO_TCP) {
3772 DEBUG2(
"Suppressing duplicate proxied request (tcp) to home server %s port %d proto TCP - ID: %d",
3775 buffer,
sizeof(buffer)),
3789 if (timercmp(&now, &when, <)) {
3790 DEBUG2(
"Suppressing duplicate proxied request (too fast) to home server %s port %d proto TCP - ID: %d",
3793 buffer,
sizeof(buffer)),
3799 #ifdef WITH_ACCOUNTING
3811 RDEBUG2(
"Sending duplicate proxied request to home server %s port %d - ID: %d",
3814 buffer,
sizeof(buffer)),
3838 if (timercmp(&when, &now, >)) {
3839 RDEBUG(
"Waiting for client retransmission in order to do a proxy retransmit");
3855 timeradd(&when, response_window, &when);
3861 if (timercmp(&when, &now, >)) {
3862 struct timeval diff;
3863 timersub(&when, &now, &diff);
3865 RDEBUG(
"Expecting proxy response no later than %d.%06d seconds from now",
3866 (
int) diff.tv_sec, (
int) diff.tv_usec);
3872 RDEBUG(
"No proxy response, giving up on request and marking it done");
3889 && (home->
proto != IPPROTO_TCP)
3932 RERROR(
"Failing proxied request for user \"%s\", due to lack of any response from home "
3933 "server %s port %d",
3937 buffer,
sizeof(buffer)),
3940 RERROR(
"Failing proxied request, due to lack of any response from home server %s port %d",
3943 buffer,
sizeof(buffer)),
3963 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
3986 int rcode, pre_proxy_type = 0;
4007 if (vp->vp_integer == 0) {
4009 TALLOC_FREE(request->
coa);
4019 memset(&ipaddr, 0,
sizeof(ipaddr));
4022 ipaddr.
af = AF_INET;
4023 ipaddr.
ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
4026 ipaddr.
af = AF_INET6;
4027 ipaddr.
ipaddr.ip6addr = vp->vp_ipv6addr;
4033 RWDEBUG2(
"No such home_server_pool %s",
4068 char buffer[INET6_ADDRSTRLEN];
4071 if (vp) port = vp->vp_integer;
4075 RWDEBUG2(
"Unknown destination %s:%d for CoA request",
4077 buffer,
sizeof(buffer)), port);
4084 switch (vp->vp_integer) {
4091 DEBUG(
"Cannot set CoA Packet-Type to code %d",
4124 pre_proxy_type = vp->vp_integer;
4128 char const *old_server = coa->
server;
4136 coa->
server = old_server;
4191 #ifdef DEBUG_STATE_MACHINE
4192 if (
rad_debug_lvl) printf(
"(%u) ********\tSTATE %s C-%s -> C-%s\t********\n", request->
number, __FUNCTION__,
4204 #ifdef HAVE_PTHREAD_H
4205 coa->child_pid = NO_SUCH_CHILD_PID;
4219 uint32_t delay, frac;
4220 struct timeval now, when, mrd;
4221 char buffer[INET6_ADDRSTRLEN];
4227 if (request->
delay == 0) {
4238 delay = (
fr_rand() & ((1 << 22) - 1)) / 10;
4241 delay -= delay / 10;
4242 delay += request->
delay;
4243 request->
delay = delay;
4246 tv_add(&when, delay);
4248 if (timercmp(&when, &now, >)) {
4263 RERROR(
"Failing request - originate-coa ID %u, due to lack of any response from coa server %s port %d",
4267 buffer,
sizeof(buffer)),
4286 delay ^= (delay >> 16);
4288 frac = request->
delay / 5;
4289 delay = ((frac >> 16) * delay) + (((frac & 0xffff) * delay) >> 16);
4291 delay += (2 * request->
delay) - (request->
delay / 10);
4305 delay ^= (delay >> 15);
4307 delay = ((mrt_usec >> 16) * delay) + (((mrt_usec & 0xffff) * delay) >> 16);
4308 delay += mrt_usec - (mrt_usec / 10);
4311 request->
delay = delay;
4313 tv_add(&when, request->
delay);
4320 if (timercmp(&mrd, &when, <)) {
4329 RDEBUG2(
"Sending duplicate CoA request to home server %s port %d - ID: %d",
4332 buffer,
sizeof(buffer)),
4381 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
4389 #ifdef DEBUG_STATE_MACHINE
4404 (void) talloc_steal(NULL, request);
4433 char buffer[INET6_ADDRSTRLEN];
4446 RDEBUG2(
"Reply from CoA server %s port %d - ID: %d arrived too late.",
4449 buffer,
sizeof(buffer)),
4455 request->
handle(request);
4461 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
4496 request->
handle(request);
4502 RDEBUG3(
"%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
4525 if ((listener->
fd < 0)
4527 #ifndef WITH_DETAIL_THREAD
4534 listener->
print(listener, buffer,
sizeof(buffer));
4535 ERROR(
"FATAL: Asked to read from closed socket: %s",
4542 listener->
recv(listener);
4546 #ifdef WITH_DETAIL_THREAD
4556 struct timeval when;
4571 delay = this->encode(
this, NULL);
4572 if (delay == 0)
goto redo;
4574 tv_add(&when, delay);
4578 &when, &detail->ev)) {
4579 ERROR(
"Failed creating handler");
4588 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
4594 INFO(
"Ready to process requests");
4595 just_started =
false;
4601 INFO(
"Ready to process requests");
4603 }
else if ((wake->tv_sec != 0) ||
4604 (wake->tv_usec >= 100000)) {
4605 DEBUG(
"Waking up in %d.%01u seconds.",
4606 (
int) wake->tv_sec, (
unsigned int) wake->tv_usec / 100000);
4615 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
4622 while (waitpid(-1, &argval, WNOHANG) > 0) {
4635 if (this->count > 0) {
4636 struct timeval when;
4655 this->print(
this, buffer,
sizeof(buffer));
4656 DEBUG(
"... cleaning up socket %s", buffer);
4665 struct timeval when;
4668 if (request->proxy_listener != ctx)
return 0;
4674 #ifdef WITH_ACCOUNTING
4680 RDEBUG(
"Stopping request due to failed connection to home server");
4710 this->print(
this, buffer,
sizeof(buffer));
4717 DEBUG(
"Listening on %s", buffer);
4719 INFO(
" ... adding new socket %s", buffer);
4728 INFO(
" ... adding new socket %s", buffer);
4730 INFO(
" ... adding new socket %s (%u of %u)", buffer,
4737 switch (this->type) {
4746 #ifndef WITH_DETAIL_THREAD
4750 gettimeofday(&now, NULL);
4777 struct timeval when;
4779 when.tv_sec = sock->
opened + 1;
4803 struct timeval when;
4805 when.tv_sec = sock->
opened + 1;
4841 if (this->count > 0) {
4842 struct timeval when;
4849 gettimeofday(&when, NULL);
4855 this, &when, &sock->ev)) {
4887 if (this->count > 0) {
4898 if (this->count > 0) {
4899 struct timeval when;
4906 gettimeofday(&when, NULL);
4912 this, &when, &sock->ev)) {
4934 struct timeval when;
4950 devnull = open(
"/dev/null", O_RDWR);
4952 ERROR(
"FATAL failure opening /dev/null: %s",
4956 if (dup2(devnull, this->fd) < 0) {
4957 ERROR(
"FATAL failure closing socket: %s",
4979 INFO(
" ... shutting down socket %s", buffer);
4981 INFO(
" ... shutting down socket %s (%u of %u)", buffer,
4989 ERROR(
"Fatal error removing socket %s: %s",
4997 INFO(
" ... shutting down socket %s", buffer);
5008 if (!spawn_workers) {
5018 gettimeofday(&when, NULL);
5044 INFO(
"Signalled to exit");
5047 INFO(
"Signalled to terminate");
5059 static time_t last_hup = 0;
5062 if ((
int) (when - last_hup) < 5) {
5063 INFO(
"Ignoring HUP (less than 5s since last one)");
5067 INFO(
"Received HUP signal");
5075 #if defined(WITH_DETAIL) && !defined(WITH_DETAIL_THREAD)
5084 this = this->
next) {
5093 if (!this->decode(
this, NULL))
continue;
5095 gettimeofday(&now, NULL);
5104 #if defined(WITH_TCP) && defined(WITH_PROXY) && defined(HAVE_PTHREAD_H)
5118 for (
this = new_listeners;
this != NULL;
this = next) {
5125 new_listeners = NULL;
5131 #ifndef HAVE_PTHREAD_H
5151 rcode = read(self_pipe[0], buffer,
sizeof(buffer));
5155 for (i = 0; i < rcode; i++) {
5156 buffer[0] |= buffer[i];
5164 if (write(self_pipe[1], buffer, 1) < 0)
fr_exit(0);
5174 rcode = read(self_pipe[0], buffer,
sizeof(buffer));
5175 if (rcode <= 0)
return;
5180 for (i = 0; i < rcode; i++) {
5181 buffer[0] |= buffer[i];
5224 memset(&home, 0,
sizeof(home));
5229 home.
proto = IPPROTO_UDP;
5251 ERROR(
"Failed adding proxy socket");
5267 bool has_v4, has_v6;
5275 defined_proxy = has_v4 = has_v6 =
false;
5281 for (
this = head;
this != NULL;
this = this->next) {
5284 switch (this->type) {
5286 defined_proxy =
true;
5298 if (sock->
my_ipaddr.
af == AF_INET6) has_v6 =
true;
5309 if (defined_proxy)
return;
5321 if (fr_start_time != (time_t)-1)
return 0;
5323 time(&fr_start_time);
5335 request_num_counter = 0;
5344 if (!proxy_list)
return 0;
5346 #ifdef HAVE_PTHREAD_H
5348 ERROR(
"FATAL: Failed to initialize proxy mutex: %s",
5364 proxy_ctx = talloc_init(
"proxy");
5373 spawn_workers = have_children;
5375 #ifdef HAVE_PTHREAD_H
5376 NO_SUCH_CHILD_PID = pthread_self();
5380 DEBUG(
"%s: #### Skipping IP addresses and Ports ####",
5385 #ifdef HAVE_PTHREAD_H
5390 if (pipe(self_pipe) < 0) {
5394 if ((fcntl(self_pipe[0], F_SETFL, O_NONBLOCK) < 0) ||
5395 (fcntl(self_pipe[0], F_SETFD, FD_CLOEXEC) < 0)) {
5399 if ((fcntl(self_pipe[1], F_SETFL, O_NONBLOCK) < 0) ||
5400 (fcntl(self_pipe[1], F_SETFD, FD_CLOEXEC) < 0)) {
5404 DEBUG4(
"Created signal pipe. Read end FD %i, write end FD %i", self_pipe[0], self_pipe[1]);
5452 #ifdef HAVE_PTHREAD_H
5453 if (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0)
return 0;
5491 #ifdef HAVE_PTHREAD_H
5492 if (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0)
return 0;
5504 RDEBUG2(
"Cleaning up request packet ID %u with timestamp +%d",
5506 (
unsigned int) (request->
timestamp.tv_sec - fr_start_time));
5540 if (spawn_workers) {
5553 ERROR(
"Proxy list has %d requests still in it.", num);
5561 ERROR(
"Request list has %d requests still in it.", num);
5573 if (proxy_ctx) talloc_free(proxy_ctx);
5578 if (debug_condition) talloc_free(debug_condition);
void home_server_update_request(home_server_t *home, REQUEST *request)
void fr_pair_list_free(VALUE_PAIR **)
Free memory used by a valuepair list.
static int insert_into_proxy_hash(REQUEST *request)
struct timeval reject_delay
How long to wait before sending an Access-Reject.
fr_state_action_t timer_action
What action to perform when the timer event fires.
static void proxy_reply_too_late(REQUEST *request)
REALM * realm_find2(char const *name)
int sockfd
Socket this packet was read from.
struct timeval response_delay
How long to wait before sending Access-Rejects.
2nd highest priority debug messages (-xx | -X).
fr_ipaddr_t src_ipaddr
Resolved version of src_ipaddr_str.
#define pthread_mutex_init(_x, _y)
rad_master_state_t master_state
Set by the master thread to signal the child that's currently working with the request, to do something.
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
static bool request_max_time(REQUEST *request)
bool home_servers_udp
Whether there are any UDP home servers.
int id
Packet ID (used to link requests/responses).
#define RINDENT()
Indent R* messages by one level.
struct timeval timestamp
When we received the packet.
char const * ping_user_name
bool proxy_requests
Toggle to enable/disable proxying globally.
void rbtree_free(rbtree_t *tree)
#define FR_STATS_TYPE_INC(_x)
#define we_are_master(_x)
static void check_proxy(rad_listen_t *head)
RFC2865 - Access-Challenge.
Main server configuration.
int fr_event_fd_delete(fr_event_list_t *el, int type, int fd)
RADIUS_PACKET * fr_radius_copy(TALLOC_CTX *ctx, RADIUS_PACKET const *in)
Duplicate a RADIUS_PACKET.
RADIUS_PACKET * proxy_reply
Incoming response from proxy server.
struct rad_request::@7 log
fr_stats_t proxy_acct_stats
bool fr_packet_list_id_free(fr_packet_list_t *pl, RADIUS_PACKET *request, bool yank)
static fr_packet_list_t * proxy_list
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().
The module is OK, continue.
static void request_cleanup_delay_init(REQUEST *request)
void rad_suid_down_permanent(void)
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.
static fr_event_list_t * el
void(* fr_event_callback_t)(void *, struct timeval *now)
static int proxy_to_virtual_server(REQUEST *request)
char const * ping_user_password
char const * fr_packet_codes[FR_MAX_PACKET_CODE]
int rad_postauth(REQUEST *)
uint32_t fr_rand(void)
Return a 32-bit random number.
#define FD_MUTEX_UNLOCK(_x)
void revive_home_server(void *ctx, UNUSED struct timeval *now)
fr_ipaddr_t src_ipaddr
Src IP address of packet.
static void create_default_proxy_listener(int af)
RADIUS_PACKET ** fr_packet_list_find_byreply(fr_packet_list_t *pl, RADIUS_PACKET *reply)
void radius_event_free(void)
uint8_t prefix
Prefix length - Between 0-32 for IPv4 and 0-128 for IPv6.
uint32_t talloc_pool_size
Size of pool to allocate to hold each REQUEST.
fr_event_t * ev
Event in event loop tied to this request.
static void event_poll_detail(void *ctx, struct timeval *now)
VALUE_PAIR * radius_pair_create(TALLOC_CTX *ctx, VALUE_PAIR **vps, unsigned int attribute, unsigned int vendor)
Create a VALUE_PAIR and add it to a list of VALUE_PAIR s.
static int setup_post_proxy_fail(REQUEST *request)
home_pool_t * coa_pool
The CoA home_pool_t the client is associated with.
static void remove_from_proxy_hash_nl(REQUEST *request, bool yank)
VALUE_PAIR * username
Cached username VALUE_PAIR from request RADIUS_PACKET.
static void mark_home_server_zombie(home_server_t *home, struct timeval *now, struct timeval *response_window)
#define REDEBUG2(fmt,...)
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
#define pair_make_request(_a, _b, _c)
uint32_t num_pings_to_alive
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
VALUE_PAIR * fr_cursor_init(vp_cursor_t *cursor, VALUE_PAIR *const *node)
Setup a cursor to iterate over attribute pairs.
static void event_socket_handler(fr_event_list_t *xel, UNUSED int fd, void *ctx)
void mark_home_server_dead(home_server_t *home, struct timeval *when)
static void remove_from_proxy_hash(REQUEST *request)
static REQUEST * request_setup(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *packet, RADCLIENT *client, RAD_REQUEST_FUNP fun)
char const * fr_dict_enum_name_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int value)
Lookup the name of an enum value in a fr_dict_attr_t.
static void tcp_socket_timer(void *ctx, struct timeval *now)
int simul_max
Maximum number of concurrent sessions for this user.
fr_stats_t auth
Authentication stats.
bool fr_packet_list_socket_del(fr_packet_list_t *pl, int sockfd)
VALUE_PAIR * password
Cached password VALUE_PAIR from request RADIUS_PACKET.
rad_listen_t * listener
The listener that received the request.
static void request_running(REQUEST *request, int action)
Process a request from a client.
uint32_t num_proxied_responses
void * rbtree_finddata(rbtree_t *tree, void const *data)
Find the user data.
#define VERIFY_REQUEST(_x)
The module considers the request invalid.
static void proxy_running(REQUEST *request, int action)
Process the request after receiving a proxy reply.
char const * name
Name of the daemon, usually 'radiusd'.
#define TRACE_STATE_MACHINE
unsigned int number
Monotonically increasing request number. Reset on server restart.
uint8_t * data
Packet data (body).
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.
fr_event_list_t * fr_event_list_create(TALLOC_CTX *ctx, fr_event_status_t status)
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.
fr_request_process_t process
The function to call to move the request through the state machine.
static void request_free(REQUEST *request)
static void request_dup(REQUEST *request)
static void listener_free_cb(void *ctx, UNUSED struct timeval *now)
int fr_event_now(fr_event_list_t *el, struct timeval *when)
REQUEST * request_alloc_fake(REQUEST *oldreq)
int fr_event_fd_insert(fr_event_list_t *el, int type, int fd, fr_event_fd_handler_t handler, void *ctx)
fr_dict_enum_t * fr_dict_enum_by_name(fr_dict_t *dict, fr_dict_attr_t const *da, char const *val)
static int process_proxy_reply(REQUEST *request, RADIUS_PACKET *reply)
Abstraction to allow iterating over different configurations of VALUE_PAIRs.
#define FR_STATS_INC(_x, _y)
uint32_t num_coa_requests
Counter for number of requests sent including.
fr_stats_t proxy_dsc_stats
int radius_event_init(TALLOC_CTX *ctx)
void vradlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg, va_list ap) CC_HINT(format(printf
uint32_t magic
Magic number used to detect memory corruption, or request structs that have not been properly initial...
#define REQUEST_MASTER_NUM_STATES
static void request_done(REQUEST *request, int action)
Mark a request DONE and clean it up.
Authentication and accounting server.
uint32_t response_timeouts
static void proxy_no_reply(REQUEST *request, int action)
Process a request after the proxy has timed out.
struct timeval proxy_retransmit
RADIUS_PACKET * proxy
Outgoing request to proxy server.
char const * server
For internal proxying.
static int event_new_fd(rad_listen_t *this)
main_config_t * root
Pointer to the main config hack to try and deal with hup.
Reject the request (user is locked out).
#define FD_MUTEX_LOCK(_x)
fr_cond_t * debug_condition
RFC2865 - Access-Request.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define STATE_MACHINE_TIMER(_x)
Insert REQUEST back into the event heap, to continue executing at a future time.
VALUE_PAIR * fr_pair_list_copy(TALLOC_CTX *ctx, VALUE_PAIR *from)
Copy a pairlist.
static void event_status(struct timeval *wake)
home_pool_t * home_pool
For dynamic failover.
home_server_t * home_server_ldb(char const *realmname, home_pool_t *pool, REQUEST *request)
#define RAD_REQUEST_OPTION_COA
rbtree_t * rbtree_create(TALLOC_CTX *ctx, rb_comparator_t compare, rb_free_t node_free, int flags)
Create a new RED-BLACK tree.
static int null_handler(UNUSED REQUEST *request)
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 request_finish(REQUEST *request, int action)
Do the final processing of a request before we reply to the NAS.
void fr_pair_value_strcpy(VALUE_PAIR *vp, char const *src)
Copy data into an "string" data type.
static void coa_no_reply(REQUEST *request, int action)
Process a request after the CoA has timed out.
uint32_t max_request_time
How long a request can be processed for before timing out.
void fr_cursor_merge(vp_cursor_t *cursor, VALUE_PAIR *vp)
Merges multiple VALUE_PAIR into the cursor.
#define REQUEST_CHILD_NUM_STATES
char const * component
Section the request is in.
struct timeval revive_time
void radius_update_listener(rad_listen_t *this)
#define pair_make_config(_a, _b, _c)
void fr_pair_add(VALUE_PAIR **head, VALUE_PAIR *vp)
Add a VP to the end of the list.
uint32_t num_proxied_requests
How many times this request was proxied.
RFC2866 - Accounting-Request.
uint32_t cleanup_delay
How long before cleaning up cached responses.
RADIUS_PACKET * fr_radius_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new RADIUS_PACKET.
unsigned int attr
Attribute number.
REQUEST * coa
CoA request originated by this request.
Immediately reject the request.
static void add_jitter(struct timeval *when)
union fr_ipaddr_t::@1 ipaddr
RFC3575/RFC5176 - CoA-Nak (not willing to perform)
unsigned int code
Packet code (type).
int fr_packet_list_walk(fr_packet_list_t *pl, void *ctx, rb_walker_t callback)
static RADIUS_PACKET my_packet
int rbtree_walk(rbtree_t *tree, rb_order_t order, rb_walker_t compare, void *context)
static void request_coa_originate(REQUEST *request)
fr_stats_t proxy_auth_stats
static int eol_proxy_listener(void *ctx, void *data)
static void request_timer(void *ctx, struct timeval *now)
static void ping_home_server(void *ctx, struct timeval *now)
Stores an attribute, a value and various bits of other data.
rlm_rcode_t process_pre_proxy(int type, REQUEST *request)
static void home_trigger(home_server_t *home, char const *trigger)
rlm_rcode_t process_post_proxy(int type, REQUEST *request)
static void coa_wait_for_reply(REQUEST *request, int action)
Wait for a reply after originating a CoA a request.
RADIUS_PACKET * reply
Outgoing response.
#define PTHREAD_MUTEX_LOCK(_x)
rad_listen_t * proxy_new_listener(TALLOC_CTX *ctx, home_server_t *home, uint16_t src_port)
static NEVER_RETURNS void _rad_panic(char const *file, unsigned int line, char const *msg)
#define REXDENT()
Exdent (unindent) R* messages by one level.
CoA destination (NAS or Proxy)
static TALLOC_CTX * proxy_ctx
#define VERIFY_PACKET(_x)
bool memory_report
Print a memory report on what's left unfreed.
static int proxy_delete_cb(UNUSED void *ctx, void *data)
fr_packet_list_t * fr_packet_list_create(int alloc_id)
static int request_will_proxy(REQUEST *request) CC_HINT(nonnull)
Determine if a REQUEST needs to be proxied, and perform pre-proxy operations.
RFC3575/RFC5176 - CoA-Request.
void radius_signal_self(int flag)
uint8_t vector[AUTH_VECTOR_LEN]
RADIUS authentication vector.
char const * fr_strerror(void)
Get the last library error.
#define RWDEBUG2(fmt,...)
void request_stats_final(REQUEST *request)
uint32_t fr_packet_list_num_elements(fr_packet_list_t *pl)
void radlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg,...) CC_HINT(format(printf
fr_uint_t total_responses
fr_event_list_t * radius_event_list_corral(UNUSED event_corral_t hint)
static int packet_entry_cmp(void const *one, void const *two)
void fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int attr, int8_t tag)
Delete matching pairs.
char const * log_name
The name used for log messages.
Module succeeded without doing anything.
int if_index
Index of receiving interface.
void(* fr_request_process_t)(REQUEST *, int)
Describes a host allowed to send packets to the server.
static void proxy_wait_for_reply(REQUEST *request, int action)
Wait for a reply after proxying a request.
#define STATE_MACHINE_DECL(_x)
Declare a state in the state machine.
static int request_pre_handler(REQUEST *request, UNUSED int action)
static bool spawn_workers
rad_listen_t * proxy_listener
Listener for outgoing requests.
Module failed, don't reply.
int request_receive(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *packet, RADCLIENT *client, RAD_REQUEST_FUNP fun)
fr_stats_t radius_acct_stats
rad_listen_decode_t decode
static void mark_home_server_alive(REQUEST *request, home_server_t *home)
home_ping_check_t ping_check
What method we use to perform the 'ping' none, status-server or fake request.
struct timeval timestamp
When we started processing the request.
void fr_packet_list_free(fr_packet_list_t *pl)
static int self_pipe[2]
Signals from sig handlers.
bool fr_packet_list_id_alloc(fr_packet_list_t *pl, int proto, RADIUS_PACKET **request_p, void **pctx)
log_lvl_t rad_debug_lvl
Global debugging level.
bool fr_request_to_state(fr_state_tree_t *state, REQUEST *request, RADIUS_PACKET *original, RADIUS_PACKET *packet)
Transfer ownership of the state VALUE_PAIRs and ctx, back to a state entry.
uint32_t num_received_pings
int radius_event_start(bool have_children)
static void request_response_delay(REQUEST *request, int action)
Sit on a request until it's time to respond to it.
static int request_init_delay(REQUEST *request)
static int eol_listener(void *ctx, void *data)
#define PTHREAD_MUTEX_UNLOCK(_x)
fr_uint_t total_access_accepts
size_t data_len
Length of packet data.
static void coa_retransmit(REQUEST *request)
bool rbtree_insert(rbtree_t *tree, void *data)
#define RAD_REQUEST_OPTION_CTX
static void request_ping(REQUEST *request, int action)
Ping a home server.
#define INSERT_EVENT(_function, _ctx)
fr_uint_t total_access_challenges
int fr_event_loop(fr_event_list_t *el)
RADIUS_PACKET * packet
Incoming request.
static void handle_signal_self(int flag)
char const * virtual_server
static struct timeval * request_response_window(REQUEST *request)
fr_dict_enum_t * fr_dict_enum_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
#define RATE_LIMIT(_x)
Rate limit messages.
bool fr_packet_list_socket_freeze(fr_packet_list_t *pl, int sockfd)
home_server_t * coa_server
The CoA home_server_t the client is associated with.
void listen_free(rad_listen_t **head)
Free a linked list of listeners.
struct timeval init_delay
Initial request processing delay.
static int proxy_eol_cb(void *ctx, void *data)
static char const * action_codes[]
main_config_t main_config
Main server configuration.
static int request_proxy_anew(REQUEST *request)
uint32_t currently_outstanding
uint32_t max_response_timeouts
int delay
incrementing delay for various timers
static void coa_running(REQUEST *request, int action)
Process the request after receiving a coa reply.
rad_listen_t * listen
Head of a linked list of listeners.
static void request_cleanup_delay(REQUEST *request, int action)
Sit on a request until it's time to clean it up.
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.
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)
home_server_t * home_server
int fr_event_delete(fr_event_list_t *el, fr_event_t **parent)
static int request_delete_cb(UNUSED void *ctx, void *data)
RFC2865/RFC5997 - Status Server (request)
struct timeval response_window
How long the client has to respond.
RAD_REQUEST_FUNP handle
The function to call to move the request through the various server configuration sections...
fr_stats_t acct
Accounting stats.
static int request_proxy(REQUEST *request, int retransmit) CC_HINT(nonnull)
fr_stats_t proxy_coa_stats
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
static void coa_separate(REQUEST *request)
int listen_init(rad_listen_t **head, bool spawn_flag)
Search for listeners in the server.
int radius_evaluate_cond(REQUEST *request, int modreturn, int depth, fr_cond_t const *c)
Evaluate a fr_cond_t;.
home_pool_t * home_pool_byname(char const *name, int type)
struct timeval zombie_period_start
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.
void fr_event_loop_exit(fr_event_list_t *el, int code)
int fr_event_insert(fr_event_list_t *el, fr_event_callback_t callback, void *ctx, struct timeval *when, fr_event_t **parent)
fr_uint_t total_access_rejects
RADCLIENT * client
The client that originally sent us the request.
RFC3575/RFC5176 - Disconnect-Nak (not willing to perform)
fr_stats_t radius_auth_stats
char const * server
Virtual server client is associated with.
static int request_num_counter
uint32_t revive_interval
How often we revive it (if it doesn't support pings).
home_type_t type
Auth, Acct, CoA etc.
The module handled the request, so stop.
int request_proxy_reply(RADIUS_PACKET *packet)
char const * module
Module the request is currently being processed by.
void fr_pair_value_snprintf(VALUE_PAIR *vp, char const *fmt,...) CC_HINT(format(printf
VALUE_PAIR * fr_pair_make(TALLOC_CTX *ctx, VALUE_PAIR **vps, char const *attribute, char const *value, FR_TOKEN op)
Create a VALUE_PAIR from ASCII strings.
rad_child_state_t child_state
uint32_t rad_pps(uint32_t *past, uint32_t *present, time_t *then, struct timeval *now)
int radius_event_process(void)
uint32_t options
mainly for proxying EAP-MSCHAPv2.
uint32_t zombie_period
Unresponsive for T, mark it dead.
static void state_machine_timer(char const *file, int line, REQUEST *request, struct timeval *when, fr_state_action_t action)
Insert REQUEST back into the event heap, to continue executing at a future time.
fr_state_tree_t * global_state
Value of an enumerated attribute.
#define fr_packet2myptr(TYPE, MEMBER, PTR)
fr_ipaddr_t ipaddr
IP address of home server.
void fr_pair_value_memcpy(VALUE_PAIR *vp, uint8_t const *src, size_t len)
Copy data into an "octets" data type.
REQUEST * request_alloc(TALLOC_CTX *ctx)
Create a new REQUEST data structure.
rad_listen_encode_t encode
char const * shortname
Client nickname.
static void request_queue_or_run(REQUEST *request, fr_request_process_t process)
struct timeval response_window
RFC3575/RFC5176 - Disconnect-Request.
int fr_packet_cmp(RADIUS_PACKET const *a, RADIUS_PACKET const *b)
uint32_t rbtree_num_elements(rbtree_t *tree)