"Fossies" - the Fresh Open Source Software Archive

Member "freeradius-server-3.0.23/src/main/process.c" (10 Jun 2021, 153033 Bytes) of package /linux/misc/freeradius-server-3.0.23.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "process.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.0.22_vs_3.0.23.

    1 /*
    2  *   This program is free software; you can redistribute it and/or modify
    3  *   it under the terms of the GNU General Public License as published by
    4  *   the Free Software Foundation; either version 2 of the License, or
    5  *   (at your option) any later version.
    6  *
    7  *   This program is distributed in the hope that it will be useful,
    8  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10  *   GNU General Public License for more details.
   11  *
   12  *   You should have received a copy of the GNU General Public License
   13  *   along with this program; if not, write to the Free Software
   14  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
   15  */
   16 
   17 /**
   18  * $Id: da2b614e0806cb1f2689ff172c04905956c38f59 $
   19  *
   20  * @file process.c
   21  * @brief Defines the state machines that control how requests are processed.
   22  *
   23  * @copyright 2012  The FreeRADIUS server project
   24  * @copyright 2012  Alan DeKok <aland@deployingradius.com>
   25  */
   26 
   27 RCSID("$Id: da2b614e0806cb1f2689ff172c04905956c38f59 $")
   28 
   29 #include <freeradius-devel/radiusd.h>
   30 #include <freeradius-devel/process.h>
   31 #include <freeradius-devel/modules.h>
   32 #include <freeradius-devel/state.h>
   33 
   34 #include <freeradius-devel/rad_assert.h>
   35 
   36 #ifdef WITH_DETAIL
   37 #include <freeradius-devel/detail.h>
   38 #endif
   39 
   40 #include <signal.h>
   41 #include <fcntl.h>
   42 
   43 #ifdef HAVE_SYS_WAIT_H
   44 #   include <sys/wait.h>
   45 #endif
   46 
   47 #ifdef HAVE_SYSTEMD_WATCHDOG
   48 #  include <systemd/sd-daemon.h>
   49 #endif
   50 
   51 extern pid_t radius_pid;
   52 extern fr_cond_t *debug_condition;
   53 
   54 #ifdef HAVE_SYSTEMD_WATCHDOG
   55 struct timeval sd_watchdog_interval;
   56 static fr_event_t *sd_watchdog_ev;
   57 #endif
   58 
   59 static bool spawn_flag = false;
   60 static bool just_started = true;
   61 time_t fr_start_time = (time_t)-1;
   62 static rbtree_t *pl = NULL;
   63 static fr_event_list_t *el = NULL;
   64 
   65 fr_event_list_t *radius_event_list_corral(UNUSED event_corral_t hint) {
   66     /* Currently we do not run a second event loop for modules. */
   67     return el;
   68 }
   69 
   70 static char const *action_codes[] = {
   71     "INVALID",
   72     "run",
   73     "done",
   74     "dup",
   75     "timer",
   76 #ifdef WITH_PROXY
   77     "proxy-reply"
   78 #endif
   79 };
   80 
   81 #ifdef DEBUG_STATE_MACHINE
   82 #  define TRACE_STATE_MACHINE \
   83 if (rad_debug_lvl) do { \
   84     struct timeval debug_tv; \
   85     gettimeofday(&debug_tv, NULL); \
   86     debug_tv.tv_sec -= fr_start_time; \
   87     printf("(%u) %d.%06d ********\tSTATE %s action %s live M-%s C-%s\t********\n",\
   88            request->number, (int) debug_tv.tv_sec, (int) debug_tv.tv_usec, \
   89            __FUNCTION__, action_codes[action], master_state_names[request->master_state], \
   90            child_state_names[request->child_state]); \
   91 } while (0)
   92 
   93 static char const *master_state_names[REQUEST_MASTER_NUM_STATES] = {
   94     "?",
   95     "active",
   96     "stop-processing",
   97     "counted"
   98 };
   99 
  100 static char const *child_state_names[REQUEST_CHILD_NUM_STATES] = {
  101     "?",
  102     "queued",
  103     "running",
  104     "proxied",
  105     "reject-delay",
  106     "cleanup-delay",
  107     "done"
  108 };
  109 
  110 #else
  111 #  define TRACE_STATE_MACHINE {}
  112 #endif
  113 
  114 static NEVER_RETURNS void _rad_panic(char const *file, unsigned int line, char const *msg)
  115 {
  116     ERROR("%s[%u]: %s", file, line, msg);
  117     fr_exit_now(1);
  118 }
  119 
  120 #define rad_panic(x) _rad_panic(__FILE__, __LINE__, x)
  121 
  122 /** Declare a state in the state machine
  123  *
  124  * Expands to the start of a function definition for a given state.
  125  *
  126  * @param _x the name of the state.
  127  */
  128 #define STATE_MACHINE_DECL(_x) static void _x(REQUEST *request, int action)
  129 
  130 static void request_timer(void *ctx);
  131 
  132 /** Insert #REQUEST back into the event heap, to continue executing at a future time
  133  *
  134  * @param file the state machine timer call occurred in.
  135  * @param line the state machine timer call occurred on.
  136  * @param request to set add the timer event for.
  137  * @param when the event should fine.
  138  * @param action to perform when we resume processing the request.
  139  */
  140 static inline void state_machine_timer(char const *file, int line, REQUEST *request,
  141                        struct timeval *when, fr_state_action_t action)
  142 {
  143     request->timer_action = action;
  144     if (!fr_event_insert(el, request_timer, request, when, &request->ev)) {
  145         _rad_panic(file, line, "Failed to insert event");
  146     }
  147 }
  148 
  149 /** @copybrief state_machine_timer
  150  *
  151  * @param _x the action to perform when we resume processing the request.
  152  */
  153 #define STATE_MACHINE_TIMER(_x) state_machine_timer(__FILE__, __LINE__, request, &when, _x)
  154 
  155 /*
  156  *  We need a different VERIFY_REQUEST macro in process.c
  157  *  To avoid the race conditions with the master thread
  158  *  checking the REQUEST whilst it's being worked on by
  159  *  the child.
  160  */
  161 #if defined(WITH_VERIFY_PTR) && defined(HAVE_PTHREAD_H)
  162 #  undef VERIFY_REQUEST
  163 #  define VERIFY_REQUEST(_x) if (pthread_equal(pthread_self(), _x->child_pid) != 0) verify_request(__FILE__, __LINE__, _x)
  164 #endif
  165 
  166 /**
  167  * @section request_timeline
  168  *
  169  *  Time sequence of a request
  170  * @code
  171  *
  172  *  RQ-----------------P=============================Y-J-C
  173  *   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::M
  174  * @endcode
  175  *
  176  * -    R: received.  Duplicate detection is done, and request is
  177  *     cached.
  178  *
  179  * -    Q: Request is placed onto a queue for child threads to pick up.
  180  *     If there are no child threads, the request goes immediately
  181  *     to P.
  182  *
  183  * -    P: Processing the request through the modules.
  184  *
  185  * -    Y: Reply is ready.  Rejects MAY be delayed here.  All other
  186  *     replies are sent immediately.
  187  *
  188  * -    J: Reject is sent "response_delay" after the reply is ready.
  189  *
  190  * -    C: For Access-Requests, After "cleanup_delay", the request is
  191  *     deleted.  Accounting-Request packets go directly from Y to C.
  192  *
  193  * -    M: Max request time.  If the request hits this timer, it is
  194  *     forcibly stopped.
  195  *
  196  *  Other considerations include duplicate and conflicting
  197  *  packets.  When a dupicate packet is received, it is ignored
  198  *  until we've reached Y, as no response is ready.  If the reply
  199  *  is a reject, duplicates are ignored until J, when we're ready
  200  *  to send the reply.  In between the reply being sent (Y or J),
  201  *  and C, the server responds to duplicates by sending the cached
  202  *  reply.
  203  *
  204  *  Conflicting packets are sent in 2 situations.
  205  *
  206  *  The first is in between R and Y.  In that case, we consider
  207  *  it as a hint that we're taking too long, and the NAS has given
  208  *  up on the request.  We then behave just as if the M timer was
  209  *  reached, and we discard the current request.  This allows us
  210  *  to process the new one.
  211  *
  212  *  The second case is when we're at Y, but we haven't yet
  213  *  finished processing the request.  This is a race condition in
  214  *  the threading code (avoiding locks is faster).  It means that
  215  *  a thread has actually encoded and sent the reply, and that the
  216  *  NAS has responded with a new packet.  The server can then
  217  *  safely mark the current request as "OK to delete", and behaves
  218  *  just as if the M timer was reached.  This usually happens only
  219  *  in high-load situations.
  220  *
  221  *  Duplicate packets are sent when the NAS thinks we're taking
  222  *  too long, and wants a reply.  From R-Y, duplicates are
  223  *  ignored.  From Y-J (for Access-Rejects), duplicates are also
  224  *  ignored.  From Y-C, duplicates get a duplicate reply.  *And*,
  225  *  they cause the "cleanup_delay" time to be extended.  This
  226  *  extension means that we're more likely to send a duplicate
  227  *  reply (if we have one), or to suppress processing the packet
  228  *  twice if we didn't reply to it.
  229  *
  230  *  All functions in this file should be thread-safe, and should
  231  *  assume thet the REQUEST structure is being accessed
  232  *  simultaneously by the main thread, and by the child worker
  233  *  threads.  This means that timers, etc. cannot be updated in
  234  *  the child thread.
  235  *
  236  *  Instead, the master thread periodically calls request->process
  237  *  with action TIMER.  It's up to the individual functions to
  238  *  determine how to handle that.  They need to check if they're
  239  *  being called from a child thread or the master, and then do
  240  *  different things based on that.
  241  */
  242 #ifdef WITH_PROXY
  243 static fr_packet_list_t *proxy_list = NULL;
  244 static TALLOC_CTX *proxy_ctx = NULL;
  245 #endif
  246 
  247 #ifdef HAVE_PTHREAD_H
  248 #  ifdef WITH_PROXY
  249 static pthread_mutex_t proxy_mutex;
  250 static bool proxy_no_new_sockets = false;
  251 #  endif
  252 
  253 #  define PTHREAD_MUTEX_LOCK if (spawn_flag) pthread_mutex_lock
  254 #  define PTHREAD_MUTEX_UNLOCK if (spawn_flag) pthread_mutex_unlock
  255 
  256 static pthread_t NO_SUCH_CHILD_PID;
  257 #  define NO_CHILD_THREAD request->child_pid = NO_SUCH_CHILD_PID
  258 
  259 #else
  260 /*
  261  *  This is easier than ifdef's throughout the code.
  262  */
  263 #  define PTHREAD_MUTEX_LOCK(_x)
  264 #  define PTHREAD_MUTEX_UNLOCK(_x)
  265 #  define NO_CHILD_THREAD
  266 #endif
  267 
  268 #ifdef HAVE_PTHREAD_H
  269 static bool we_are_master(void)
  270 {
  271     if (spawn_flag &&
  272         (pthread_equal(pthread_self(), NO_SUCH_CHILD_PID) == 0)) {
  273         return false;
  274     }
  275 
  276     return true;
  277 }
  278 
  279 /*
  280  *  Assertions are debug checks.
  281  */
  282 #  ifndef NDEBUG
  283 #    define ASSERT_MASTER   if (!we_are_master()) rad_panic("We are not master")
  284 #    endif
  285 #else
  286 
  287 /*
  288  *  No threads: we're always master.
  289  */
  290 #  define we_are_master(_x) (1)
  291 #endif  /* HAVE_PTHREAD_H */
  292 
  293 #ifndef ASSERT_MASTER
  294 #  define ASSERT_MASTER
  295 #endif
  296 
  297 /*
  298  *  Make state transitions simpler.
  299  */
  300 #define FINAL_STATE(_x) NO_CHILD_THREAD; request->component = "<" #_x ">"; request->module = ""; request->child_state = _x
  301 
  302 
  303 static void event_new_fd(rad_listen_t *this);
  304 
  305 /*
  306  *  We need mutexes around the event FD list *only* in certain
  307  *  cases.
  308  */
  309 #if defined (HAVE_PTHREAD_H) && (defined(WITH_PROXY) || defined(WITH_TCP))
  310 static rad_listen_t *new_listeners = NULL;
  311 
  312 static pthread_mutex_t  fd_mutex;
  313 #  define FD_MUTEX_LOCK if (spawn_flag) pthread_mutex_lock
  314 #  define FD_MUTEX_UNLOCK if (spawn_flag) pthread_mutex_unlock
  315 
  316 void radius_update_listener(rad_listen_t *this)
  317 {
  318     /*
  319      *  Just do it ourselves.
  320      */
  321     if (we_are_master()) {
  322         event_new_fd(this);
  323         return;
  324     }
  325 
  326     FD_MUTEX_LOCK(&fd_mutex);
  327 
  328     /*
  329      *  If it's already in the list, don't add it again.
  330      */
  331     if (this->next) {
  332         FD_MUTEX_UNLOCK(&fd_mutex);
  333         return;
  334     }
  335 
  336     /*
  337      *  Otherwise, add it to the list
  338      */
  339     this->next = new_listeners;
  340     new_listeners = this;
  341     FD_MUTEX_UNLOCK(&fd_mutex);
  342     radius_signal_self(RADIUS_SIGNAL_SELF_NEW_FD);
  343 }
  344 #else
  345 void radius_update_listener(rad_listen_t *this)
  346 {
  347     /*
  348      *  No threads.  Just insert it.
  349      */
  350     event_new_fd(this);
  351 }
  352 /*
  353  *  This is easier than ifdef's throughout the code.
  354  */
  355 #  define FD_MUTEX_LOCK(_x)
  356 #  define FD_MUTEX_UNLOCK(_x)
  357 #endif
  358 
  359 /*
  360  *  Emit a systemd watchdog notification and reschedule the event.
  361  */
  362 #ifdef HAVE_SYSTEMD_WATCHDOG
  363 typedef struct {
  364     fr_event_list_t *el;
  365     struct timeval when;
  366 } sd_watchdog_data_t;
  367 
  368 static sd_watchdog_data_t sdwd;
  369 
  370 static void sd_watchdog_event(void *ctx)
  371 {
  372     sd_watchdog_data_t *s = (sd_watchdog_data_t *)ctx;
  373 
  374     DEBUG("Emitting systemd watchdog notification");
  375     sd_notify(0, "WATCHDOG=1");
  376 
  377     timeradd(&s->when, &sd_watchdog_interval, &s->when);
  378     if (!fr_event_insert(s->el, sd_watchdog_event, ctx, &s->when, &sd_watchdog_ev)) {
  379         rad_panic("Failed to insert event");
  380     }
  381 }
  382 #endif
  383 
  384 static int request_num_counter = 1;
  385 #ifdef WITH_PROXY
  386 static int request_will_proxy(REQUEST *request) CC_HINT(nonnull);
  387 static int request_proxy(REQUEST *request) CC_HINT(nonnull);
  388 STATE_MACHINE_DECL(request_ping) CC_HINT(nonnull);
  389 
  390 STATE_MACHINE_DECL(request_response_delay) CC_HINT(nonnull);
  391 STATE_MACHINE_DECL(request_cleanup_delay) CC_HINT(nonnull);
  392 STATE_MACHINE_DECL(request_running) CC_HINT(nonnull);
  393 STATE_MACHINE_DECL(request_done) CC_HINT(nonnull);
  394 
  395 STATE_MACHINE_DECL(proxy_no_reply) CC_HINT(nonnull);
  396 STATE_MACHINE_DECL(proxy_running) CC_HINT(nonnull);
  397 STATE_MACHINE_DECL(proxy_wait_for_reply) CC_HINT(nonnull);
  398 
  399 static int process_proxy_reply(REQUEST *request, RADIUS_PACKET *reply) CC_HINT(nonnull (1));
  400 static void remove_from_proxy_hash(REQUEST *request) CC_HINT(nonnull);
  401 static void remove_from_proxy_hash_nl(REQUEST *request, bool yank) CC_HINT(nonnull);
  402 static int insert_into_proxy_hash(REQUEST *request) CC_HINT(nonnull);
  403 static int setup_post_proxy_fail(REQUEST *request);
  404 #endif
  405 
  406 static REQUEST *request_setup(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *packet,
  407                   RADCLIENT *client, RAD_REQUEST_FUNP fun);
  408 static int request_pre_handler(REQUEST *request, UNUSED int action) CC_HINT(nonnull);
  409 
  410 #ifdef WITH_COA
  411 static void request_coa_originate(REQUEST *request) CC_HINT(nonnull);
  412 STATE_MACHINE_DECL(coa_wait_for_reply) CC_HINT(nonnull);
  413 STATE_MACHINE_DECL(coa_no_reply) CC_HINT(nonnull);
  414 STATE_MACHINE_DECL(coa_running) CC_HINT(nonnull);
  415 static void coa_separate(REQUEST *request, bool retransmit) CC_HINT(nonnull);
  416 #  define COA_SEPARATE if (request->coa) coa_separate(request->coa, true);
  417 #else
  418 #  define COA_SEPARATE
  419 #endif
  420 
  421 #define CHECK_FOR_STOP do { if (request->master_state == REQUEST_STOP_PROCESSING) {request_done(request, FR_ACTION_CANCELLED);return;}} while (0)
  422 
  423 #undef USEC
  424 #define USEC (1000000)
  425 
  426 #define INSERT_EVENT(_function, _ctx) if (!fr_event_insert(el, _function, _ctx, &((_ctx)->when), &((_ctx)->ev))) { _rad_panic(__FILE__, __LINE__, "Failed to insert event"); }
  427 
  428 static void tv_add(struct timeval *tv, int usec_delay)
  429 {
  430     if (usec_delay >= USEC) {
  431         tv->tv_sec += usec_delay / USEC;
  432         usec_delay %= USEC;
  433     }
  434     tv->tv_usec += usec_delay;
  435 
  436     if (tv->tv_usec >= USEC) {
  437         tv->tv_sec += tv->tv_usec / USEC;
  438         tv->tv_usec %= USEC;
  439     }
  440 }
  441 
  442 /*
  443  *  Debug the packet if requested.
  444  */
  445 static void debug_packet(REQUEST *request, RADIUS_PACKET *packet, bool received)
  446 {
  447     char src_ipaddr[128];
  448     char dst_ipaddr[128];
  449 
  450     if (!packet) return;
  451     if (!RDEBUG_ENABLED) return;
  452 
  453 #ifdef WITH_DETAIL
  454     /*
  455      *  Don't print IP addresses for detail files.
  456      */
  457     if (request->listener &&
  458         (request->listener->type == RAD_LISTEN_DETAIL)) return;
  459 
  460 #endif
  461     /*
  462      *  Client-specific debugging re-prints the input
  463      *  packet into the client log.
  464      *
  465      *  This really belongs in a utility library
  466      */
  467     if (is_radius_code(packet->code)) {
  468         RDEBUG("%s %s Id %u from %s%s%s:%i to %s%s%s:%i length %zu",
  469                received ? "Received" : "Sent",
  470                fr_packet_codes[packet->code],
  471                packet->id,
  472                packet->src_ipaddr.af == AF_INET6 ? "[" : "",
  473                inet_ntop(packet->src_ipaddr.af,
  474                  &packet->src_ipaddr.ipaddr,
  475                  src_ipaddr, sizeof(src_ipaddr)),
  476                packet->src_ipaddr.af == AF_INET6 ? "]" : "",
  477                packet->src_port,
  478                packet->dst_ipaddr.af == AF_INET6 ? "[" : "",
  479                inet_ntop(packet->dst_ipaddr.af,
  480                  &packet->dst_ipaddr.ipaddr,
  481                  dst_ipaddr, sizeof(dst_ipaddr)),
  482                packet->dst_ipaddr.af == AF_INET6 ? "]" : "",
  483                packet->dst_port,
  484                packet->data_len);
  485     } else {
  486         RDEBUG("%s code %u Id %u from %s%s%s:%i to %s%s%s:%i length %zu\n",
  487                received ? "Received" : "Sent",
  488                packet->code,
  489                packet->id,
  490                packet->src_ipaddr.af == AF_INET6 ? "[" : "",
  491                inet_ntop(packet->src_ipaddr.af,
  492                  &packet->src_ipaddr.ipaddr,
  493                  src_ipaddr, sizeof(src_ipaddr)),
  494                packet->src_ipaddr.af == AF_INET6 ? "]" : "",
  495                packet->src_port,
  496                packet->dst_ipaddr.af == AF_INET6 ? "[" : "",
  497                inet_ntop(packet->dst_ipaddr.af,
  498                  &packet->dst_ipaddr.ipaddr,
  499                  dst_ipaddr, sizeof(dst_ipaddr)),
  500                packet->dst_ipaddr.af == AF_INET6 ? "]" : "",
  501                packet->dst_port,
  502                packet->data_len);
  503     }
  504 
  505     if (received) {
  506         rdebug_pair_list(L_DBG_LVL_1, request, packet->vps, NULL);
  507     } else {
  508         rdebug_proto_pair_list(L_DBG_LVL_1, request, packet->vps);
  509     }
  510 }
  511 
  512 
  513 /***********************************************************************
  514  *
  515  *  Start of RADIUS server state machine.
  516  *
  517  ***********************************************************************/
  518 
  519 static struct timeval *request_response_window(REQUEST *request)
  520 {
  521     VERIFY_REQUEST(request);
  522 
  523     rad_assert(request->home_server != NULL);
  524 
  525     if (request->client) {
  526         /*
  527          *  The client hasn't set the response window.  Return
  528          *  either the home server one, if set, or the global one.
  529          */
  530         if (!timerisset(&request->client->response_window)) {
  531             return &request->home_server->response_window;
  532         }
  533 
  534         if (timercmp(&request->client->response_window,
  535                  &request->home_server->response_window, <)) {
  536             return &request->client->response_window;
  537         }
  538     }
  539 
  540     return &request->home_server->response_window;
  541 }
  542 
  543 /*
  544  * Determine initial request processing delay.
  545  */
  546 static int request_init_delay(REQUEST *request)
  547 {
  548     struct timeval half_response_window;
  549 
  550     VERIFY_REQUEST(request);
  551 
  552     /* Allow client response window to lower initial delay */
  553     if (timerisset(&request->client->response_window)) {
  554         half_response_window.tv_sec = request->client->response_window.tv_sec >> 1;
  555         half_response_window.tv_usec =
  556             ((request->client->response_window.tv_sec & 1) * USEC +
  557                 request->client->response_window.tv_usec) >> 1;
  558         if (timercmp(&half_response_window, &request->root->init_delay, <))
  559             return (int)half_response_window.tv_sec * USEC +
  560                 (int)half_response_window.tv_usec;
  561     }
  562 
  563     return (int)request->root->init_delay.tv_sec * USEC +
  564         (int)request->root->init_delay.tv_usec;
  565 }
  566 
  567 /*
  568  *  Callback for ALL timer events related to the request.
  569  */
  570 static void request_timer(void *ctx)
  571 {
  572     REQUEST *request = talloc_get_type_abort(ctx, REQUEST);
  573     int action;
  574 
  575     action = request->timer_action;
  576 
  577     TRACE_STATE_MACHINE;
  578 
  579     request->process(request, action);
  580 }
  581 
  582 /*
  583  *  Wrapper for talloc pools.  If there's no parent, just free the
  584  *  request.  If there is a parent, free the parent INSTEAD of the
  585  *  request.
  586  */
  587 static void request_free(REQUEST *request)
  588 {
  589     void *ptr;
  590 
  591     rad_assert(request->ev == NULL);
  592     rad_assert(!request->in_request_hash);
  593     rad_assert(!request->in_proxy_hash);
  594 
  595     if ((request->options & RAD_REQUEST_OPTION_CTX) == 0) {
  596         talloc_free(request);
  597         return;
  598     }
  599 
  600     ptr = talloc_parent(request);
  601     rad_assert(ptr != NULL);
  602     talloc_free(ptr);
  603 }
  604 
  605 
  606 #ifdef WITH_PROXY
  607 static void proxy_reply_too_late(REQUEST *request)
  608 {
  609     char buffer[128];
  610 
  611     RDEBUG2("Reply from home server %s port %d  - ID: %d arrived too late.  Try increasing 'retry_delay' or 'max_request_time'",
  612         inet_ntop(request->proxy->dst_ipaddr.af,
  613               &request->proxy->dst_ipaddr.ipaddr,
  614               buffer, sizeof(buffer)),
  615         request->proxy->dst_port, request->proxy->id);
  616 }
  617 #endif
  618 
  619 
  620 /** Mark a request DONE and clean it up.
  621  *
  622  *  When a request is DONE, it can have ties to a number of other
  623  *  portions of the server.  The request hash, proxy hash, events,
  624  *  child threads, etc.  This function takes care of either cleaning
  625  *  up the request, or managing the timers to wait for the ties to be
  626  *  removed.
  627  *
  628  *  \dot
  629  *  digraph done {
  630  *      stopped -> done
  631  *      done -> done [ label = "still running" ];
  632  *  }
  633  *  \enddot
  634  */
  635 static void request_done(REQUEST *request, int action)
  636 {
  637     struct timeval now, when;
  638 
  639     VERIFY_REQUEST(request);
  640 
  641     TRACE_STATE_MACHINE;
  642 
  643     /*
  644      *  Force this no matter what.
  645      */
  646     request->process = request_done;
  647 
  648 #ifdef WITH_DETAIL
  649     /*
  650      *  Tell the detail listener that we're done.
  651      */
  652     if (request->listener &&
  653         (request->listener->type == RAD_LISTEN_DETAIL) &&
  654         (request->simul_max != 1)) {
  655         request->simul_max = 1;
  656         request->listener->send(request->listener,
  657                     request);
  658     }
  659 #endif
  660 
  661 #ifdef HAVE_PTHREAD_H
  662     /*
  663      *  If called from a child thread, mark ourselves as done,
  664      *  and wait for the master thread timer to clean us up.
  665      */
  666     if (!we_are_master()) {
  667         FINAL_STATE(REQUEST_DONE);
  668         return;
  669     }
  670 #endif
  671 
  672     /*
  673      *  Mark the request as STOP.
  674      */
  675     request->master_state = REQUEST_STOP_PROCESSING;
  676 
  677 #ifdef WITH_PROXY
  678     /*
  679      *  Walk through the server pool to see if we need to mark
  680      *  connections as dead.
  681      */
  682     if (request->home_pool) {
  683         fr_event_now(el, &now);
  684         if (request->home_pool->last_serviced < now.tv_sec) {
  685             int i;
  686 
  687             request->home_pool->last_serviced = now.tv_sec;
  688 
  689             for (i = 0; i < request->home_pool->num_home_servers; i++) {
  690                 home_server_t *home = request->home_pool->servers[i];
  691 
  692                 if (home->state == HOME_STATE_CONNECTION_FAIL) {
  693                     mark_home_server_dead(home, &now, false);
  694                 }
  695             }
  696         }
  697     }
  698 #endif
  699 
  700     /*
  701      *  If it was administratively canceled, then it's done.
  702      */
  703     if (action == FR_ACTION_CANCELLED) {
  704         action = FR_ACTION_DONE;
  705 
  706 #ifdef WITH_COA
  707         /*
  708          *  Don't touch request->coa, it's in the middle
  709          *  of being processed...
  710          */
  711     } else {
  712         /*
  713          *  Move the CoA request to its own handler, but
  714          *  only if the request finished normally, and was
  715          *  not administratively canceled.
  716          */
  717         if (request->coa) {
  718             coa_separate(request->coa, true);
  719         } else if (request->parent && (request->parent->coa == request)) {
  720             coa_separate(request, true);
  721         }
  722 #endif
  723     }
  724 
  725     /*
  726      *  It doesn't hurt to send duplicate replies.  All other
  727      *  signals are ignored, as the request will be cleaned up
  728      *  soon anyways.
  729      */
  730     switch (action) {
  731     case FR_ACTION_DUP:
  732 #ifdef WITH_DETAIL
  733         rad_assert(request->listener != NULL);
  734 #endif
  735         if (request->reply->code != 0) {
  736             request->listener->send(request->listener, request);
  737             return;
  738         } else {
  739             RDEBUG("No reply.  Ignoring retransmit");
  740         }
  741         break;
  742 
  743         /*
  744          *  Mark the request as done.
  745          */
  746     case FR_ACTION_DONE:
  747 #ifdef HAVE_PTHREAD_H
  748         /*
  749          *  If the child is still running, leave it alone.
  750          */
  751         if (spawn_flag && (request->child_state <= REQUEST_RUNNING)) {
  752             break;
  753         }
  754 #endif
  755 
  756 #ifdef DEBUG_STATE_MACHINE
  757         if (rad_debug_lvl) printf("(%u) ********\tSTATE %s C-%s -> C-%s\t********\n",
  758                        request->number, __FUNCTION__,
  759                        child_state_names[request->child_state],
  760                        child_state_names[REQUEST_DONE]);
  761 #endif
  762         request->child_state = REQUEST_DONE;
  763         break;
  764 
  765         /*
  766          *  Called when the child is taking too long to
  767          *  finish.  We've already marked it "please
  768          *  stop", so we don't complain any more.
  769          */
  770     case FR_ACTION_TIMER:
  771         break;
  772 
  773 #ifdef WITH_PROXY
  774     case FR_ACTION_PROXY_REPLY:
  775         proxy_reply_too_late(request);
  776         break;
  777 #endif
  778 
  779     default:
  780         break;
  781     }
  782 
  783     /*
  784      *  Remove it from the request hash.
  785      */
  786     if (request->in_request_hash) {
  787         if (!rbtree_deletebydata(pl, &request->packet)) {
  788             rad_assert(0 == 1);
  789         }
  790         request->in_request_hash = false;
  791     }
  792 
  793 #ifdef WITH_PROXY
  794     /*
  795      *  Wait for the proxy ID to expire.  This allows us to
  796      *  avoid re-use of proxy IDs for a while.
  797      */
  798     if (request->in_proxy_hash) {
  799         rad_assert(request->proxy != NULL);
  800 
  801         fr_event_now(el, &now);
  802         when = request->proxy->timestamp;
  803 
  804 #ifdef WITH_COA
  805         if (((request->proxy->code == PW_CODE_COA_REQUEST) ||
  806              (request->proxy->code == PW_CODE_DISCONNECT_REQUEST)) &&
  807             (request->packet->code != request->proxy->code)) {
  808             when.tv_sec += request->home_server->coa_mrd;
  809         } else
  810 #endif
  811             timeradd(&when, request_response_window(request), &when);
  812 
  813         /*
  814          *  We haven't received all responses, AND there's still
  815          *  time to wait.  Do so.
  816          */
  817         if ((request->num_proxied_requests > request->num_proxied_responses) &&
  818 #ifdef WITH_TCP
  819             (request->home_server->proto != IPPROTO_TCP) &&
  820 #endif
  821             timercmp(&now, &when, <)) {
  822             RDEBUG("Waiting for more responses from the home server");
  823             goto wait_some_more;
  824         }
  825 
  826         /*
  827          *  Time to remove it.
  828          */
  829         remove_from_proxy_hash(request);
  830     }
  831 #endif
  832 
  833 #ifdef HAVE_PTHREAD_H
  834     /*
  835      *  If there's no children, we can mark the request as done.
  836      */
  837     if (!spawn_flag) request->child_state = REQUEST_DONE;
  838 #endif
  839 
  840     /*
  841      *  If the child is still running, wait for it to be finished.
  842      */
  843     if (request->child_state <= REQUEST_RUNNING) {
  844         gettimeofday(&now, NULL);
  845 #ifdef WITH_PROXY
  846     wait_some_more:
  847 #endif
  848         when = now;
  849         if (request->delay < (USEC / 3)) request->delay = USEC / 3;
  850         tv_add(&when, request->delay);
  851         request->delay += request->delay >> 1;
  852         if (request->delay > (10 * USEC)) request->delay = 10 * USEC;
  853 
  854         STATE_MACHINE_TIMER(FR_ACTION_TIMER);
  855         return;
  856     }
  857 
  858 #ifdef HAVE_PTHREAD_H
  859     rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
  860 #endif
  861 
  862 #ifdef WITH_COA
  863     /*
  864      *  Now that the child is done, free the CoA packet.  If
  865      *  the CoA is running, it's already been separated.
  866      */
  867     if (request->coa) TALLOC_FREE(request->coa);
  868 #endif
  869 
  870 
  871     /*
  872      *  @todo: do final states for TCP sockets, too?
  873      */
  874     request_stats_final(request);
  875 #ifdef WITH_TCP
  876     if (request->listener) {
  877         request->listener->count--;
  878 
  879         /*
  880          *  If we're the last one, remove the listener now.
  881          */
  882         if ((request->listener->count == 0) &&
  883             (request->listener->status >= RAD_LISTEN_STATUS_FROZEN)) {
  884             event_new_fd(request->listener);
  885         }
  886     }
  887 #endif
  888 
  889     if (request->packet) {
  890         RDEBUG2("Cleaning up request packet ID %u with timestamp +%d",
  891             request->packet->id,
  892             (unsigned int) (request->timestamp - fr_start_time));
  893     } /* else don't print anything */
  894 
  895     ASSERT_MASTER;
  896     fr_event_delete(el, &request->ev);
  897     request_free(request);
  898 }
  899 
  900 
  901 static void request_cleanup_delay_init(REQUEST *request)
  902 {
  903     struct timeval now, when;
  904 
  905     VERIFY_REQUEST(request);
  906 
  907     /*
  908      *  Do cleanup delay ONLY for RADIUS packets from a real
  909      *  client.  Everything else just gets cleaned up
  910      *  immediately.
  911      */
  912     if (request->packet->dst_port == 0) goto done;
  913 
  914     /*
  915      *  Accounting packets shouldn't be retransmitted.  They
  916      *  should always be updated with Acct-Delay-Time.
  917      */
  918 #ifdef WITH_ACCOUNTING
  919     if (request->packet->code == PW_CODE_ACCOUNTING_REQUEST) goto done;
  920 #endif
  921 
  922 #ifdef WITH_DHCP
  923     if (request->listener->type == RAD_LISTEN_DHCP) goto done;
  924 #endif
  925 
  926 #ifdef WITH_VMPS
  927     if (request->listener->type == RAD_LISTEN_VQP) goto done;
  928 #endif
  929 
  930     if (!request->root->cleanup_delay) goto done;
  931 
  932     gettimeofday(&now, NULL);
  933 
  934     rad_assert(request->reply->timestamp.tv_sec != 0);
  935     when = request->reply->timestamp;
  936 
  937     request->delay = request->root->cleanup_delay;
  938     when.tv_sec += request->delay;
  939 
  940     /*
  941      *  Set timer for when we need to clean it up.
  942      */
  943     if (timercmp(&when, &now, >)) {
  944 #ifdef DEBUG_STATE_MACHINE
  945         if (rad_debug_lvl) printf("(%u) ********\tNEXT-STATE %s -> %s\n", request->number, __FUNCTION__, "request_cleanup_delay");
  946 #endif
  947         request->process = request_cleanup_delay;
  948 
  949         if (!we_are_master()) {
  950             FINAL_STATE(REQUEST_CLEANUP_DELAY);
  951             return;
  952         }
  953 
  954         /*
  955          *  Update this if we can, otherwise let the timers pick it up.
  956          */
  957         request->child_state = REQUEST_CLEANUP_DELAY;
  958 #ifdef HAVE_PTHREAD_H
  959         rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
  960 #endif
  961         STATE_MACHINE_TIMER(FR_ACTION_TIMER);
  962         return;
  963     }
  964 
  965     /*
  966      *  Otherwise just clean it up.
  967      */
  968 done:
  969     request_done(request, FR_ACTION_DONE);
  970 }
  971 
  972 
  973 /*
  974  *  Enforce max_request_time.
  975  */
  976 static bool request_max_time(REQUEST *request)
  977 {
  978     struct timeval now, when;
  979     rad_assert(request->magic == REQUEST_MAGIC);
  980 #ifdef DEBUG_STATE_MACHINE
  981     int action = FR_ACTION_TIMER;
  982 #endif
  983 
  984     VERIFY_REQUEST(request);
  985 
  986     TRACE_STATE_MACHINE;
  987     ASSERT_MASTER;
  988 
  989     /*
  990      *  The child thread has acknowledged it's done.
  991      *  Transition to the DONE state.
  992      *
  993      *  If the request was marked STOP, then the "check for
  994      *  stop" macro already took care of it.
  995      */
  996     if (request->child_state == REQUEST_DONE) {
  997     done:
  998         request_done(request, FR_ACTION_CANCELLED);
  999         return true;
 1000     }
 1001 
 1002     /*
 1003      *  The request is still running.  Enforce max_request_time.
 1004      */
 1005     fr_event_now(el, &now);
 1006     when = request->packet->timestamp;
 1007     when.tv_sec += request->root->max_request_time;
 1008 
 1009     /*
 1010      *  Taking too long: tell it to die.
 1011      */
 1012     if (timercmp(&now, &when, >=)) {
 1013 #ifdef HAVE_PTHREAD_H
 1014         /*
 1015          *  If there's a child thread processing it,
 1016          *  complain.
 1017          */
 1018         if (spawn_flag &&
 1019             (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0)) {
 1020             ERROR("Unresponsive child for request %u, in component %s module %s",
 1021                   request->number,
 1022                   request->component ? request->component : "<core>",
 1023                   request->module ? request->module : "<core>");
 1024             exec_trigger(request, NULL, "server.thread.unresponsive", true);
 1025         }
 1026 #endif
 1027         /*
 1028          *  Tell the request that it's done.
 1029          */
 1030         goto done;
 1031     }
 1032 
 1033     /*
 1034      *  Sleep for some more.  We HOPE that the child will
 1035      *  become responsive at some point in the future.  We do
 1036      *  this by adding 50% to the current timer.
 1037      */
 1038     when = now;
 1039     tv_add(&when, request->delay);
 1040     request->delay += request->delay >> 1;
 1041     STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 1042     return false;
 1043 }
 1044 
 1045 static void request_queue_or_run(REQUEST *request,
 1046                  fr_request_process_t process)
 1047 {
 1048 #ifdef DEBUG_STATE_MACHINE
 1049     int action = FR_ACTION_TIMER;
 1050 #endif
 1051 
 1052     VERIFY_REQUEST(request);
 1053 
 1054     TRACE_STATE_MACHINE;
 1055 
 1056     /*
 1057      *  Do this here so that fewer other functions need to do
 1058      *  it.
 1059      */
 1060     if (request->master_state == REQUEST_STOP_PROCESSING) {
 1061 #ifdef DEBUG_STATE_MACHINE
 1062         if (rad_debug_lvl) printf("(%u) ********\tSTATE %s M-%s causes C-%s-> C-%s\t********\n",
 1063                        request->number, __FUNCTION__,
 1064                        master_state_names[request->master_state],
 1065                        child_state_names[request->child_state],
 1066                        child_state_names[REQUEST_DONE]);
 1067 #endif
 1068         request_done(request, FR_ACTION_CANCELLED);
 1069         return;
 1070     }
 1071 
 1072     request->process = process;
 1073 
 1074     if (we_are_master()) {
 1075         struct timeval when;
 1076 
 1077         /*
 1078          *  (re) set the initial delay.
 1079          */
 1080         request->delay = request_init_delay(request);
 1081         if (request->delay > USEC) request->delay = USEC;
 1082         gettimeofday(&when, NULL);
 1083         tv_add(&when, request->delay);
 1084         request->delay += request->delay >> 1;
 1085 
 1086         STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 1087 
 1088 #ifdef HAVE_PTHREAD_H
 1089         if (spawn_flag) {
 1090             /*
 1091              *  A child thread will eventually pick it up.
 1092              */
 1093             if (request_enqueue(request)) return;
 1094 
 1095             /*
 1096              *  Otherwise we're not going to do anything with
 1097              *  it...
 1098              */
 1099             request_done(request, FR_ACTION_CANCELLED);
 1100             return;
 1101         }
 1102 #endif
 1103     }
 1104 
 1105     request->child_state = REQUEST_RUNNING;
 1106     request->process(request, FR_ACTION_RUN);
 1107 
 1108 #ifdef WNOHANG
 1109     /*
 1110      *  Requests that care about child process exit
 1111      *  codes have already either called
 1112      *  rad_waitpid(), or they've given up.
 1113      */
 1114     while (waitpid(-1, NULL, WNOHANG) > 0);
 1115 #endif
 1116 }
 1117 
 1118 void request_inject(REQUEST *request)
 1119 {
 1120     request_queue_or_run(request, request_running);
 1121 }
 1122 
 1123 
 1124 static void request_dup(REQUEST *request)
 1125 {
 1126     ERROR("(%u) Ignoring duplicate packet from "
 1127           "client %s port %d - ID: %u due to unfinished request "
 1128           "in component %s module %s",
 1129           request->number, request->client->shortname,
 1130           request->packet->src_port,request->packet->id,
 1131           request->component, request->module);
 1132 }
 1133 
 1134 
 1135 /** Sit on a request until it's time to clean it up.
 1136  *
 1137  *  A NAS may not see a response from the server.  When the NAS
 1138  *  retransmits, we want to be able to send a cached reply back.  The
 1139  *  alternative is to re-process the packet, which does bad things for
 1140  *  EAP, among others.
 1141  *
 1142  *  IF we do see a NAS retransmit, we extend the cleanup delay,
 1143  *  because the NAS might miss our cached reply.
 1144  *
 1145  *  Otherwise, once we reach cleanup_delay, we transition to DONE.
 1146  *
 1147  *  \dot
 1148  *  digraph cleanup_delay {
 1149  *      cleanup_delay;
 1150  *      send_reply [ label = "send_reply\nincrease cleanup delay" ];
 1151  *
 1152  *      cleanup_delay -> send_reply [ label = "DUP" ];
 1153  *      send_reply -> cleanup_delay;
 1154  *      cleanup_delay -> proxy_reply_too_late [ label = "PROXY_REPLY", arrowhead = "none" ];
 1155  *      cleanup_delay -> cleanup_delay [ label = "TIMER < timeout" ];
 1156  *      cleanup_delay -> done [ label = "TIMER >= timeout" ];
 1157  *  }
 1158  *  \enddot
 1159  */
 1160 static void request_cleanup_delay(REQUEST *request, int action)
 1161 {
 1162     struct timeval when, now;
 1163 
 1164     VERIFY_REQUEST(request);
 1165 
 1166     TRACE_STATE_MACHINE;
 1167     ASSERT_MASTER;
 1168     COA_SEPARATE;
 1169     CHECK_FOR_STOP;
 1170 
 1171     switch (action) {
 1172     case FR_ACTION_DUP:
 1173         if (request->reply->code != 0) {
 1174             DEBUG("(%u) Sending duplicate reply to "
 1175                   "client %s port %d - ID: %u",
 1176                   request->number, request->client->shortname,
 1177                   request->packet->src_port,request->packet->id);
 1178             request->listener->send(request->listener, request);
 1179         } else {
 1180             RDEBUG("No reply.  Ignoring retransmit");
 1181         }
 1182 
 1183         /*
 1184          *  Double the cleanup_delay to catch retransmits.
 1185          */
 1186         when = request->reply->timestamp;
 1187         request->delay += request->delay;
 1188         when.tv_sec += request->delay;
 1189 
 1190         STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 1191         break;
 1192 
 1193 #ifdef WITH_PROXY
 1194     case FR_ACTION_PROXY_REPLY:
 1195         proxy_reply_too_late(request);
 1196         break;
 1197 #endif
 1198 
 1199     case FR_ACTION_TIMER:
 1200         fr_event_now(el, &now);
 1201 
 1202         rad_assert(request->root->cleanup_delay > 0);
 1203 
 1204         when = request->reply->timestamp;
 1205         when.tv_sec += request->root->cleanup_delay;
 1206 
 1207         if (timercmp(&when, &now, >)) {
 1208 #ifdef DEBUG_STATE_MACHINE
 1209             if (rad_debug_lvl) printf("(%u) ********\tNEXT-STATE %s -> %s\n", request->number, __FUNCTION__, "request_cleanup_delay");
 1210 #endif
 1211             STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 1212             return;
 1213         } /* else it's time to clean up */
 1214 
 1215         request_done(request, FR_ACTION_DONE);
 1216         break;
 1217 
 1218     default:
 1219         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 1220         break;
 1221     }
 1222 }
 1223 
 1224 
 1225 /** Sit on a request until it's time to respond to it.
 1226  *
 1227  *  For security reasons, rejects (and maybe some other) packets are
 1228  *  delayed for a while before we respond.  This delay means that
 1229  *  badly behaved NASes don't hammer the server with authentication
 1230  *  attempts.
 1231  *
 1232  *  Otherwise, once we reach response_delay, we send the reply, and
 1233  *  transition to cleanup_delay.
 1234  *
 1235  *  \dot
 1236  *  digraph response_delay {
 1237  *      response_delay -> proxy_reply_too_late [ label = "PROXY_REPLY", arrowhead = "none" ];
 1238  *      response_delay -> response_delay [ label = "DUP, TIMER < timeout" ];
 1239  *      response_delay -> send_reply [ label = "TIMER >= timeout" ];
 1240  *      send_reply -> cleanup_delay;
 1241  *  }
 1242  *  \enddot
 1243  */
 1244 static void request_response_delay(REQUEST *request, int action)
 1245 {
 1246     struct timeval when, now;
 1247 
 1248     VERIFY_REQUEST(request);
 1249 
 1250     TRACE_STATE_MACHINE;
 1251     ASSERT_MASTER;
 1252     COA_SEPARATE;
 1253     CHECK_FOR_STOP;
 1254 
 1255     switch (action) {
 1256     case FR_ACTION_DUP:
 1257         RDEBUG("(%u) Discarding duplicate request from "
 1258               "client %s port %d - ID: %u due to delayed response",
 1259               request->number, request->client->shortname,
 1260               request->packet->src_port,request->packet->id);
 1261         break;
 1262 
 1263 #ifdef WITH_PROXY
 1264     case FR_ACTION_PROXY_REPLY:
 1265         proxy_reply_too_late(request);
 1266         break;
 1267 #endif
 1268 
 1269     case FR_ACTION_TIMER:
 1270         fr_event_now(el, &now);
 1271 
 1272         /*
 1273          *  See if it's time to send the reply.  If not,
 1274          *  we wait some more.
 1275          */
 1276         when = request->reply->timestamp;
 1277 
 1278         tv_add(&when, request->response_delay.tv_sec * USEC);
 1279         tv_add(&when, request->response_delay.tv_usec);
 1280 
 1281         if (timercmp(&when, &now, >)) {
 1282 #ifdef DEBUG_STATE_MACHINE
 1283             if (rad_debug_lvl) printf("(%u) ********\tNEXT-STATE %s -> %s\n", request->number, __FUNCTION__, "request_response_delay");
 1284 #endif
 1285             STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 1286             return;
 1287         } /* else it's time to send the reject */
 1288 
 1289         RDEBUG2("Sending delayed response");
 1290         debug_packet(request, request->reply, false);
 1291         request->listener->send(request->listener, request);
 1292 
 1293         /*
 1294          *  Clean up the request.
 1295          */
 1296         request_cleanup_delay_init(request);
 1297         break;
 1298 
 1299     default:
 1300         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 1301         break;
 1302     }
 1303 }
 1304 
 1305 
 1306 static int request_pre_handler(REQUEST *request, UNUSED int action)
 1307 {
 1308     int rcode;
 1309 
 1310     VERIFY_REQUEST(request);
 1311 
 1312     TRACE_STATE_MACHINE;
 1313 
 1314     if (request->master_state == REQUEST_STOP_PROCESSING) return 0;
 1315 
 1316     /*
 1317      *  Don't decode the packet if it's an internal "fake"
 1318      *  request.  Instead, just return so that the caller can
 1319      *  process it.
 1320      */
 1321     if (request->packet->dst_port == 0) {
 1322         request->username = fr_pair_find_by_num(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
 1323         request->password = fr_pair_find_by_num(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY);
 1324         return 1;
 1325     }
 1326 
 1327     if (!request->packet->vps) { /* FIXME: check for correct state */
 1328         rcode = request->listener->decode(request->listener, request);
 1329 
 1330 #ifdef WITH_UNLANG
 1331         if (debug_condition) {
 1332             /*
 1333              *  Ignore parse errors.
 1334              */
 1335             if (radius_evaluate_cond(request, RLM_MODULE_OK, 0, debug_condition)) {
 1336                 request->log.lvl = L_DBG_LVL_2;
 1337                 request->log.func = vradlog_request;
 1338             }
 1339         }
 1340 #endif
 1341 
 1342         debug_packet(request, request->packet, true);
 1343     } else {
 1344         rcode = 0;
 1345     }
 1346 
 1347     if (rcode < 0) {
 1348         RATE_LIMIT(INFO("Dropping packet without response because of error: %s", fr_strerror()));
 1349         request->reply->offset = -2; /* bad authenticator */
 1350         return 0;
 1351     }
 1352 
 1353     if (!request->username) {
 1354         request->username = fr_pair_find_by_num(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
 1355     }
 1356 
 1357     return 1;
 1358 }
 1359 
 1360 
 1361 /**  Do the final processing of a request before we reply to the NAS.
 1362  *
 1363  *  Various cleanups, suppress responses, copy Proxy-State, and set
 1364  *  response_delay or cleanup_delay;
 1365  */
 1366 static void request_finish(REQUEST *request, int action)
 1367 {
 1368     VALUE_PAIR *vp;
 1369 
 1370     VERIFY_REQUEST(request);
 1371 
 1372     TRACE_STATE_MACHINE;
 1373     CHECK_FOR_STOP;
 1374 
 1375     (void) action;  /* -Wunused */
 1376 
 1377 #ifdef WITH_COA
 1378     /*
 1379      *  Don't do post-auth if we're a CoA request originated
 1380      *  from an Access-Request.  See request_alloc_coa() for
 1381      *  details.
 1382      */
 1383     if ((request->options & RAD_REQUEST_OPTION_COA) != 0) goto done;
 1384 #endif
 1385 
 1386     /*
 1387      *  Override the response code if a control:Response-Packet-Type attribute is present.
 1388      */
 1389     vp = fr_pair_find_by_num(request->config, PW_RESPONSE_PACKET_TYPE, 0, TAG_ANY);
 1390     if (vp) {
 1391         if (vp->vp_integer == 256) {
 1392             RDEBUG2("Not responding to request");
 1393             fr_pair_delete_by_num(&request->reply->vps, PW_RESPONSE_PACKET_TYPE, 0, TAG_ANY);
 1394             request->reply->code = 0;
 1395         } else {
 1396             request->reply->code = vp->vp_integer;
 1397         }
 1398     }
 1399     /*
 1400      *  Catch Auth-Type := Reject BEFORE proxying the packet.
 1401      */
 1402     else if (request->packet->code == PW_CODE_ACCESS_REQUEST) {
 1403         if (request->reply->code == 0) {
 1404             vp = fr_pair_find_by_num(request->config, PW_AUTH_TYPE, 0, TAG_ANY);
 1405             if (!vp || (vp->vp_integer != 5)) {
 1406                 RDEBUG2("There was no response configured: "
 1407                     "rejecting request");
 1408             }
 1409 
 1410             request->reply->code = PW_CODE_ACCESS_REJECT;
 1411         }
 1412     }
 1413 
 1414     /*
 1415      *  Copy Proxy-State from the request to the reply.
 1416      */
 1417     vp = fr_pair_list_copy_by_num(request->reply, request->packet->vps,
 1418                PW_PROXY_STATE, 0, TAG_ANY);
 1419     if (vp) fr_pair_add(&request->reply->vps, vp);
 1420 
 1421     /*
 1422      *  Call Post-Auth for Access-Request packets.
 1423      */
 1424     if (request->packet->code == PW_CODE_ACCESS_REQUEST) {
 1425         rad_postauth(request);
 1426 
 1427         vp = fr_pair_find_by_num(request->config, PW_RESPONSE_PACKET_TYPE, 0, TAG_ANY);
 1428         if (vp && (vp->vp_integer == 256)) {
 1429             RDEBUG2("Not responding to request");
 1430             request->reply->code = 0;
 1431         }
 1432     }
 1433 
 1434 #ifdef WITH_COA
 1435     /*
 1436      *  Maybe originate a CoA request.
 1437      */
 1438     if ((action == FR_ACTION_RUN) && !request->proxy && request->coa) {
 1439         request_coa_originate(request);
 1440     }
 1441 #endif
 1442 
 1443     /*
 1444      *  Clean up.  These are no longer needed.
 1445      */
 1446     gettimeofday(&request->reply->timestamp, NULL);
 1447 
 1448     /*
 1449      *  Fake packets get marked as "done", and have the
 1450      *  proxy-reply section deal with the reply attributes.
 1451      *  We therefore don't free the reply attributes.
 1452      */
 1453     if (request->packet->dst_port == 0) {
 1454         RDEBUG("Finished internally proxied request.");
 1455         FINAL_STATE(REQUEST_DONE);
 1456         return;
 1457     }
 1458 
 1459 #ifdef WITH_DETAIL
 1460     /*
 1461      *  Always send the reply to the detail listener.
 1462      */
 1463     if (request->listener->type == RAD_LISTEN_DETAIL) {
 1464         request->simul_max = 1;
 1465 
 1466         /*
 1467          *  But only print the reply if there is one.
 1468          */
 1469         if (request->reply->code != 0) {
 1470             debug_packet(request, request->reply, false);
 1471         }
 1472 
 1473         request->listener->send(request->listener, request);
 1474         goto done;
 1475     }
 1476 #endif
 1477 
 1478     /*
 1479      *  Ignore all "do not respond" packets.
 1480      *  Except for the detail ones, which need to ping
 1481      *  the detail file reader so that it will retransmit.
 1482      */
 1483     if (!request->reply->code) {
 1484         RDEBUG("Not sending reply to client.");
 1485         goto done;
 1486     }
 1487 
 1488     /*
 1489      *  If it's not in the request hash, we MIGHT not want to
 1490      *  send a reply.
 1491      *
 1492      *  If duplicate packets are allowed, then then only
 1493      *  reason to NOT be in the request hash is because we
 1494      *  don't want to send a reply.
 1495      *
 1496      *  FIXME: this is crap.  The rest of the state handling
 1497      *  should use a different field so that we don't have two
 1498      *  meanings for it.
 1499      *
 1500      *  Otherwise duplicates are forbidden, and the request is
 1501      *  SUPPOSED to avoid the request hash.
 1502      *
 1503      *  In that case, we need to send a reply.
 1504      */
 1505     if (!request->in_request_hash &&
 1506         !request->listener->nodup) {
 1507         RDEBUG("Suppressing reply to client.");
 1508         goto done;
 1509     }
 1510 
 1511     /*
 1512      *  See if we need to delay an Access-Reject packet.
 1513      */
 1514     if ((request->packet->code == PW_CODE_ACCESS_REQUEST) &&
 1515         (request->reply->code == PW_CODE_ACCESS_REJECT) &&
 1516         (request->root->reject_delay.tv_sec > 0)) {
 1517         request->response_delay = request->root->reject_delay;
 1518 
 1519         vp = fr_pair_find_by_num(request->reply->vps, PW_FREERADIUS_RESPONSE_DELAY, 0, TAG_ANY);
 1520         if (vp) {
 1521             if (vp->vp_integer <= 10) {
 1522                 request->response_delay.tv_sec = vp->vp_integer;
 1523             } else {
 1524                 request->response_delay.tv_sec = 10;
 1525             }
 1526             request->response_delay.tv_usec = 0;
 1527         } else {
 1528             vp = fr_pair_find_by_num(request->reply->vps, PW_FREERADIUS_RESPONSE_DELAY_USEC, 0, TAG_ANY);
 1529             if (vp) {
 1530                 if (vp->vp_integer <= 10 * USEC) {
 1531                     request->response_delay.tv_sec = vp->vp_integer / USEC;
 1532                     request->response_delay.tv_usec = vp->vp_integer % USEC;
 1533                 } else {
 1534                     request->response_delay.tv_sec = 10;
 1535                     request->response_delay.tv_usec = 0;
 1536                 }
 1537             }
 1538         }
 1539 
 1540 #ifdef WITH_PROXY
 1541         /*
 1542          *  If we timed out a proxy packet, don't delay
 1543          *  the reject any more.
 1544          */
 1545         if (request->proxy && !request->proxy_reply) {
 1546             request->response_delay.tv_sec = 0;
 1547             request->response_delay.tv_usec = 0;
 1548         }
 1549 #endif
 1550     }
 1551 
 1552     /*
 1553      *  Send the reply.
 1554      */
 1555     if ((request->response_delay.tv_sec == 0) &&
 1556         (request->response_delay.tv_usec == 0)) {
 1557 
 1558         /*
 1559          *  Don't print a reply if there's none to send.
 1560          */
 1561         if (request->reply->code != 0) {
 1562             if (rad_debug_lvl && request->state &&
 1563                 (request->reply->code == PW_CODE_ACCESS_ACCEPT)) {
 1564                 if (!fr_pair_find_by_num(request->packet->vps, PW_STATE, 0, TAG_ANY)) {
 1565                     RWDEBUG2("Unused attributes found in &session-state:");
 1566                 }
 1567             }
 1568 
 1569             debug_packet(request, request->reply, false);
 1570             request->listener->send(request->listener, request);
 1571         }
 1572 
 1573     done:
 1574         RDEBUG2("Finished request");
 1575         request_cleanup_delay_init(request);
 1576 
 1577     } else {
 1578         /*
 1579          *  Encode and sign it here, so that the master
 1580          *  thread can just send the encoded data, which
 1581          *  means it does less work.
 1582          */
 1583         RDEBUG2("Delaying response for %d.%06d seconds",
 1584             (int) request->response_delay.tv_sec, (int) request->response_delay.tv_usec);
 1585         request->listener->encode(request->listener, request);
 1586         request->process = request_response_delay;
 1587 
 1588         FINAL_STATE(REQUEST_RESPONSE_DELAY);
 1589     }
 1590 }
 1591 
 1592 /** Process a request from a client.
 1593  *
 1594  *  The outcome might be that the request is proxied.
 1595  *
 1596  *  \dot
 1597  *  digraph running {
 1598  *      running -> running [ label = "TIMER < max_request_time" ];
 1599  *      running -> done [ label = "TIMER >= max_request_time" ];
 1600  *      running -> proxy [ label = "proxied" ];
 1601  *      running -> dup [ label = "DUP", arrowhead = "none" ];
 1602  *  }
 1603  *  \enddot
 1604  */
 1605 static void request_running(REQUEST *request, int action)
 1606 {
 1607     int rcode;
 1608 
 1609     VERIFY_REQUEST(request);
 1610 
 1611     TRACE_STATE_MACHINE;
 1612     CHECK_FOR_STOP;
 1613 
 1614     switch (action) {
 1615     case FR_ACTION_TIMER:
 1616         (void) request_max_time(request);
 1617         break;
 1618 
 1619     case FR_ACTION_DUP:
 1620         request_dup(request);
 1621         break;
 1622 
 1623     case FR_ACTION_RUN:
 1624         if (!request_pre_handler(request, action)) {
 1625 #ifdef DEBUG_STATE_MACHINE
 1626             if (rad_debug_lvl) printf("(%u) ********\tSTATE %s failed in pre-handler C-%s -> C-%s\t********\n",
 1627                            request->number, __FUNCTION__,
 1628                            child_state_names[request->child_state],
 1629                            child_state_names[REQUEST_DONE]);
 1630 #endif
 1631             FINAL_STATE(REQUEST_DONE);
 1632             break;
 1633         }
 1634 
 1635         rad_assert(request->handle != NULL);
 1636         request->handle(request);
 1637 
 1638 #ifdef WITH_PROXY
 1639         /*
 1640          *  We may need to send a proxied request.
 1641          */
 1642         rcode = request_will_proxy(request);
 1643         if (rcode == 1) {
 1644 #ifdef DEBUG_STATE_MACHINE
 1645             if (rad_debug_lvl) printf("(%u) ********\tWill Proxy\t********\n", request->number);
 1646 #endif
 1647             /*
 1648              *  If this fails, it
 1649              *  takes care of setting
 1650              *  up the post proxy fail
 1651              *  handler.
 1652              */
 1653         retry_proxy:
 1654             if (request_proxy(request) < 0) {
 1655                 if (request->home_server && request->home_server->server) goto req_finished;
 1656 
 1657                 if (request->home_pool && request->home_server &&
 1658                     (request->home_server->state >= HOME_STATE_IS_DEAD)) {
 1659                     VALUE_PAIR *vp;
 1660                     REALM *realm = NULL;
 1661                     home_server_t *home = NULL;
 1662 
 1663                     vp = fr_pair_find_by_num(request->config, PW_PROXY_TO_REALM, 0, TAG_ANY);
 1664                     if (vp) realm = realm_find2(vp->vp_strvalue);
 1665 
 1666                     /*
 1667                      *  Since request->home_server is dead,
 1668                      *  this function won't pick the same home server as before.
 1669                      */
 1670                     if (realm) home = home_server_ldb(vp->vp_strvalue, request->home_pool, request);
 1671                     if (home) {
 1672                         home_server_update_request(home, request);
 1673                         goto retry_proxy;
 1674                     }
 1675                 }
 1676 
 1677                 (void) setup_post_proxy_fail(request);
 1678                 process_proxy_reply(request, NULL);
 1679                 goto req_finished;
 1680             }
 1681 
 1682         } else if (rcode < 0) {
 1683             /*
 1684              *  No live home servers, run Post-Proxy-Type Fail.
 1685              */
 1686             (void) setup_post_proxy_fail(request);
 1687             process_proxy_reply(request, NULL);
 1688             goto req_finished;
 1689         } else
 1690 #endif
 1691         {
 1692 #ifdef DEBUG_STATE_MACHINE
 1693             if (rad_debug_lvl) printf("(%u) ********\tFinished\t********\n", request->number);
 1694 #endif
 1695 
 1696 #ifdef WITH_PROXY
 1697         req_finished:
 1698 #endif
 1699             request_finish(request, action);
 1700         }
 1701         break;
 1702 
 1703     default:
 1704         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 1705         break;
 1706     }
 1707 }
 1708 
 1709 int request_receive(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *packet,
 1710             RADCLIENT *client, RAD_REQUEST_FUNP fun)
 1711 {
 1712     uint32_t count;
 1713     RADIUS_PACKET **packet_p;
 1714     REQUEST *request = NULL;
 1715     struct timeval now;
 1716     listen_socket_t *sock = NULL;
 1717 
 1718     VERIFY_PACKET(packet);
 1719 
 1720     /*
 1721      *  Set the last packet received.
 1722      */
 1723     gettimeofday(&now, NULL);
 1724 
 1725     packet->timestamp = now;
 1726 
 1727 #ifdef WITH_ACCOUNTING
 1728     if (listener->type != RAD_LISTEN_DETAIL)
 1729 #endif
 1730 
 1731 #ifdef WITH_TCP
 1732     {
 1733         sock = listener->data;
 1734         sock->last_packet = now.tv_sec;
 1735 
 1736         packet->proto = sock->proto;
 1737     }
 1738 #endif
 1739 
 1740     /*
 1741      *  Skip everything if required.
 1742      */
 1743     if (listener->nodup) goto skip_dup;
 1744 
 1745     packet_p = rbtree_finddata(pl, &packet);
 1746     if (packet_p) {
 1747         rad_child_state_t child_state;
 1748         char const *old_module;
 1749 
 1750         request = fr_packet2myptr(REQUEST, packet, packet_p);
 1751         rad_assert(request->in_request_hash);
 1752         child_state = request->child_state;
 1753         old_module = request->module;
 1754 
 1755         /*
 1756          *  Same src/dst ip/port, length, and
 1757          *  authentication vector: must be a duplicate.
 1758          */
 1759         if ((request->packet->data_len == packet->data_len) &&
 1760             (memcmp(request->packet->vector, packet->vector,
 1761                 sizeof(packet->vector)) == 0)) {
 1762 
 1763 #ifdef WITH_STATS
 1764             switch (packet->code) {
 1765             case PW_CODE_ACCESS_REQUEST:
 1766                 FR_STATS_INC(auth, total_dup_requests);
 1767                 break;
 1768 
 1769 #ifdef WITH_ACCOUNTING
 1770             case PW_CODE_ACCOUNTING_REQUEST:
 1771                 FR_STATS_INC(acct, total_dup_requests);
 1772                 break;
 1773 #endif
 1774 #ifdef WITH_COA
 1775             case PW_CODE_COA_REQUEST:
 1776                 FR_STATS_INC(coa, total_dup_requests);
 1777                 break;
 1778 
 1779             case PW_CODE_DISCONNECT_REQUEST:
 1780                 FR_STATS_INC(dsc, total_dup_requests);
 1781                 break;
 1782 #endif
 1783 
 1784             default:
 1785                 break;
 1786             }
 1787 #endif  /* WITH_STATS */
 1788 
 1789             /*
 1790              *  Tell the state machine that there's a
 1791              *  duplicate request.
 1792              */
 1793             request->process(request, FR_ACTION_DUP);
 1794             return 0; /* duplicate of live request */
 1795         }
 1796 
 1797         /*
 1798          *  Mark the request as done ASAP, and before we
 1799          *  log anything.  The child may stop processing
 1800          *  the request just as we're logging the
 1801          *  complaint.
 1802          */
 1803         request_done(request, FR_ACTION_CANCELLED);
 1804         request = NULL;
 1805 
 1806         /*
 1807          *  It's a new request, not a duplicate.  If the
 1808          *  old one is done, then we can clean it up.
 1809          */
 1810         if (child_state <= REQUEST_RUNNING) {
 1811             /*
 1812              *  The request is still QUEUED or RUNNING.  That's a problem.
 1813              */
 1814             ERROR("Received conflicting packet from "
 1815                   "client %s port %d - ID: %u due to "
 1816                   "unfinished request in module %s.  Giving up on old request.",
 1817                   client->shortname,
 1818                   packet->src_port, packet->id,
 1819                   old_module);
 1820         }
 1821 
 1822         /*
 1823          *  Mark the old request as done.  If there's no
 1824          *  child, the request will be cleaned up
 1825          *  immediately.  If there is a child, we'll set a
 1826          *  timer to go clean up the request.
 1827          */
 1828     } /* else the new packet is unique */
 1829 
 1830     /*
 1831      *  Quench maximum number of outstanding requests.
 1832      */
 1833     if (main_config.max_requests &&
 1834         ((count = rbtree_num_elements(pl)) > main_config.max_requests)) {
 1835         RATE_LIMIT(ERROR("Dropping request (%d is too many): from client %s port %d - ID: %d", count,
 1836                  client->shortname,
 1837                  packet->src_port, packet->id);
 1838                WARN("Please check the configuration file.\n"
 1839                 "\tThe value for 'max_requests' is probably set too low.\n"));
 1840 
 1841         exec_trigger(NULL, NULL, "server.max_requests", true);
 1842         return 0;
 1843     }
 1844 
 1845 skip_dup:
 1846     /*
 1847      *  Rate-limit the incoming packets
 1848      */
 1849     if (sock && sock->max_rate) {
 1850         uint32_t pps;
 1851 
 1852         pps = rad_pps(&sock->rate_pps_old, &sock->rate_pps_now, &sock->rate_time, &now);
 1853         if (pps > sock->max_rate) {
 1854             DEBUG("Dropping request due to rate limiting");
 1855             return 0;
 1856         }
 1857         sock->rate_pps_now++;
 1858     }
 1859 
 1860     /*
 1861      *  Allocate a pool for the request.
 1862      */
 1863     if (!ctx) {
 1864         ctx = talloc_pool(NULL, main_config.talloc_pool_size);
 1865         if (!ctx) return 0;
 1866         talloc_set_name_const(ctx, "request_receive_pool");
 1867 
 1868         /*
 1869          *  The packet is still allocated from a different
 1870          *  context, but oh well.
 1871          */
 1872         (void) talloc_steal(ctx, packet);
 1873     }
 1874 
 1875     request = request_setup(ctx, listener, packet, client, fun);
 1876     if (!request) {
 1877         talloc_free(ctx);
 1878         return 1;
 1879     }
 1880 
 1881     /*
 1882      *  Mark it as a "real" request with a context.
 1883      */
 1884     request->options |= RAD_REQUEST_OPTION_CTX;
 1885 
 1886     /*
 1887      *  Remember the request in the list.
 1888      */
 1889     if (!listener->nodup) {
 1890         if (!rbtree_insert(pl, &request->packet)) {
 1891             RERROR("Failed to insert request in the list of live requests: discarding it");
 1892             request_done(request, FR_ACTION_CANCELLED);
 1893             return 1;
 1894         }
 1895 
 1896         request->in_request_hash = true;
 1897     }
 1898 
 1899     /*
 1900      *  Process it.  Send a response, and free it.
 1901      */
 1902     if (listener->synchronous) {
 1903 #ifdef WITH_DETAIL
 1904         rad_assert(listener->type != RAD_LISTEN_DETAIL);
 1905 #endif
 1906 
 1907         request->listener->decode(request->listener, request);
 1908         request->username = fr_pair_find_by_num(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
 1909         request->password = fr_pair_find_by_num(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY);
 1910 
 1911         fun(request);
 1912 
 1913         if (request->reply->code != 0) {
 1914             request->listener->send(request->listener, request);
 1915         } else {
 1916             RDEBUG("Not sending reply");
 1917         }
 1918 
 1919         /*
 1920          *  Don't do delayed reject.  Oh well.
 1921          */
 1922         request_free(request);
 1923         return 1;
 1924     }
 1925 
 1926     /*
 1927      *  Otherwise, insert it into the state machine.
 1928      *  The child threads will take care of processing it.
 1929      */
 1930     request_queue_or_run(request, request_running);
 1931 
 1932     return 1;
 1933 }
 1934 
 1935 
 1936 static REQUEST *request_setup(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *packet,
 1937                   RADCLIENT *client, RAD_REQUEST_FUNP fun)
 1938 {
 1939     REQUEST *request;
 1940 
 1941     /*
 1942      *  Create and initialize the new request.
 1943      */
 1944     request = request_alloc(ctx);
 1945     if (!request) {
 1946         ERROR("No memory");
 1947         return NULL;
 1948     }
 1949     request->reply = rad_alloc_reply(request, packet);
 1950     if (!request->reply) {
 1951         ERROR("No memory");
 1952         talloc_free(request);
 1953         return NULL;
 1954     }
 1955 
 1956     request->listener = listener;
 1957     request->client = client;
 1958     request->packet = talloc_steal(request, packet);
 1959     request->number = request_num_counter++;
 1960     request->priority = listener->type;
 1961     request->master_state = REQUEST_ACTIVE;
 1962     request->child_state = REQUEST_RUNNING;
 1963 #ifdef DEBUG_STATE_MACHINE
 1964     if (rad_debug_lvl) printf("(%u) ********\tSTATE %s C-%s -> C-%s\t********\n",
 1965                    request->number, __FUNCTION__,
 1966                    child_state_names[request->child_state],
 1967                    child_state_names[REQUEST_RUNNING]);
 1968 #endif
 1969     request->handle = fun;
 1970     NO_CHILD_THREAD;
 1971 
 1972 #ifdef WITH_STATS
 1973     request->listener->stats.last_packet = request->packet->timestamp.tv_sec;
 1974     if (packet->code == PW_CODE_ACCESS_REQUEST) {
 1975         request->client->auth.last_packet = request->packet->timestamp.tv_sec;
 1976         radius_auth_stats.last_packet = request->packet->timestamp.tv_sec;
 1977 #ifdef WITH_ACCOUNTING
 1978     } else if (packet->code == PW_CODE_ACCOUNTING_REQUEST) {
 1979         request->client->acct.last_packet = request->packet->timestamp.tv_sec;
 1980         radius_acct_stats.last_packet = request->packet->timestamp.tv_sec;
 1981 #endif
 1982     }
 1983 #endif  /* WITH_STATS */
 1984 
 1985     /*
 1986      *  Status-Server packets go to the head of the queue.
 1987      */
 1988     if (request->packet->code == PW_CODE_STATUS_SERVER) request->priority = 0;
 1989 
 1990     /*
 1991      *  Set virtual server identity
 1992      */
 1993     if (client->server) {
 1994         request->server = client->server;
 1995     } else if (listener->server) {
 1996         request->server = listener->server;
 1997     } else {
 1998         request->server = NULL;
 1999     }
 2000 
 2001     request->root = &main_config;
 2002 #ifdef WITH_TCP
 2003     request->listener->count++;
 2004 #endif
 2005 
 2006     /*
 2007      *  The request passes many of our sanity checks.
 2008      *  From here on in, if anything goes wrong, we
 2009      *  send a reject message, instead of dropping the
 2010      *  packet.
 2011      */
 2012 
 2013     /*
 2014      *  Build the reply template from the request.
 2015      */
 2016 
 2017     request->reply->sockfd = request->packet->sockfd;
 2018     request->reply->dst_ipaddr = request->packet->src_ipaddr;
 2019     request->reply->src_ipaddr = request->packet->dst_ipaddr;
 2020     request->reply->dst_port = request->packet->src_port;
 2021     request->reply->src_port = request->packet->dst_port;
 2022     request->reply->id = request->packet->id;
 2023     request->reply->code = 0; /* UNKNOWN code */
 2024     memcpy(request->reply->vector, request->packet->vector,
 2025            sizeof(request->reply->vector));
 2026     request->reply->vps = NULL;
 2027     request->reply->data = NULL;
 2028     request->reply->data_len = 0;
 2029 
 2030     return request;
 2031 }
 2032 
 2033 #ifdef WITH_TCP
 2034 /***********************************************************************
 2035  *
 2036  *  TCP Handlers.
 2037  *
 2038  ***********************************************************************/
 2039 
 2040 /*
 2041  *  Timer function for all TCP sockets.
 2042  */
 2043 static void tcp_socket_timer(void *ctx)
 2044 {
 2045     rad_listen_t *listener = talloc_get_type_abort(ctx, rad_listen_t);
 2046     listen_socket_t *sock = listener->data;
 2047     struct timeval end, now;
 2048     char buffer[256];
 2049     fr_socket_limit_t *limit;
 2050 
 2051     ASSERT_MASTER;
 2052 
 2053     if (listener->status != RAD_LISTEN_STATUS_KNOWN) return;
 2054 
 2055     fr_event_now(el, &now);
 2056 
 2057     switch (listener->type) {
 2058 #ifdef WITH_PROXY
 2059     case RAD_LISTEN_PROXY:
 2060         limit = &sock->home->limit;
 2061         break;
 2062 #endif
 2063 
 2064     case RAD_LISTEN_AUTH:
 2065 #ifdef WITH_ACCOUNTING
 2066     case RAD_LISTEN_ACCT:
 2067 #endif
 2068         limit = &sock->limit;
 2069         break;
 2070 
 2071     default:
 2072         return;
 2073     }
 2074 
 2075     /*
 2076      *  If we enforce a lifetime, do it now.
 2077      */
 2078     if (limit->lifetime > 0) {
 2079         end.tv_sec = sock->opened + limit->lifetime;
 2080         end.tv_usec = 0;
 2081 
 2082         if (timercmp(&end, &now, <=)) {
 2083             listener->print(listener, buffer, sizeof(buffer));
 2084             DEBUG("Reached maximum lifetime on socket %s", buffer);
 2085 
 2086         do_close:
 2087 
 2088 #ifdef WITH_PROXY
 2089             /*
 2090              *  Proxy sockets get frozen, so that we don't use
 2091              *  them for new requests.  But we do keep them
 2092              *  open to listen for replies to requests we had
 2093              *  previously sent.
 2094              */
 2095             if (listener->type == RAD_LISTEN_PROXY) {
 2096                 PTHREAD_MUTEX_LOCK(&proxy_mutex);
 2097                 if (!fr_packet_list_socket_freeze(proxy_list,
 2098                                   listener->fd)) {
 2099                     ERROR("Fatal error freezing socket: %s", fr_strerror());
 2100                     fr_exit(1);
 2101                 }
 2102                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2103             }
 2104 #endif
 2105 
 2106             /*
 2107              *  Mark the socket as "don't use if at all possible".
 2108              */
 2109             listener->status = RAD_LISTEN_STATUS_FROZEN;
 2110             event_new_fd(listener);
 2111             return;
 2112         }
 2113     } else {
 2114         end = now;
 2115         end.tv_sec += 3600;
 2116     }
 2117 
 2118     /*
 2119      *  Enforce an idle timeout.
 2120      */
 2121     if (limit->idle_timeout > 0) {
 2122         struct timeval idle;
 2123 
 2124         rad_assert(sock->last_packet != 0);
 2125         idle.tv_sec = sock->last_packet + limit->idle_timeout;
 2126         idle.tv_usec = 0;
 2127 
 2128         if (timercmp(&idle, &now, <=)) {
 2129             listener->print(listener, buffer, sizeof(buffer));
 2130             DEBUG("Reached idle timeout on socket %s", buffer);
 2131             goto do_close;
 2132         }
 2133 
 2134         /*
 2135          *  Enforce the minimum of idle timeout or lifetime.
 2136          */
 2137         if (timercmp(&idle, &end, <)) {
 2138             end = idle;
 2139         }
 2140     }
 2141 
 2142     /*
 2143      *  Wake up at t + 0.5s.  The code above checks if the timers
 2144      *  are <= t.  This addition gives us a bit of leeway.
 2145      */
 2146     end.tv_usec = USEC / 2;
 2147 
 2148     ASSERT_MASTER;
 2149     if (!fr_event_insert(el, tcp_socket_timer, listener, &end, &sock->ev)) {
 2150         rad_panic("Failed to insert event");
 2151     }
 2152 }
 2153 
 2154 
 2155 #ifdef WITH_PROXY
 2156 /*
 2157  *  Called by socket_del to remove requests with this socket
 2158  */
 2159 static int eol_proxy_listener(void *ctx, void *data)
 2160 {
 2161     rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
 2162     RADIUS_PACKET **proxy_p = data;
 2163     REQUEST *request;
 2164 
 2165     request = fr_packet2myptr(REQUEST, proxy, proxy_p);
 2166     if (request->proxy_listener != this) return 0;
 2167 
 2168     /*
 2169      *  The normal "remove_from_proxy_hash" tries to grab the
 2170      *  proxy mutex.  We already have it held, so grabbing it
 2171      *  again will cause a deadlock.  Instead, call the "no
 2172      *  lock" version of the function.
 2173      */
 2174     rad_assert(request->in_proxy_hash == true);
 2175     remove_from_proxy_hash_nl(request, false);
 2176 
 2177     /*
 2178      *  Don't mark it as DONE.  The client can retransmit, and
 2179      *  the packet SHOULD be re-proxied somewhere else.
 2180      *
 2181      *  Return "2" means that the rbtree code will remove it
 2182      *  from the tree, and we don't need to do it ourselves.
 2183      */
 2184     return 2;
 2185 }
 2186 #endif  /* WITH_PROXY */
 2187 
 2188 static int eol_listener(void *ctx, void *data)
 2189 {
 2190     rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
 2191     RADIUS_PACKET **packet_p = data;
 2192     REQUEST *request;
 2193 
 2194     request = fr_packet2myptr(REQUEST, packet, packet_p);
 2195     if (request->listener != this) return 0;
 2196 
 2197     request->master_state = REQUEST_STOP_PROCESSING;
 2198     request->process = request_done;
 2199 
 2200     return 0;
 2201 }
 2202 #endif  /* WITH_TCP */
 2203 
 2204 #ifdef WITH_PROXY
 2205 /***********************************************************************
 2206  *
 2207  *  Proxy handlers for the state machine.
 2208  *
 2209  ***********************************************************************/
 2210 
 2211 /*
 2212  *  Called with the proxy mutex held
 2213  */
 2214 static void remove_from_proxy_hash_nl(REQUEST *request, bool yank)
 2215 {
 2216     VERIFY_REQUEST(request);
 2217 
 2218     if (!request->in_proxy_hash) return;
 2219 
 2220     fr_packet_list_id_free(proxy_list, request->proxy, yank);
 2221     request->in_proxy_hash = false;
 2222 
 2223     /*
 2224      *  On the FIRST reply, decrement the count of outstanding
 2225      *  requests.  Note that this is NOT the count of sent
 2226      *  packets, but whether or not the home server has
 2227      *  responded at all.
 2228      */
 2229     if (request->home_server &&
 2230         request->home_server->currently_outstanding) {
 2231         request->home_server->currently_outstanding--;
 2232 
 2233         /*
 2234          *  If we're NOT sending it packets, AND it's been
 2235          *  a while since we got a response, then we don't
 2236          *  know if it's alive or dead.
 2237          */
 2238         if ((request->home_server->currently_outstanding == 0) &&
 2239             (request->home_server->state == HOME_STATE_ALIVE)) {
 2240             struct timeval when, now;
 2241 
 2242             when.tv_sec = request->home_server->last_packet_recv ;
 2243             when.tv_usec = 0;
 2244 
 2245             timeradd(&when, request_response_window(request), &when);
 2246             gettimeofday(&now, NULL);
 2247 
 2248             /*
 2249              *  last_packet + response_window
 2250              *
 2251              *  We *administratively* mark the home
 2252              *  server as "unknown" state, because we
 2253              *  haven't seen a packet for a while.
 2254              */
 2255             if (timercmp(&now, &when, >)) {
 2256                 request->home_server->state = HOME_STATE_UNKNOWN;
 2257                 request->home_server->last_packet_sent = 0;
 2258                 request->home_server->last_packet_recv = 0;
 2259             }
 2260         }
 2261     }
 2262 
 2263 #ifdef WITH_TCP
 2264     if (request->proxy_listener) {
 2265         request->proxy_listener->count--;
 2266     }
 2267 #endif
 2268     request->proxy_listener = NULL;
 2269 
 2270     /*
 2271      *  Got from YES in hash, to NO, not in hash while we hold
 2272      *  the mutex.  This guarantees that when another thread
 2273      *  grabs the mutex, the "not in hash" flag is correct.
 2274      */
 2275 }
 2276 
 2277 static void remove_from_proxy_hash(REQUEST *request)
 2278 {
 2279     VERIFY_REQUEST(request);
 2280 
 2281     /*
 2282      *  Check this without grabbing the mutex because it's a
 2283      *  lot faster that way.
 2284      */
 2285     if (!request->in_proxy_hash) return;
 2286 
 2287     /*
 2288      *  The "not in hash" flag is definitive.  However, if the
 2289      *  flag says that it IS in the hash, there might still be
 2290      *  a race condition where it isn't.
 2291      */
 2292     PTHREAD_MUTEX_LOCK(&proxy_mutex);
 2293 
 2294     if (!request->in_proxy_hash) {
 2295         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2296         return;
 2297     }
 2298 
 2299     remove_from_proxy_hash_nl(request, true);
 2300 
 2301     PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2302 }
 2303 
 2304 static int insert_into_proxy_hash(REQUEST *request)
 2305 {
 2306     char buf[128];
 2307     int tries;
 2308     bool success = false;
 2309     void *proxy_listener;
 2310 
 2311     VERIFY_REQUEST(request);
 2312 
 2313     rad_assert(request->proxy != NULL);
 2314     rad_assert(request->home_server != NULL);
 2315     rad_assert(proxy_list != NULL);
 2316 
 2317 
 2318     PTHREAD_MUTEX_LOCK(&proxy_mutex);
 2319     proxy_listener = NULL;
 2320     request->num_proxied_requests = 1;
 2321     request->num_proxied_responses = 0;
 2322 
 2323     for (tries = 0; tries < 2; tries++) {
 2324         rad_listen_t *this;
 2325         listen_socket_t *sock;
 2326 
 2327         RDEBUG3("proxy: Trying to allocate ID (%d/2)", tries);
 2328         success = fr_packet_list_id_alloc(proxy_list,
 2329                         request->home_server->proto,
 2330                         &request->proxy, &proxy_listener);
 2331         if (success) break;
 2332 
 2333         if (tries > 0) continue; /* try opening new socket only once */
 2334 
 2335 #ifdef HAVE_PTHREAD_H
 2336         if (proxy_no_new_sockets) break;
 2337 #endif
 2338 
 2339         RDEBUG3("proxy: Trying to open a new listener to the home server");
 2340         this = proxy_new_listener(proxy_ctx, request->home_server, 0);
 2341         if (!this) {
 2342             request->home_server->state = HOME_STATE_CONNECTION_FAIL;
 2343             PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2344             goto fail;
 2345         }
 2346 
 2347         request->proxy->src_port = 0; /* Use any new socket */
 2348         proxy_listener = this;
 2349 
 2350         sock = this->data;
 2351         if (!fr_packet_list_socket_add(proxy_list, this->fd,
 2352                            sock->proto,
 2353                            &sock->other_ipaddr, sock->other_port,
 2354                            this)) {
 2355 
 2356 #ifdef HAVE_PTHREAD_H
 2357             proxy_no_new_sockets = true;
 2358 #endif
 2359             PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2360 
 2361             /*
 2362              *  This is bad.  However, the
 2363              *  packet list now supports 256
 2364              *  open sockets, which should
 2365              *  minimize this problem.
 2366              */
 2367             ERROR("Failed adding proxy socket: %s",
 2368                   fr_strerror());
 2369             goto fail;
 2370         }
 2371 
 2372         /*
 2373          *  Add it to the event loop.  Ensure that we have
 2374          *  only one mutex locked at a time.
 2375          */
 2376         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2377         radius_update_listener(this);
 2378         PTHREAD_MUTEX_LOCK(&proxy_mutex);
 2379     }
 2380 
 2381     if (!proxy_listener || !success) {
 2382         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2383         REDEBUG2("proxy: Failed allocating Id for proxied request");
 2384     fail:
 2385         request->proxy_listener = NULL;
 2386         request->in_proxy_hash = false;
 2387         return 0;
 2388     }
 2389 
 2390     rad_assert(request->proxy->id >= 0);
 2391 
 2392     request->proxy_listener = proxy_listener;
 2393     request->in_proxy_hash = true;
 2394     RDEBUG3("proxy: request is now in proxy hash");
 2395 
 2396     /*
 2397      *  Keep track of maximum outstanding requests to a
 2398      *  particular home server.  'max_outstanding' is
 2399      *  enforced in home_server_ldb(), in realms.c.
 2400      */
 2401     request->home_server->currently_outstanding++;
 2402 
 2403 #ifdef WITH_TCP
 2404     request->proxy_listener->count++;
 2405 #endif
 2406 
 2407     PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2408 
 2409     RDEBUG3("proxy: allocating destination %s port %d - Id %d",
 2410            inet_ntop(request->proxy->dst_ipaddr.af,
 2411              &request->proxy->dst_ipaddr.ipaddr, buf, sizeof(buf)),
 2412            request->proxy->dst_port,
 2413            request->proxy->id);
 2414 
 2415     return 1;
 2416 }
 2417 
 2418 static int process_proxy_reply(REQUEST *request, RADIUS_PACKET *reply)
 2419 {
 2420     int rcode;
 2421     int post_proxy_type = 0;
 2422     VALUE_PAIR *vp;
 2423     char const *old_server;
 2424 
 2425     VERIFY_REQUEST(request);
 2426 
 2427     /*
 2428      *  There may be a proxy reply, but it may be too late.
 2429      */
 2430     if ((request->home_server && !request->home_server->server) && !request->proxy_listener) return 0;
 2431 
 2432     /*
 2433      *  Delete any reply we had accumulated until now.
 2434      */
 2435     RDEBUG2("Clearing existing &reply: attributes");
 2436     fr_pair_list_free(&request->reply->vps);
 2437 
 2438     /*
 2439      *  Run the packet through the post-proxy stage,
 2440      *  BEFORE playing games with the attributes.
 2441      */
 2442     vp = fr_pair_find_by_num(request->config, PW_POST_PROXY_TYPE, 0, TAG_ANY);
 2443     if (vp) {
 2444         post_proxy_type = vp->vp_integer;
 2445     /*
 2446      *  If we have a proxy_reply, and it was a reject, or a NAK
 2447      *  setup Post-Proxy <type>.
 2448      *
 2449      *  If the <type> doesn't have a section, then the Post-Proxy
 2450      *  section is ignored.
 2451      */
 2452     } else if (reply) {
 2453         DICT_VALUE *dval = NULL;
 2454 
 2455         switch (reply->code) {
 2456         case PW_CODE_ACCESS_REJECT:
 2457             dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Reject");
 2458             if (dval) post_proxy_type = dval->value;
 2459             break;
 2460 
 2461         case PW_CODE_DISCONNECT_NAK:
 2462             dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, fr_packet_codes[reply->code]);
 2463             if (dval) post_proxy_type = dval->value;
 2464             break;
 2465 
 2466         case PW_CODE_COA_NAK:
 2467             dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, fr_packet_codes[reply->code]);
 2468             if (dval) post_proxy_type = dval->value;
 2469             break;
 2470 
 2471         default:
 2472             break;
 2473         }
 2474 
 2475         /*
 2476          *  Create config:Post-Proxy-Type
 2477          */
 2478         if (dval) {
 2479             vp = radius_pair_create(request, &request->config, PW_POST_PROXY_TYPE, 0);
 2480             vp->vp_integer = dval->value;
 2481         }
 2482     }
 2483 
 2484     if (post_proxy_type > 0) RDEBUG2("Found Post-Proxy-Type %s",
 2485                      dict_valnamebyattr(PW_POST_PROXY_TYPE, 0, post_proxy_type));
 2486 
 2487     if (reply) {
 2488         VERIFY_PACKET(reply);
 2489 
 2490         /*
 2491          *  Decode the packet if required.
 2492          */
 2493         if (request->proxy_listener) {
 2494             rcode = request->proxy_listener->decode(request->proxy_listener, request);
 2495             debug_packet(request, reply, true);
 2496 
 2497             /*
 2498              *  Pro-actively remove it from the proxy hash.
 2499              *  This is later than in 2.1.x, but it means that
 2500              *  the replies are authenticated before being
 2501              *  removed from the hash.
 2502              */
 2503             if ((rcode == 0) &&
 2504                 (request->num_proxied_requests <= request->num_proxied_responses)) {
 2505                 remove_from_proxy_hash(request);
 2506             }
 2507         } else {
 2508             rad_assert(!request->in_proxy_hash);
 2509         }
 2510     } else if (request->in_proxy_hash) {
 2511         remove_from_proxy_hash(request);
 2512     }
 2513 
 2514 
 2515     /*
 2516      *  Run the request through the virtual server for the
 2517      *  home server, OR through the virtual server for the
 2518      *  home server pool.
 2519      */
 2520     old_server = request->server;
 2521     if (request->home_server && request->home_server->server) {
 2522         request->server = request->home_server->server;
 2523 
 2524     } else if (request->home_pool && request->home_pool->virtual_server) {
 2525         request->server = request->home_pool->virtual_server;
 2526     }
 2527 
 2528     /*
 2529      *  Run the request through the given virtual server.
 2530      */
 2531     RDEBUG2("server %s {", request->server);
 2532     RINDENT();
 2533     rcode = process_post_proxy(post_proxy_type, request);
 2534     REXDENT();
 2535     RDEBUG2("}");
 2536     request->server = old_server;
 2537 
 2538 #ifdef WITH_COA
 2539     if (request->proxy && request->packet->code == request->proxy->code) {
 2540       /*
 2541        *    Don't run the next bit if we originated a CoA
 2542        *    packet, after receiving an Access-Request or
 2543        *    Accounting-Request.
 2544        */
 2545 #endif
 2546 
 2547         /*
 2548          *  There may NOT be a proxy reply, as we may be
 2549          *  running Post-Proxy-Type = Fail.
 2550          */
 2551         if (reply) {
 2552             fr_pair_add(&request->reply->vps, fr_pair_list_copy(request->reply, reply->vps));
 2553 
 2554             /*
 2555              *  Delete the Proxy-State Attributes from
 2556              *  the reply.  These include Proxy-State
 2557              *  attributes from us and remote server.
 2558              */
 2559             fr_pair_delete_by_num(&request->reply->vps, PW_PROXY_STATE, 0, TAG_ANY);
 2560 
 2561         } else {
 2562             vp = fr_pair_find_by_num(request->config, PW_RESPONSE_PACKET_TYPE, 0, TAG_ANY);
 2563             if (vp && (vp->vp_integer != 256)) {
 2564                 request->proxy_reply = rad_alloc_reply(request, request->proxy);
 2565                 request->proxy_reply->code = vp->vp_integer;
 2566             }
 2567         }
 2568 #ifdef WITH_COA
 2569     }
 2570 #endif
 2571     switch (rcode) {
 2572     default:  /* Don't do anything */
 2573         break;
 2574     case RLM_MODULE_FAIL:
 2575         return 0;
 2576 
 2577     case RLM_MODULE_HANDLED:
 2578         return 0;
 2579     }
 2580 
 2581     return 1;
 2582 }
 2583 
 2584 static void mark_home_server_alive(REQUEST *request, home_server_t *home)
 2585 {
 2586     char buffer[128];
 2587 
 2588     home->state = HOME_STATE_ALIVE;
 2589     home->response_timeouts = 0;
 2590     exec_trigger(request, home->cs, "home_server.alive", false);
 2591     home->currently_outstanding = 0;
 2592     home->num_sent_pings = 0;
 2593     home->num_received_pings = 0;
 2594     gettimeofday(&home->revive_time, NULL);
 2595 
 2596     fr_event_delete(el, &home->ev);
 2597 
 2598     RPROXY("Marking home server %s port %d alive",
 2599            inet_ntop(request->proxy->dst_ipaddr.af,
 2600              &request->proxy->dst_ipaddr.ipaddr,
 2601              buffer, sizeof(buffer)),
 2602            request->proxy->dst_port);
 2603 }
 2604 
 2605 
 2606 int request_proxy_reply(RADIUS_PACKET *packet)
 2607 {
 2608     RADIUS_PACKET **proxy_p;
 2609     REQUEST *request;
 2610     struct timeval now;
 2611     char buffer[128];
 2612 
 2613     VERIFY_PACKET(packet);
 2614 
 2615     PTHREAD_MUTEX_LOCK(&proxy_mutex);
 2616     proxy_p = fr_packet_list_find_byreply(proxy_list, packet);
 2617 
 2618     if (!proxy_p) {
 2619         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2620         PROXY("No outstanding request was found for %s packet from host %s port %d - ID %u",
 2621                fr_packet_codes[packet->code],
 2622                inet_ntop(packet->src_ipaddr.af,
 2623                  &packet->src_ipaddr.ipaddr,
 2624                  buffer, sizeof(buffer)),
 2625                packet->src_port, packet->id);
 2626         return 0;
 2627     }
 2628 
 2629     request = fr_packet2myptr(REQUEST, proxy, proxy_p);
 2630 
 2631     PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 2632 
 2633     /*
 2634      *  No reply, BUT the current packet fails verification:
 2635      *  ignore it.  This does the MD5 calculations in the
 2636      *  server core, but I guess we can fix that later.
 2637      */
 2638     if (!request->proxy_reply &&
 2639         (rad_verify(packet, request->proxy,
 2640             request->home_server->secret) != 0)) {
 2641         DEBUG("Ignoring spoofed proxy reply.  Signature is invalid");
 2642         return 0;
 2643     }
 2644 
 2645     /*
 2646      *  The home server sent us a packet which doesn't match
 2647      *  something we have: ignore it.  This is done only to
 2648      *  catch the case of broken systems.
 2649      */
 2650     if (request->proxy_reply &&
 2651         (memcmp(request->proxy_reply->vector,
 2652             packet->vector,
 2653             sizeof(request->proxy_reply->vector)) != 0)) {
 2654         RDEBUG2("Ignoring conflicting proxy reply");
 2655         return 0;
 2656     }
 2657 
 2658     /*
 2659      *  This shouldn't happen, but threads and race
 2660      *  conditions.
 2661      */
 2662     if (!request->proxy_listener || !request->proxy_listener->data) {
 2663         proxy_reply_too_late(request);
 2664         return 0;
 2665     }
 2666 
 2667     gettimeofday(&now, NULL);
 2668 
 2669     /*
 2670      *  Status-Server packets don't count as real packets.
 2671      */
 2672     if (request->proxy->code != PW_CODE_STATUS_SERVER) {
 2673 #ifdef WITH_TCP
 2674         listen_socket_t *sock = request->proxy_listener->data;
 2675 
 2676         sock->last_packet = now.tv_sec;
 2677 #endif
 2678         request->home_server->last_packet_recv = now.tv_sec;
 2679     }
 2680 
 2681     request->num_proxied_responses++;
 2682 
 2683     /*
 2684      *  If we have previously seen a reply, ignore the
 2685      *  duplicate.
 2686      */
 2687     if (request->proxy_reply) {
 2688         RDEBUG2("Discarding duplicate reply from host %s port %d  - ID: %d",
 2689             inet_ntop(packet->src_ipaddr.af,
 2690                   &packet->src_ipaddr.ipaddr,
 2691                   buffer, sizeof(buffer)),
 2692             packet->src_port, packet->id);
 2693         return 0;
 2694     }
 2695 
 2696     /*
 2697      *  Call the state machine to do something useful with the
 2698      *  request.
 2699      */
 2700     request->proxy_reply = talloc_steal(request, packet);
 2701     packet->timestamp = now;
 2702     request->priority = RAD_LISTEN_PROXY;
 2703 
 2704 #ifdef WITH_STATS
 2705     /*
 2706      *  Update the proxy listener stats here, because only one
 2707      *  thread accesses that at a time.  The home_server and
 2708      *  main proxy_*_stats structures are updated once the
 2709      *  request is cleaned up.
 2710      */
 2711     request->proxy_listener->stats.total_responses++;
 2712 
 2713     request->home_server->stats.last_packet = packet->timestamp.tv_sec;
 2714     request->proxy_listener->stats.last_packet = packet->timestamp.tv_sec;
 2715 
 2716     switch (request->proxy->code) {
 2717     case PW_CODE_ACCESS_REQUEST:
 2718         proxy_auth_stats.last_packet = packet->timestamp.tv_sec;
 2719 
 2720         if (request->proxy_reply->code == PW_CODE_ACCESS_ACCEPT) {
 2721             request->proxy_listener->stats.total_access_accepts++;
 2722 
 2723         } else if (request->proxy_reply->code == PW_CODE_ACCESS_REJECT) {
 2724             request->proxy_listener->stats.total_access_rejects++;
 2725 
 2726         } else if (request->proxy_reply->code == PW_CODE_ACCESS_CHALLENGE) {
 2727             request->proxy_listener->stats.total_access_challenges++;
 2728         }
 2729         break;
 2730 
 2731 #ifdef WITH_ACCOUNTING
 2732     case PW_CODE_ACCOUNTING_REQUEST:
 2733         request->proxy_listener->stats.total_responses++;
 2734         proxy_acct_stats.last_packet = packet->timestamp.tv_sec;
 2735         break;
 2736 
 2737 #endif
 2738 
 2739 #ifdef WITH_COA
 2740     case PW_CODE_COA_REQUEST:
 2741         request->proxy_listener->stats.total_responses++;
 2742         proxy_coa_stats.last_packet = packet->timestamp.tv_sec;
 2743         break;
 2744 
 2745     case PW_CODE_DISCONNECT_REQUEST:
 2746         request->proxy_listener->stats.total_responses++;
 2747         proxy_dsc_stats.last_packet = packet->timestamp.tv_sec;
 2748         break;
 2749 
 2750 #endif
 2751     default:
 2752         break;
 2753     }
 2754 #endif
 2755 
 2756     /*
 2757      *  If we hadn't been sending the home server packets for
 2758      *  a while, just mark it alive.  Or, if it was zombie,
 2759      *  it's now responded, and is therefore alive.
 2760      */
 2761     if ((request->home_server->state == HOME_STATE_UNKNOWN) ||
 2762         (request->home_server->state == HOME_STATE_ZOMBIE)) {
 2763         mark_home_server_alive(request, request->home_server);
 2764     }
 2765 
 2766     /*
 2767      *  Tell the request state machine that we have a proxy
 2768      *  reply.  Depending on the function, this should either
 2769      *  ignore it, or process it.
 2770      */
 2771     request->process(request, FR_ACTION_PROXY_REPLY);
 2772 
 2773     return 1;
 2774 }
 2775 
 2776 
 2777 static int setup_post_proxy_fail(REQUEST *request)
 2778 {
 2779     DICT_VALUE const *dval = NULL;
 2780     VALUE_PAIR *vp;
 2781     RADIUS_PACKET *packet;
 2782 
 2783     VERIFY_REQUEST(request);
 2784 
 2785     packet = request->proxy ? request->proxy : request->packet;
 2786 
 2787     if (packet->code == PW_CODE_ACCESS_REQUEST) {
 2788         dval = dict_valbyname(PW_POST_PROXY_TYPE, 0,
 2789                       "Fail-Authentication");
 2790 #ifdef WITH_ACCOUNTING
 2791     } else if (packet->code == PW_CODE_ACCOUNTING_REQUEST) {
 2792         dval = dict_valbyname(PW_POST_PROXY_TYPE, 0,
 2793                       "Fail-Accounting");
 2794 #endif
 2795 
 2796 #ifdef WITH_COA
 2797     } else if (packet->code == PW_CODE_COA_REQUEST) {
 2798         dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail-CoA");
 2799 
 2800     } else if (packet->code == PW_CODE_DISCONNECT_REQUEST) {
 2801         dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail-Disconnect");
 2802 #endif
 2803     } else {
 2804         WARN("Unknown packet type in Post-Proxy-Type Fail: ignoring");
 2805         return 0;
 2806     }
 2807 
 2808     if (!dval) dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail");
 2809 
 2810     if (!dval) {
 2811         fr_pair_delete_by_num(&request->config, PW_POST_PROXY_TYPE, 0, TAG_ANY);
 2812         return 0;
 2813     }
 2814 
 2815     vp = fr_pair_find_by_num(request->config, PW_POST_PROXY_TYPE, 0, TAG_ANY);
 2816     if (!vp) vp = radius_pair_create(request, &request->config,
 2817                     PW_POST_PROXY_TYPE, 0);
 2818     vp->vp_integer = dval->value;
 2819 
 2820     return 1;
 2821 }
 2822 
 2823 
 2824 /** Process a request after the proxy has timed out.
 2825  *
 2826  *  Run the packet through Post-Proxy-Type Fail
 2827  *
 2828  *  \dot
 2829  *  digraph proxy_no_reply {
 2830  *      proxy_no_reply;
 2831  *
 2832  *      proxy_no_reply -> dup [ label = "DUP", arrowhead = "none" ];
 2833  *      proxy_no_reply -> timer [ label = "TIMER < max_request_time" ];
 2834  *      proxy_no_reply -> proxy_reply_too_late [ label = "PROXY_REPLY" arrowhead = "none"];
 2835  *      proxy_no_reply -> process_proxy_reply [ label = "RUN" ];
 2836  *      proxy_no_reply -> done [ label = "TIMER >= timeout" ];
 2837  *  }
 2838  *  \enddot
 2839  */
 2840 static void proxy_no_reply(REQUEST *request, int action)
 2841 {
 2842     VERIFY_REQUEST(request);
 2843 
 2844     TRACE_STATE_MACHINE;
 2845     CHECK_FOR_STOP;
 2846 
 2847     switch (action) {
 2848     case FR_ACTION_DUP:
 2849         request_dup(request);
 2850         break;
 2851 
 2852     case FR_ACTION_TIMER:
 2853         (void) request_max_time(request);
 2854         break;
 2855 
 2856     case FR_ACTION_PROXY_REPLY:
 2857         proxy_reply_too_late(request);
 2858         break;
 2859 
 2860     case FR_ACTION_RUN:
 2861         if (process_proxy_reply(request, NULL)) {
 2862             request->handle(request);
 2863         }
 2864         request_finish(request, action);
 2865         break;
 2866 
 2867     default:
 2868         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 2869         break;
 2870     }
 2871 }
 2872 
 2873 /** Process the request after receiving a proxy reply.
 2874  *
 2875  *  Throught the post-proxy section, and the through the handler
 2876  *  function.
 2877  *
 2878  *  \dot
 2879  *  digraph proxy_running {
 2880  *      proxy_running;
 2881  *
 2882  *      proxy_running -> dup [ label = "DUP", arrowhead = "none" ];
 2883  *      proxy_running -> timer [ label = "TIMER < max_request_time" ];
 2884  *      proxy_running -> process_proxy_reply [ label = "RUN" ];
 2885  *      proxy_running -> done [ label = "TIMER >= timeout" ];
 2886  *  }
 2887  *  \enddot
 2888  */
 2889 static void proxy_running(REQUEST *request, int action)
 2890 {
 2891     VERIFY_REQUEST(request);
 2892 
 2893     TRACE_STATE_MACHINE;
 2894     CHECK_FOR_STOP;
 2895 
 2896     switch (action) {
 2897     case FR_ACTION_DUP:
 2898         request_dup(request);
 2899         break;
 2900 
 2901     case FR_ACTION_TIMER:
 2902         (void) request_max_time(request);
 2903         break;
 2904 
 2905     case FR_ACTION_RUN:
 2906         if (process_proxy_reply(request, request->proxy_reply)) {
 2907             request->handle(request);
 2908         }
 2909         request_finish(request, action);
 2910         break;
 2911 
 2912     default:        /* duplicate proxy replies are suppressed */
 2913         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 2914         break;
 2915     }
 2916 }
 2917 
 2918 /** Determine if a #REQUEST needs to be proxied, and perform pre-proxy operations
 2919  *
 2920  * Whether a request will be proxied is determined by the attributes present
 2921  * in request->config. If any of the following attributes are found, the
 2922  * request may be proxied.
 2923  *
 2924  * The key attributes are:
 2925  *   - PW_PROXY_TO_REALM          - Specifies a realm the request should be proxied to.
 2926  *   - PW_HOME_SERVER_POOL        - Specifies a specific home server pool to proxy to.
 2927  *   - PW_HOME_SERVER_NAME        - Specifies a home server by name
 2928  *   - PW_PACKET_DST_IP_ADDRESS   - Specifies a home server by IPv4 address
 2929  *   - PW_PACKET_DST_IPV6_ADDRESS - Specifies a home server by IPv5 address
 2930  *
 2931  * Certain packet types such as #PW_CODE_STATUS_SERVER will never be proxied.
 2932  *
 2933  * If request should be proxied, will:
 2934  *   - Add request:Proxy-State
 2935  *   - Strip the current username value of its realm (depending on config)
 2936  *   - Create a CHAP-Challenge from the original request vector, if one doesn't already
 2937  *     exist.
 2938  *   - Call the pre-process section in the current server, or in the virtual server
 2939  *     associated with the home server pool we're proxying to.
 2940  *
 2941  * @todo A lot of this logic is RADIUS specific, and should be moved out into a protocol
 2942  *  specific function.
 2943  *
 2944  * @param request The #REQUEST to evaluate for proxying.
 2945  * @return 0 if not proxying, 1 if request should be proxied, -1 on error.
 2946  */
 2947 static int request_will_proxy(REQUEST *request)
 2948 {
 2949     int rcode, pre_proxy_type = 0;
 2950     char const *realmname = NULL;
 2951     VALUE_PAIR *vp, *strippedname;
 2952     home_server_t *home;
 2953     REALM *realm = NULL;
 2954     home_pool_t *pool = NULL;
 2955     char const *old_server;
 2956 
 2957     VERIFY_REQUEST(request);
 2958 
 2959     if (!request->root->proxy_requests) return 0;
 2960     if (request->packet->dst_port == 0) return 0;
 2961     if (request->packet->code == PW_CODE_STATUS_SERVER) return 0;
 2962     if (request->in_proxy_hash) return 0;
 2963 
 2964     /*
 2965      *  FIXME: for 3.0, allow this only for rejects?
 2966      */
 2967     if (request->reply->code != 0) return 0;
 2968 
 2969     vp = fr_pair_find_by_num(request->config, PW_PROXY_TO_REALM, 0, TAG_ANY);
 2970     if (vp) {
 2971         realm = realm_find2(vp->vp_strvalue);
 2972         if (!realm) {
 2973             REDEBUG2("Cannot proxy to unknown realm %s",
 2974                 vp->vp_strvalue);
 2975             return 0;
 2976         }
 2977 
 2978         realmname = vp->vp_strvalue;
 2979 
 2980         /*
 2981          *  Figure out which pool to use.
 2982          */
 2983         if (request->packet->code == PW_CODE_ACCESS_REQUEST) {
 2984             DEBUG3("Using home pool auth for realm %s", realm->name);
 2985             pool = realm->auth_pool;
 2986 
 2987 #ifdef WITH_ACCOUNTING
 2988         } else if (request->packet->code == PW_CODE_ACCOUNTING_REQUEST) {
 2989             DEBUG3("Using home pool acct for realm %s", realm->name);
 2990             pool = realm->acct_pool;
 2991 #endif
 2992 
 2993 #ifdef WITH_COA
 2994         } else if ((request->packet->code == PW_CODE_COA_REQUEST) ||
 2995                (request->packet->code == PW_CODE_DISCONNECT_REQUEST)) {
 2996             DEBUG3("Using home pool coa for realm %s", realm->name);
 2997             pool = realm->coa_pool;
 2998 #endif
 2999 
 3000         } else {
 3001             return 0;
 3002         }
 3003 
 3004     } else if ((vp = fr_pair_find_by_num(request->config, PW_HOME_SERVER_POOL, 0, TAG_ANY)) != NULL) {
 3005         int pool_type;
 3006 
 3007         DEBUG3("Using Home-Server-Pool %s", vp->vp_strvalue);
 3008 
 3009         switch (request->packet->code) {
 3010         case PW_CODE_ACCESS_REQUEST:
 3011             pool_type = HOME_TYPE_AUTH;
 3012             break;
 3013 
 3014 #ifdef WITH_ACCOUNTING
 3015         case PW_CODE_ACCOUNTING_REQUEST:
 3016             pool_type = HOME_TYPE_ACCT;
 3017             break;
 3018 #endif
 3019 
 3020 #ifdef WITH_COA
 3021         case PW_CODE_COA_REQUEST:
 3022         case PW_CODE_DISCONNECT_REQUEST:
 3023             pool_type = HOME_TYPE_COA;
 3024             break;
 3025 #endif
 3026 
 3027         default:
 3028             return 0;
 3029         }
 3030 
 3031         pool = home_pool_byname(vp->vp_strvalue, pool_type);
 3032 
 3033         /*
 3034          *  Send it directly to a home server (i.e. NAS)
 3035          */
 3036     } else if (((vp = fr_pair_find_by_num(request->config, PW_PACKET_DST_IP_ADDRESS, 0, TAG_ANY)) != NULL) ||
 3037            ((vp = fr_pair_find_by_num(request->config, PW_PACKET_DST_IPV6_ADDRESS, 0, TAG_ANY)) != NULL)) {
 3038         uint16_t dst_port;
 3039         fr_ipaddr_t dst_ipaddr;
 3040 
 3041         memset(&dst_ipaddr, 0, sizeof(dst_ipaddr));
 3042 
 3043         if (vp->da->attr == PW_PACKET_DST_IP_ADDRESS) {
 3044             dst_ipaddr.af = AF_INET;
 3045             dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
 3046             dst_ipaddr.prefix = 32;
 3047         } else {
 3048             dst_ipaddr.af = AF_INET6;
 3049             memcpy(&dst_ipaddr.ipaddr.ip6addr, &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
 3050             dst_ipaddr.prefix = 128;
 3051         }
 3052 
 3053         vp = fr_pair_find_by_num(request->config, PW_PACKET_DST_PORT, 0, TAG_ANY);
 3054         if (!vp) {
 3055             if (request->packet->code == PW_CODE_ACCESS_REQUEST) {
 3056                 dst_port = PW_AUTH_UDP_PORT;
 3057 
 3058 #ifdef WITH_ACCOUNTING
 3059             } else if (request->packet->code == PW_CODE_ACCOUNTING_REQUEST) {
 3060                 dst_port = PW_ACCT_UDP_PORT;
 3061 #endif
 3062 
 3063 #ifdef WITH_COA
 3064             } else if ((request->packet->code == PW_CODE_COA_REQUEST) ||
 3065                    (request->packet->code == PW_CODE_DISCONNECT_REQUEST)) {
 3066                 dst_port = PW_COA_UDP_PORT;
 3067 #endif
 3068             } else { /* shouldn't happen for RADIUS... */
 3069                 return 0;
 3070             }
 3071 
 3072         } else {
 3073             dst_port = vp->vp_integer;
 3074         }
 3075 
 3076         /*
 3077          *  Nothing does CoA over TCP.
 3078          */
 3079         home = home_server_find(&dst_ipaddr, dst_port, IPPROTO_UDP);
 3080         if (!home) {
 3081             char buffer[256];
 3082 
 3083             RWDEBUG("No such home server %s port %u",
 3084                 inet_ntop(dst_ipaddr.af, &dst_ipaddr.ipaddr, buffer, sizeof(buffer)),
 3085                 (unsigned int) dst_port);
 3086             return 0;
 3087         }
 3088 
 3089         /*
 3090          *  The home server is alive (or may be alive).
 3091          *  Send the packet to the IP.
 3092          */
 3093         if (home->state < HOME_STATE_IS_DEAD) goto do_home;
 3094 
 3095         /*
 3096          *  The home server is dead.  If you wanted
 3097          *  fail-over, you should have proxied to a pool.
 3098          *  Sucks to be you.
 3099          */
 3100 
 3101         return 0;
 3102 
 3103     } else if ((vp = fr_pair_find_by_num(request->config, PW_HOME_SERVER_NAME, 0, TAG_ANY)) != NULL) {
 3104         int type;
 3105 
 3106         switch (request->packet->code) {
 3107         case PW_CODE_ACCESS_REQUEST:
 3108             type = HOME_TYPE_AUTH;
 3109             break;
 3110 
 3111 #ifdef WITH_ACCOUNTING
 3112         case PW_CODE_ACCOUNTING_REQUEST:
 3113             type = HOME_TYPE_ACCT;
 3114             break;
 3115 #endif
 3116 
 3117 #ifdef WITH_COA
 3118         case PW_CODE_COA_REQUEST:
 3119         case PW_CODE_DISCONNECT_REQUEST:
 3120             type = HOME_TYPE_COA;
 3121             break;
 3122 #endif
 3123 
 3124         default:
 3125             return 0;
 3126         }
 3127 
 3128         /*
 3129          *  Find the home server by name.
 3130          */
 3131         home = home_server_byname(vp->vp_strvalue, type);
 3132         if (!home) {
 3133             RWDEBUG("No such home server %s", vp->vp_strvalue);
 3134             return 0;
 3135         }
 3136 
 3137         /*
 3138          *  The home server is alive (or may be alive).
 3139          *  Send the packet to the IP.
 3140          */
 3141         if (home->state < HOME_STATE_IS_DEAD) goto do_home;
 3142 
 3143         /*
 3144          *  The home server is dead.  If you wanted
 3145          *  fail-over, you should have proxied to a pool.
 3146          *  Sucks to be you.
 3147          */
 3148 
 3149         return 0;
 3150 
 3151     } else {
 3152         return 0;
 3153     }
 3154 
 3155     if (!pool) {
 3156         RWDEBUG2("Cancelling proxy as no home pool exists");
 3157         return 0;
 3158     }
 3159 
 3160     if (request->listener->synchronous) {
 3161         WARN("Cannot proxy a request which is from a 'synchronous' socket");
 3162         return 0;
 3163     }
 3164 
 3165     request->home_pool = pool;
 3166 
 3167     home = home_server_ldb(realmname, pool, request);
 3168 
 3169     if (!home) {
 3170         REDEBUG2("Failed to find live home server: Cancelling proxy");
 3171         return -1;
 3172     }
 3173 
 3174 do_home:
 3175     home_server_update_request(home, request);
 3176 
 3177 #ifdef WITH_COA
 3178     /*
 3179      *  Once we've decided to proxy a request, we cannot send
 3180      *  a CoA packet.  So we free up any CoA packet here.
 3181      */
 3182     if (request->coa) request_done(request->coa, FR_ACTION_CANCELLED);
 3183 #endif
 3184 
 3185     /*
 3186      *  Remember that we sent the request to a Realm.
 3187      */
 3188     if (realmname) pair_make_request("Realm", realmname, T_OP_EQ);
 3189 
 3190     /*
 3191      *  Strip the name, if told to.
 3192      *
 3193      *  Doing it here catches the case of proxied tunneled
 3194      *  requests.
 3195      */
 3196     if (realm && (realm->strip_realm == true) &&
 3197        (strippedname = fr_pair_find_by_num(request->proxy->vps, PW_STRIPPED_USER_NAME, 0, TAG_ANY)) != NULL) {
 3198         /*
 3199          *  If there's a Stripped-User-Name attribute in
 3200          *  the request, then use THAT as the User-Name
 3201          *  for the proxied request, instead of the
 3202          *  original name.
 3203          *
 3204          *  This is done by making a copy of the
 3205          *  Stripped-User-Name attribute, turning it into
 3206          *  a User-Name attribute, deleting the
 3207          *  Stripped-User-Name and User-Name attributes
 3208          *  from the vps list, and making the new
 3209          *  User-Name the head of the vps list.
 3210          */
 3211         vp = fr_pair_find_by_num(request->proxy->vps, PW_USER_NAME, 0, TAG_ANY);
 3212         if (!vp) {
 3213             vp_cursor_t cursor;
 3214             vp = radius_pair_create(NULL, NULL,
 3215                            PW_USER_NAME, 0);
 3216             rad_assert(vp != NULL); /* handled by above function */
 3217             /* Insert at the START of the list */
 3218             /* FIXME: Can't make assumptions about ordering */
 3219             fr_cursor_init(&cursor, &vp);
 3220             fr_cursor_merge(&cursor, request->proxy->vps);
 3221             request->proxy->vps = vp;
 3222         }
 3223         fr_pair_value_strcpy(vp, strippedname->vp_strvalue);
 3224 
 3225         /*
 3226          *  Do NOT delete Stripped-User-Name.
 3227          */
 3228     }
 3229 
 3230     /*
 3231      *  If there is no PW_CHAP_CHALLENGE attribute but
 3232      *  there is a PW_CHAP_PASSWORD we need to add it
 3233      *  since we can't use the request authenticator
 3234      *  anymore - we changed it.
 3235      */
 3236     if ((request->packet->code == PW_CODE_ACCESS_REQUEST) &&
 3237         fr_pair_find_by_num(request->proxy->vps, PW_CHAP_PASSWORD, 0, TAG_ANY) &&
 3238         fr_pair_find_by_num(request->proxy->vps, PW_CHAP_CHALLENGE, 0, TAG_ANY) == NULL) {
 3239         vp = radius_pair_create(request->proxy, &request->proxy->vps, PW_CHAP_CHALLENGE, 0);
 3240         fr_pair_value_memcpy(vp, request->packet->vector, sizeof(request->packet->vector));
 3241     }
 3242 
 3243     /*
 3244      *  The RFC's say we have to do this, but FreeRADIUS
 3245      *  doesn't need it.
 3246      */
 3247     vp = radius_pair_create(request->proxy, &request->proxy->vps, PW_PROXY_STATE, 0);
 3248     fr_pair_value_sprintf(vp, "%u", request->packet->id);
 3249 
 3250     /*
 3251      *  Should be done BEFORE inserting into proxy hash, as
 3252      *  pre-proxy may use this information, or change it.
 3253      */
 3254     request->proxy->code = request->packet->code;
 3255 
 3256     /*
 3257      *  Call the pre-proxy routines.
 3258      */
 3259     vp = fr_pair_find_by_num(request->config, PW_PRE_PROXY_TYPE, 0, TAG_ANY);
 3260     if (vp) {
 3261         DICT_VALUE const *dval = dict_valbyattr(vp->da->attr, vp->da->vendor, vp->vp_integer);
 3262         /* Must be a validation issue */
 3263         rad_assert(dval);
 3264         RDEBUG2("Found Pre-Proxy-Type %s", dval->name);
 3265         pre_proxy_type = vp->vp_integer;
 3266     }
 3267 
 3268     /*
 3269      *  Run the request through the virtual server for the
 3270      *  home server, OR through the virtual server for the
 3271      *  home server pool.
 3272      */
 3273     old_server = request->server;
 3274     if (request->home_server && request->home_server->server) {
 3275         request->server = request->home_server->server;
 3276 
 3277     } else {
 3278         char buffer[128];
 3279 
 3280         RDEBUG2("Starting proxy to home server %s port %d",
 3281             inet_ntop(request->proxy->dst_ipaddr.af,
 3282                   &request->proxy->dst_ipaddr.ipaddr,
 3283                   buffer, sizeof(buffer)),
 3284             request->proxy->dst_port);
 3285 
 3286         if (request->home_pool && request->home_pool->virtual_server) {
 3287             request->server = request->home_pool->virtual_server;
 3288         }
 3289     }
 3290 
 3291     /*
 3292      *  Run the request through the given virtual server.
 3293      */
 3294     RDEBUG2("server %s {", request->server);
 3295     RINDENT();
 3296     rcode = process_pre_proxy(pre_proxy_type, request);
 3297     REXDENT();
 3298     RDEBUG2("}");
 3299     request->server = old_server;
 3300 
 3301     switch (rcode) {
 3302     case RLM_MODULE_FAIL:
 3303     case RLM_MODULE_INVALID:
 3304     case RLM_MODULE_NOTFOUND:
 3305     case RLM_MODULE_USERLOCK:
 3306     default:
 3307         /* FIXME: debug print failed stuff */
 3308         return -1;
 3309 
 3310     case RLM_MODULE_REJECT:
 3311     case RLM_MODULE_HANDLED:
 3312         return 0;
 3313 
 3314     /*
 3315      *  Only proxy the packet if the pre-proxy code succeeded.
 3316      */
 3317     case RLM_MODULE_NOOP:
 3318     case RLM_MODULE_OK:
 3319     case RLM_MODULE_UPDATED:
 3320         return 1;
 3321     }
 3322 }
 3323 
 3324 static int proxy_to_virtual_server(REQUEST *request)
 3325 {
 3326     REQUEST *fake;
 3327 
 3328     if (request->packet->dst_port == 0) {
 3329         WARN("Cannot proxy an internal request");
 3330         return 0;
 3331     }
 3332 
 3333     DEBUG("Proxying to virtual server %s",
 3334           request->home_server->server);
 3335 
 3336     /*
 3337      *  Packets to virtual servers don't get
 3338      *  retransmissions sent to them.  And the virtual
 3339      *  server is run ONLY if we have no child
 3340      *  threads, or we're running in a child thread.
 3341      */
 3342     rad_assert(!spawn_flag || !we_are_master());
 3343 
 3344     fake = request_alloc_fake(request);
 3345 
 3346     fake->packet->vps = fr_pair_list_copy(fake->packet, request->packet->vps);
 3347     talloc_free(request->proxy);
 3348 
 3349     fake->server = request->home_server->server;
 3350     fake->handle = request->handle;
 3351     fake->process = NULL; /* should never be run for anything */
 3352 
 3353     /*
 3354      *  Run the virtual server.
 3355      */
 3356     request_running(fake, FR_ACTION_RUN);
 3357 
 3358     request->proxy = talloc_steal(request, fake->packet);
 3359     fake->packet = NULL;
 3360     request->proxy_reply = talloc_steal(request, fake->reply);
 3361     fake->reply = NULL;
 3362 
 3363     talloc_free(fake);
 3364 
 3365     /*
 3366      *  No reply code, toss the reply we have,
 3367      *  and do post-proxy-type Fail.
 3368      */
 3369     if (!request->proxy_reply->code) {
 3370         TALLOC_FREE(request->proxy_reply);
 3371         setup_post_proxy_fail(request);
 3372     }
 3373 
 3374     /*
 3375      *  Do the proxy reply (if any)
 3376      */
 3377     if (process_proxy_reply(request, request->proxy_reply)) {
 3378         request->handle(request);
 3379     }
 3380 
 3381     return -1;  /* so we call request_finish */
 3382 }
 3383 
 3384 
 3385 static int request_proxy(REQUEST *request)
 3386 {
 3387     char buffer[128];
 3388 
 3389     VERIFY_REQUEST(request);
 3390 
 3391     rad_assert(request->parent == NULL);
 3392 
 3393     if (request->master_state == REQUEST_STOP_PROCESSING) return 0;
 3394 
 3395 #ifdef WITH_COA
 3396     if (request->coa) {
 3397         RWDEBUG("Cannot proxy and originate CoA packets at the same time.  Cancelling CoA request");
 3398         request_done(request->coa, FR_ACTION_CANCELLED);
 3399     }
 3400 #endif
 3401 
 3402     if (!request->home_server) {
 3403         RWDEBUG("No home server selected");
 3404         return -1;
 3405     }
 3406 
 3407     /*
 3408      *  The request may need sending to a virtual server.
 3409      *  This code is more than a little screwed up.  The rest
 3410      *  of the state machine doesn't handle parent / child
 3411      *  relationships well.  i.e. if the child request takes
 3412      *  too long, the core will mark the *parent* as "stop
 3413      *  processing".  And the child will continue without
 3414      *  knowing anything...
 3415      *
 3416      *  So, we have some horrible hacks to get around that.
 3417      */
 3418     if (request->home_server->server) return proxy_to_virtual_server(request);
 3419 
 3420     /*
 3421      *  We're actually sending a proxied packet.  Do that now.
 3422      */
 3423     if (!request->in_proxy_hash && !insert_into_proxy_hash(request)) {
 3424         RPROXY("Failed to insert request into the proxy list");
 3425         return -1;
 3426     }
 3427 
 3428     rad_assert(request->proxy->id >= 0);
 3429 
 3430     if (rad_debug_lvl) {
 3431         struct timeval *response_window;
 3432 
 3433         response_window = request_response_window(request);
 3434 
 3435 #ifdef WITH_TLS
 3436         if (request->home_server->tls) {
 3437             RDEBUG2("Proxying request to home server %s port %d (TLS) timeout %d.%06d",
 3438                 inet_ntop(request->proxy->dst_ipaddr.af,
 3439                       &request->proxy->dst_ipaddr.ipaddr,
 3440                       buffer, sizeof(buffer)),
 3441                 request->proxy->dst_port,
 3442                 (int) response_window->tv_sec, (int) response_window->tv_usec);
 3443         } else
 3444 #endif
 3445             RDEBUG2("Proxying request to home server %s port %d timeout %d.%06d",
 3446                 inet_ntop(request->proxy->dst_ipaddr.af,
 3447                       &request->proxy->dst_ipaddr.ipaddr,
 3448                       buffer, sizeof(buffer)),
 3449                 request->proxy->dst_port,
 3450                 (int) response_window->tv_sec, (int) response_window->tv_usec);
 3451 
 3452 
 3453     }
 3454 
 3455     gettimeofday(&request->proxy->timestamp, NULL);
 3456     request->home_server->last_packet_sent = request->proxy->timestamp.tv_sec;
 3457 
 3458     /*
 3459      *  Encode the packet before we do anything else.
 3460      */
 3461     request->proxy_listener->encode(request->proxy_listener, request);
 3462     debug_packet(request, request->proxy, false);
 3463 
 3464     /*
 3465      *  Set the state function, then the state, no child, and
 3466      *  send the packet.
 3467      *
 3468      *  The order here is different from other state changes
 3469      *  due to race conditions with replies from the home
 3470      *  server.
 3471      */
 3472     request->process = proxy_wait_for_reply;
 3473     request->child_state = REQUEST_PROXIED;
 3474     request->component = "<REQUEST_PROXIED>";
 3475     request->module = "";
 3476     NO_CHILD_THREAD;
 3477 
 3478     /*
 3479      *  And send the packet.
 3480      */
 3481     request->proxy_listener->send(request->proxy_listener, request);
 3482     return 1;
 3483 }
 3484 
 3485 /*
 3486  *  Proxy the packet as if it was new.
 3487  */
 3488 static int request_proxy_anew(REQUEST *request)
 3489 {
 3490     home_server_t *home;
 3491 
 3492     VERIFY_REQUEST(request);
 3493 
 3494     /*
 3495      *  Delete the request from the proxy list.
 3496      *
 3497      *  The packet list code takes care of ensuring that IDs
 3498      *  aren't reused until all 256 IDs have been used.  So
 3499      *  there's a 1/256 chance of re-using the same ID when
 3500      *  we're sending to the same home server.  Which is
 3501      *  acceptable.
 3502      */
 3503     remove_from_proxy_hash(request);
 3504 
 3505     /*
 3506      *  Find a live home server for the request.
 3507      */
 3508     home = home_server_ldb(NULL, request->home_pool, request);
 3509     if (!home) {
 3510         REDEBUG2("Failed to find live home server for request");
 3511     post_proxy_fail:
 3512         if (setup_post_proxy_fail(request)) {
 3513             request_queue_or_run(request, proxy_running);
 3514         } else {
 3515             gettimeofday(&request->reply->timestamp, NULL);
 3516             request_cleanup_delay_init(request);
 3517         }
 3518         return 0;
 3519     }
 3520 
 3521 #ifdef WITH_ACCOUNTING
 3522     /*
 3523      *  Update the Acct-Delay-Time attribute, since the LAST
 3524      *  time we tried to retransmit this packet.
 3525      */
 3526     if (request->packet->code == PW_CODE_ACCOUNTING_REQUEST) {
 3527         VALUE_PAIR *vp;
 3528 
 3529         vp = fr_pair_find_by_num(request->proxy->vps, PW_ACCT_DELAY_TIME, 0, TAG_ANY);
 3530         if (!vp) vp = radius_pair_create(request->proxy,
 3531                         &request->proxy->vps,
 3532                         PW_ACCT_DELAY_TIME, 0);
 3533         if (vp) {
 3534             struct timeval now;
 3535 
 3536             gettimeofday(&now, NULL);
 3537             vp->vp_integer += now.tv_sec - request->proxy->timestamp.tv_sec;
 3538         }
 3539     }
 3540 #endif
 3541 
 3542     /*
 3543      *  May have failed over to a "fallback" virtual server.
 3544      *  If so, run that instead of doing proxying to a real
 3545      *  server.
 3546      */
 3547     if (home->server) {
 3548         request->home_server = home;
 3549         TALLOC_FREE(request->proxy);
 3550 
 3551         (void) proxy_to_virtual_server(request);
 3552         return 0;
 3553     }
 3554 
 3555     home_server_update_request(home, request);
 3556 
 3557     if (!insert_into_proxy_hash(request)) {
 3558         RPROXY("Failed to insert retransmission into the proxy list");
 3559         goto post_proxy_fail;
 3560     }
 3561 
 3562     /*
 3563      *  Free the old packet, to force re-encoding
 3564      */
 3565     talloc_free(request->proxy->data);
 3566     request->proxy->data = NULL;
 3567     request->proxy->data_len = 0;
 3568 
 3569     if (request_proxy(request) != 1) goto post_proxy_fail;
 3570 
 3571     return 1;
 3572 }
 3573 
 3574 
 3575 /** Ping a home server.
 3576  *
 3577  */
 3578 static void request_ping(REQUEST *request, int action)
 3579 {
 3580     home_server_t *home = request->home_server;
 3581     char buffer[128];
 3582 
 3583     VERIFY_REQUEST(request);
 3584 
 3585     TRACE_STATE_MACHINE;
 3586     ASSERT_MASTER;
 3587 
 3588     switch (action) {
 3589     case FR_ACTION_TIMER:
 3590         ERROR("No response to status check %d ID %u for home server %s port %d",
 3591                request->number,
 3592                request->proxy->id,
 3593                inet_ntop(request->proxy->dst_ipaddr.af,
 3594                  &request->proxy->dst_ipaddr.ipaddr,
 3595                  buffer, sizeof(buffer)),
 3596                request->proxy->dst_port);
 3597         remove_from_proxy_hash(request);
 3598         break;
 3599 
 3600     case FR_ACTION_PROXY_REPLY:
 3601         rad_assert(request->in_proxy_hash);
 3602 
 3603         request->home_server->num_received_pings++;
 3604         RPROXY("Received response to status check %d ID %u (%d in current sequence)",
 3605                request->number, request->proxy->id, home->num_received_pings);
 3606 
 3607         /*
 3608          *  Remove the request from any hashes
 3609          */
 3610         fr_event_delete(el, &request->ev);
 3611         remove_from_proxy_hash(request);
 3612 
 3613         /*
 3614          *  The control socket may have marked the home server as
 3615          *  alive.  OR, it may have suddenly started responding to
 3616          *  requests again.  If so, don't re-do the "make alive"
 3617          *  work.
 3618          */
 3619         if (home->state == HOME_STATE_ALIVE) break;
 3620 
 3621         /*
 3622          *  It's dead, and we haven't received enough ping
 3623          *  responses to mark it "alive".  Wait a bit.
 3624          *
 3625          *  If it's zombie, we mark it alive immediately.
 3626          */
 3627         if ((home->state >= HOME_STATE_IS_DEAD) &&
 3628             (home->num_received_pings < home->num_pings_to_alive)) {
 3629             return;
 3630         }
 3631 
 3632         /*
 3633          *  Mark it alive and delete any outstanding
 3634          *  pings.
 3635          */
 3636         mark_home_server_alive(request, home);
 3637         break;
 3638 
 3639     default:
 3640         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 3641         break;
 3642     }
 3643 
 3644     rad_assert(!request->in_request_hash);
 3645     rad_assert(!request->in_proxy_hash);
 3646     rad_assert(request->ev == NULL);
 3647     NO_CHILD_THREAD;
 3648     request_done(request, FR_ACTION_DONE);
 3649 }
 3650 
 3651 /*
 3652  *  Add +/- 2s of jitter, as suggested in RFC 3539
 3653  *  and in RFC 5080.
 3654  */
 3655 static void add_jitter(struct timeval *when)
 3656 {
 3657     uint32_t jitter;
 3658 
 3659     when->tv_sec -= 2;
 3660 
 3661     jitter = fr_rand();
 3662     jitter ^= (jitter >> 10);
 3663     jitter &= ((1 << 22) - 1); /* 22 bits of 1 */
 3664 
 3665     /*
 3666      *  Add in ~ (4 * USEC) of jitter.
 3667      */
 3668     tv_add(when, jitter);
 3669 }
 3670 
 3671 /*
 3672  *  Called from start of zombie period, OR after control socket
 3673  *  marks the home server dead.
 3674  */
 3675 static void ping_home_server(void *ctx)
 3676 {
 3677     home_server_t *home = talloc_get_type_abort(ctx, home_server_t);
 3678     REQUEST *request;
 3679     VALUE_PAIR *vp;
 3680     struct timeval when, now;
 3681 
 3682     if ((home->state == HOME_STATE_ALIVE) ||
 3683         (home->ev != NULL)) {
 3684         return;
 3685     }
 3686 
 3687     gettimeofday(&now, NULL);
 3688     ASSERT_MASTER;
 3689 
 3690     /*
 3691      *  We've run out of zombie time.  Mark it dead.
 3692      */
 3693     if (home->state == HOME_STATE_ZOMBIE) {
 3694         when = home->zombie_period_start;
 3695         when.tv_sec += home->zombie_period;
 3696 
 3697         if (timercmp(&when, &now, <)) {
 3698             DEBUG("PING: Zombie period is over for home server %s", home->log_name);
 3699             mark_home_server_dead(home, &now, false);
 3700         }
 3701     }
 3702 
 3703     /*
 3704      *  We're not supposed to be pinging it.  Just wake up
 3705      *  when we're supposed to mark it dead.
 3706      */
 3707     if (home->ping_check == HOME_PING_CHECK_NONE) {
 3708         if (home->state == HOME_STATE_ZOMBIE) {
 3709             home->when = home->zombie_period_start;
 3710             home->when.tv_sec += home->zombie_period;
 3711             INSERT_EVENT(ping_home_server, home);
 3712         }
 3713 
 3714         /*
 3715          *  Else mark_home_server_dead will set a timer
 3716          *  for revive_interval.
 3717          */
 3718         return;
 3719     }
 3720 
 3721 
 3722     request = request_alloc(NULL);
 3723     if (!request) return;
 3724     request->number = request_num_counter++;
 3725     NO_CHILD_THREAD;
 3726 
 3727     request->proxy = rad_alloc(request, true);
 3728     request->root = &main_config;
 3729     rad_assert(request->proxy != NULL);
 3730 
 3731     if (home->ping_check == HOME_PING_CHECK_STATUS_SERVER) {
 3732         request->proxy->code = PW_CODE_STATUS_SERVER;
 3733 
 3734         fr_pair_make(request->proxy, &request->proxy->vps,
 3735              "Message-Authenticator", "0x00", T_OP_SET);
 3736 
 3737     } else if ((home->type == HOME_TYPE_AUTH) ||
 3738            (home->type == HOME_TYPE_AUTH_ACCT)) {
 3739         request->proxy->code = PW_CODE_ACCESS_REQUEST;
 3740 
 3741         fr_pair_make(request->proxy, &request->proxy->vps,
 3742              "User-Name", home->ping_user_name, T_OP_SET);
 3743         fr_pair_make(request->proxy, &request->proxy->vps,
 3744              "User-Password", home->ping_user_password, T_OP_SET);
 3745         fr_pair_make(request->proxy, &request->proxy->vps,
 3746              "Service-Type", "Authenticate-Only", T_OP_SET);
 3747         fr_pair_make(request->proxy, &request->proxy->vps,
 3748              "Message-Authenticator", "0x00", T_OP_SET);
 3749 
 3750 #ifdef WITH_ACCOUNTING
 3751     } else if (home->type == HOME_TYPE_ACCT) {
 3752         request->proxy->code = PW_CODE_ACCOUNTING_REQUEST;
 3753 
 3754         fr_pair_make(request->proxy, &request->proxy->vps,
 3755              "User-Name", home->ping_user_name, T_OP_SET);
 3756         fr_pair_make(request->proxy, &request->proxy->vps,
 3757              "Acct-Status-Type", "Stop", T_OP_SET);
 3758         fr_pair_make(request->proxy, &request->proxy->vps,
 3759              "Acct-Session-Id", "00000000", T_OP_SET);
 3760         vp = fr_pair_make(request->proxy, &request->proxy->vps,
 3761                   "Event-Timestamp", "0", T_OP_SET);
 3762         vp->vp_date = now.tv_sec;
 3763 #endif
 3764 
 3765     } else {
 3766         /*
 3767          *  Unkown home server type.
 3768          */
 3769         talloc_free(request);
 3770         return;
 3771     }
 3772 
 3773     vp = fr_pair_make(request->proxy, &request->proxy->vps,
 3774               "NAS-Identifier", "", T_OP_SET);
 3775     if (vp) {
 3776         fr_pair_value_sprintf(vp, "Status Check %u. Are you alive?",
 3777                 home->num_sent_pings);
 3778     }
 3779 
 3780 #ifdef WITH_TCP
 3781     request->proxy->proto = home->proto;
 3782 #endif
 3783     request->proxy->src_ipaddr = home->src_ipaddr;
 3784     request->proxy->dst_ipaddr = home->ipaddr;
 3785     request->proxy->dst_port = home->port;
 3786     request->home_server = home;
 3787 #ifdef DEBUG_STATE_MACHINE
 3788     if (rad_debug_lvl) printf("(%u) ********\tSTATE %s C-%s -> C-%s\t********\n", request->number, __FUNCTION__,
 3789                    child_state_names[request->child_state],
 3790                    child_state_names[REQUEST_DONE]);
 3791     if (rad_debug_lvl) printf("(%u) ********\tNEXT-STATE %s -> %s\n", request->number, __FUNCTION__, "request_ping");
 3792 #endif
 3793 #ifdef HAVE_PTHREAD_H
 3794     rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
 3795 #endif
 3796     request->child_state = REQUEST_PROXIED;
 3797     request->process = request_ping;
 3798 
 3799     rad_assert(request->proxy_listener == NULL);
 3800 
 3801     if (!insert_into_proxy_hash(request)) {
 3802         RPROXY("Failed to insert status check %d into proxy list.  Discarding it.",
 3803                request->number);
 3804 
 3805         rad_assert(!request->in_request_hash);
 3806         rad_assert(!request->in_proxy_hash);
 3807         rad_assert(request->ev == NULL);
 3808         talloc_free(request);
 3809         return;
 3810     }
 3811 
 3812     /*
 3813      *  Set up the timer callback.
 3814      */
 3815     when = now;
 3816     when.tv_sec += home->ping_timeout;
 3817 
 3818     DEBUG("PING: Waiting %u seconds for response to ping",
 3819           home->ping_timeout);
 3820 
 3821     STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 3822     home->num_sent_pings++;
 3823 
 3824     rad_assert(request->proxy_listener != NULL);
 3825     debug_packet(request, request->proxy, false);
 3826     request->proxy_listener->send(request->proxy_listener,
 3827                       request);
 3828 
 3829     /*
 3830      *  Add +/- 2s of jitter, as suggested in RFC 3539
 3831      *  and in the Issues and Fixes draft.
 3832      */
 3833     home->when = now;
 3834     home->when.tv_sec += home->ping_interval;
 3835 
 3836     add_jitter(&home->when);
 3837 
 3838     DEBUG("PING: Next status packet in %u seconds", home->ping_interval);
 3839     INSERT_EVENT(ping_home_server, home);
 3840 }
 3841 
 3842 static void home_trigger(home_server_t *home, char const *trigger)
 3843 {
 3844     REQUEST *my_request;
 3845     RADIUS_PACKET *my_packet;
 3846 
 3847     my_request = talloc_zero(NULL, REQUEST);
 3848     my_packet = talloc_zero(my_request, RADIUS_PACKET);
 3849     my_request->proxy = my_packet;
 3850     my_packet->dst_ipaddr = home->ipaddr;
 3851     my_packet->src_ipaddr = home->src_ipaddr;
 3852 
 3853     exec_trigger(my_request, home->cs, trigger, false);
 3854     talloc_free(my_request);
 3855 }
 3856 
 3857 static void mark_home_server_zombie(home_server_t *home, struct timeval *now, struct timeval *response_window)
 3858 {
 3859     time_t start;
 3860     char buffer[128];
 3861 
 3862     ASSERT_MASTER;
 3863 
 3864     rad_assert((home->state == HOME_STATE_ALIVE) ||
 3865            (home->state == HOME_STATE_UNKNOWN));
 3866 
 3867     /*
 3868      *  We've received a real packet recently.  Don't mark the
 3869      *  server as zombie until we've received NO packets for a
 3870      *  while.  The "1/4" of zombie period was chosen rather
 3871      *  arbitrarily.  It's a balance between too short, which
 3872      *  gives quick fail-over and fail-back, or too long,
 3873      *  where the proxy still sends packets to an unresponsive
 3874      *  home server.
 3875      */
 3876     start = now->tv_sec - ((home->zombie_period + 3) / 4);
 3877     if (home->last_packet_recv >= start) {
 3878         DEBUG("Received reply from home server %d seconds ago.  Might not be zombie.",
 3879               (int) (now->tv_sec - home->last_packet_recv));
 3880         return;
 3881     }
 3882 
 3883     home->state = HOME_STATE_ZOMBIE;
 3884     home_trigger(home, "home_server.zombie");
 3885 
 3886     /*
 3887      *  Set the home server to "zombie", as of the time
 3888      *  calculated above.
 3889      */
 3890     home->zombie_period_start.tv_sec = start;
 3891     home->zombie_period_start.tv_usec = USEC / 2;
 3892 
 3893     fr_event_delete(el, &home->ev);
 3894 
 3895     home->num_sent_pings = 0;
 3896     home->num_received_pings = 0;
 3897 
 3898     PROXY( "Marking home server %s port %d as zombie (it has not responded in %d.%06d seconds).",
 3899            inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
 3900              buffer, sizeof(buffer)),
 3901            home->port, (int) response_window->tv_sec, (int) response_window->tv_usec);
 3902 
 3903     ping_home_server(home);
 3904 }
 3905 
 3906 
 3907 void revive_home_server(void *ctx)
 3908 {
 3909     home_server_t *home = talloc_get_type_abort(ctx, home_server_t);
 3910     char buffer[128];
 3911 
 3912     home->state = HOME_STATE_ALIVE;
 3913     home->response_timeouts = 0;
 3914     home_trigger(home, "home_server.alive");
 3915     home->currently_outstanding = 0;
 3916     gettimeofday(&home->revive_time, NULL);
 3917 
 3918     /*
 3919      *  Delete any outstanding events.
 3920      */
 3921     ASSERT_MASTER;
 3922     if (home->ev) fr_event_delete(el, &home->ev);
 3923 
 3924     PROXY( "Marking home server %s port %d alive again... we have no idea if it really is alive or not.",
 3925            inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
 3926              buffer, sizeof(buffer)),
 3927            home->port);
 3928 }
 3929 
 3930 void mark_home_server_dead(home_server_t *home, struct timeval *when, bool down)
 3931 {
 3932     int previous_state = home->state;
 3933     char buffer[128];
 3934 
 3935     PROXY( "Marking home server %s port %d as dead.",
 3936            inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
 3937              buffer, sizeof(buffer)),
 3938            home->port);
 3939 
 3940     home->state = HOME_STATE_IS_DEAD;
 3941     home_trigger(home, "home_server.dead");
 3942 
 3943     /*
 3944      *  Administratively down - don't do anything to bring it
 3945      *  up.
 3946      */
 3947     if (down) {
 3948         home->state = HOME_STATE_ADMIN_DOWN;
 3949         return;
 3950     }
 3951 
 3952     /*
 3953      *  Ping it if configured, AND we can ping it.
 3954      */
 3955     if ((home->ping_check != HOME_PING_CHECK_NONE) &&
 3956         (previous_state != HOME_STATE_CONNECTION_FAIL)) {
 3957         /*
 3958          *  If the control socket marks us dead, start
 3959          *  pinging.  Otherwise, we already started
 3960          *  pinging when it was marked "zombie".
 3961          */
 3962         if (previous_state == HOME_STATE_ALIVE) {
 3963             ping_home_server(home);
 3964         } else {
 3965             DEBUG("PING: Already pinging home server %s", home->log_name);
 3966         }
 3967 
 3968     } else {
 3969         /*
 3970          *  Revive it after a fixed period of time.  This
 3971          *  is very, very, bad.
 3972          */
 3973         home->when = *when;
 3974         home->when.tv_sec += home->revive_interval;
 3975 
 3976         DEBUG("PING: Reviving home server %s in %u seconds", home->log_name, home->revive_interval);
 3977         ASSERT_MASTER;
 3978         INSERT_EVENT(revive_home_server, home);
 3979     }
 3980 }
 3981 
 3982 /** Wait for a reply after proxying a request.
 3983  *
 3984  *  Retransmit the proxied packet, or time out and go to
 3985  *  proxy_no_reply.  Mark the home server unresponsive, etc.
 3986  *
 3987  *  If we do receive a reply, we transition to proxy_running.
 3988  *
 3989  *  \dot
 3990  *  digraph proxy_wait_for_reply {
 3991  *      proxy_wait_for_reply;
 3992  *
 3993  *      proxy_wait_for_reply -> retransmit_proxied_request [ label = "DUP", arrowhead = "none" ];
 3994  *      proxy_wait_for_reply -> proxy_no_reply [ label = "TIMER >= response_window" ];
 3995  *      proxy_wait_for_reply -> timer [ label = "TIMER < max_request_time" ];
 3996  *      proxy_wait_for_reply -> proxy_running [ label = "PROXY_REPLY" arrowhead = "none"];
 3997  *      proxy_wait_for_reply -> done [ label = "TIMER >= max_request_time" ];
 3998  *  }
 3999  *  \enddot
 4000  */
 4001 static void proxy_wait_for_reply(REQUEST *request, int action)
 4002 {
 4003     struct timeval now, when;
 4004     struct timeval *response_window = NULL;
 4005     home_server_t *home = request->home_server;
 4006     char buffer[128];
 4007 
 4008     VERIFY_REQUEST(request);
 4009 
 4010     TRACE_STATE_MACHINE;
 4011     CHECK_FOR_STOP;
 4012 
 4013     rad_assert(request->packet->code != PW_CODE_STATUS_SERVER);
 4014     rad_assert(request->home_server != NULL);
 4015 
 4016     gettimeofday(&now, NULL);
 4017 
 4018     switch (action) {
 4019     case FR_ACTION_DUP:
 4020         /*
 4021          *  The request was proxied to a virtual server.
 4022          *  Ignore the retransmit.
 4023          */
 4024         if (request->home_server->server) return;
 4025 
 4026         /*
 4027          *  Failed connections get the home server marked
 4028          *  as dead.
 4029          */
 4030         if (home->state == HOME_STATE_CONNECTION_FAIL) {
 4031             mark_home_server_dead(home, &now, false);
 4032         }
 4033 
 4034         /*
 4035          *  We have a reply, ignore the retransmit.
 4036          */
 4037         if (request->proxy_reply) return;
 4038 
 4039         /*
 4040          *  Use a new connection when the home server is
 4041          *  dead, or when there's no proxy listener, or
 4042          *  when the listener is failed or dead.
 4043          *
 4044          *  If the listener is known or frozen, use it for
 4045          *  retransmits.
 4046          */
 4047         if ((home->state >= HOME_STATE_IS_DEAD) ||
 4048             !request->proxy_listener ||
 4049             (request->proxy_listener->status >= RAD_LISTEN_STATUS_EOL)) {
 4050             request_proxy_anew(request);
 4051             return;
 4052         }
 4053 
 4054 #ifdef WITH_TCP
 4055         /*
 4056          *  The home server is still alive, but TCP.  We
 4057          *  rely on TCP to get the request and reply back.
 4058          *  So there's no need to retransmit.
 4059          */
 4060         if (home->proto == IPPROTO_TCP) {
 4061             DEBUG2("Suppressing duplicate proxied request (tcp) to home server %s port %d proto TCP - ID: %d",
 4062                    inet_ntop(request->proxy->dst_ipaddr.af,
 4063                      &request->proxy->dst_ipaddr.ipaddr,
 4064                      buffer, sizeof(buffer)),
 4065                    request->proxy->dst_port,
 4066                    request->proxy->id);
 4067             return;
 4068         }
 4069 #endif
 4070 
 4071         /*
 4072          *  More than one retransmit a second is stupid,
 4073          *  and should be suppressed by the proxy.
 4074          */
 4075         when = request->proxy->timestamp;
 4076         when.tv_sec++;
 4077 
 4078         if (timercmp(&now, &when, <)) {
 4079             DEBUG2("Suppressing duplicate proxied request (too fast) to home server %s port %d proto TCP - ID: %d",
 4080                    inet_ntop(request->proxy->dst_ipaddr.af,
 4081                      &request->proxy->dst_ipaddr.ipaddr,
 4082                      buffer, sizeof(buffer)),
 4083                    request->proxy->dst_port,
 4084                    request->proxy->id);
 4085             return;
 4086         }
 4087 
 4088 #ifdef WITH_ACCOUNTING
 4089         /*
 4090          *  If we update the Acct-Delay-Time, we need to
 4091          *  get a new ID.
 4092          */
 4093         if ((request->packet->code == PW_CODE_ACCOUNTING_REQUEST) &&
 4094             fr_pair_find_by_num(request->proxy->vps, PW_ACCT_DELAY_TIME, 0, TAG_ANY)) {
 4095             request_proxy_anew(request);
 4096             return;
 4097         }
 4098 #endif
 4099 
 4100         RDEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
 4101             inet_ntop(request->proxy->dst_ipaddr.af,
 4102                   &request->proxy->dst_ipaddr.ipaddr,
 4103                   buffer, sizeof(buffer)),
 4104             request->proxy->dst_port,
 4105             request->proxy->id);
 4106         request->num_proxied_requests++;
 4107 
 4108         rad_assert(request->proxy_listener != NULL);
 4109         FR_STATS_TYPE_INC(home->stats.total_requests);
 4110         home->last_packet_sent = now.tv_sec;
 4111         request->proxy->timestamp = now;
 4112         debug_packet(request, request->proxy, false);
 4113         request->proxy_listener->send(request->proxy_listener, request);
 4114         break;
 4115 
 4116     case FR_ACTION_TIMER:
 4117         /*
 4118          *  Failed connections get the home server marked
 4119          *  as dead.
 4120          */
 4121         if (home->state == HOME_STATE_CONNECTION_FAIL) {
 4122             mark_home_server_dead(home, &now, false);
 4123         }
 4124 
 4125         response_window = request_response_window(request);
 4126 
 4127 #ifdef WITH_TCP
 4128         if (!request->proxy_listener ||
 4129             (request->proxy_listener->status >= RAD_LISTEN_STATUS_EOL)) {
 4130             remove_from_proxy_hash(request);
 4131 
 4132             when = request->packet->timestamp;
 4133             when.tv_sec += request->root->max_request_time;
 4134 
 4135             if (timercmp(&when, &now, >)) {
 4136                 RDEBUG("Waiting for client retransmission in order to do a proxy retransmit");
 4137                 STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 4138                 return;
 4139             }
 4140         } else
 4141 #endif
 4142         {
 4143             /*
 4144              *  Wake up "response_window" time in the future.
 4145              *  i.e. when MY packet hasn't received a response.
 4146              *
 4147              *  Note that we DO NOT mark the home server as
 4148              *  zombie if it doesn't respond to us.  It may be
 4149              *  responding to other (better looking) packets.
 4150              */
 4151             when = request->proxy->timestamp;
 4152             timeradd(&when, response_window, &when);
 4153 
 4154             /*
 4155              *  Not at the response window.  Set the timer for
 4156              *  that.
 4157              */
 4158             if (timercmp(&when, &now, >)) {
 4159                 struct timeval diff;
 4160                 timersub(&when, &now, &diff);
 4161 
 4162                 RDEBUG("Expecting proxy response no later than %d.%06d seconds from now",
 4163                        (int) diff.tv_sec, (int) diff.tv_usec);
 4164                 STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 4165                 return;
 4166             }
 4167         }
 4168 
 4169         RDEBUG("No proxy response, giving up on request and marking it done");
 4170 
 4171         /*
 4172          *  If we haven't received any packets for
 4173          *  "response_window", then mark the home server
 4174          *  as zombie.
 4175          *
 4176          *  This check should really be part of a home
 4177          *  server state machine.
 4178          */
 4179         if ((home->state == HOME_STATE_ALIVE) ||
 4180              (home->state == HOME_STATE_UNKNOWN)) {
 4181             home->response_timeouts++;
 4182             if (home->response_timeouts >= home->max_response_timeouts)
 4183                 mark_home_server_zombie(home, &now, response_window);
 4184         }
 4185 
 4186         FR_STATS_TYPE_INC(home->stats.total_timeouts);
 4187         if (home->type == HOME_TYPE_AUTH) {
 4188             if (request->proxy_listener) FR_STATS_TYPE_INC(request->proxy_listener->stats.total_timeouts);
 4189             FR_STATS_TYPE_INC(proxy_auth_stats.total_timeouts);
 4190         }
 4191 #ifdef WITH_ACCT
 4192         else if (home->type == HOME_TYPE_ACCT) {
 4193             if (request->proxy_listener) FR_STATS_TYPE_INC(request->proxy_listener->stats.total_timeouts);
 4194             FR_STATS_TYPE_INC(proxy_acct_stats.total_timeouts);
 4195         }
 4196 #endif
 4197 #ifdef WITH_COA
 4198         else if (home->type == HOME_TYPE_COA) {
 4199             if (request->proxy_listener) FR_STATS_TYPE_INC(request->proxy_listener->stats.total_timeouts);
 4200 
 4201             if (request->packet->code == PW_CODE_COA_REQUEST) {
 4202                 FR_STATS_TYPE_INC(proxy_coa_stats.total_timeouts);
 4203             } else {
 4204                 FR_STATS_TYPE_INC(proxy_dsc_stats.total_timeouts);
 4205             }
 4206         }
 4207 #endif
 4208 
 4209         /*
 4210          *  There was no response within the window.  Stop
 4211          *  the request.  If the client retransmitted, it
 4212          *  may have failed over to another home server.
 4213          *  But that one may be dead, too.
 4214          *
 4215          *  The extra verbose message if we have a username,
 4216          *  is extremely useful if the proxy is part of a chain
 4217          *  and the final home server, is not the one we're
 4218          *  proxying to.
 4219          */
 4220         if (request->username) {
 4221             RERROR("Failing proxied request for user \"%s\", due to lack of any response from home "
 4222                    "server %s port %d",
 4223                    request->username->vp_strvalue,
 4224                    inet_ntop(request->proxy->dst_ipaddr.af,
 4225                      &request->proxy->dst_ipaddr.ipaddr,
 4226                      buffer, sizeof(buffer)),
 4227                    request->proxy->dst_port);
 4228         } else {
 4229             RERROR("Failing proxied request, due to lack of any response from home server %s port %d",
 4230                    inet_ntop(request->proxy->dst_ipaddr.af,
 4231                      &request->proxy->dst_ipaddr.ipaddr,
 4232                      buffer, sizeof(buffer)),
 4233                    request->proxy->dst_port);
 4234         }
 4235 
 4236         if (setup_post_proxy_fail(request)) {
 4237             request_queue_or_run(request, proxy_no_reply);
 4238         } else {
 4239             gettimeofday(&request->reply->timestamp, NULL);
 4240             request_cleanup_delay_init(request);
 4241         }
 4242         break;
 4243 
 4244         /*
 4245          *  We received a new reply.  Go process it.
 4246          */
 4247     case FR_ACTION_PROXY_REPLY:
 4248         request_queue_or_run(request, proxy_running);
 4249         break;
 4250 
 4251     default:
 4252         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 4253         break;
 4254     }
 4255 }
 4256 #endif  /* WITH_PROXY */
 4257 
 4258 
 4259 /***********************************************************************
 4260  *
 4261  *  CoA code
 4262  *
 4263  ***********************************************************************/
 4264 #ifdef WITH_COA
 4265 /*
 4266  *  See if we need to originate a CoA request.
 4267  */
 4268 static void request_coa_originate(REQUEST *request)
 4269 {
 4270     int rcode, pre_proxy_type = 0;
 4271     VALUE_PAIR *vp;
 4272     REQUEST *coa;
 4273     fr_ipaddr_t ipaddr;
 4274     char const *old_server;
 4275     char buffer[256];
 4276 
 4277     VERIFY_REQUEST(request);
 4278 
 4279     rad_assert(request->coa != NULL);
 4280     rad_assert(request->proxy == NULL);
 4281     rad_assert(!request->in_proxy_hash);
 4282     rad_assert(request->proxy_reply == NULL);
 4283 
 4284     /*
 4285      *  Check whether we want to originate one, or cancel one.
 4286      */
 4287     vp = fr_pair_find_by_num(request->config, PW_SEND_COA_REQUEST, 0, TAG_ANY);
 4288     if (!vp) {
 4289         vp = fr_pair_find_by_num(request->coa->proxy->vps, PW_SEND_COA_REQUEST, 0, TAG_ANY);
 4290     }
 4291 
 4292     if (vp) {
 4293         if (vp->vp_integer == 0) {
 4294         fail:
 4295             TALLOC_FREE(request->coa);
 4296             return;
 4297         }
 4298     }
 4299 
 4300     if (!main_config.proxy_requests) {
 4301         RWDEBUG("Cannot originate CoA packets unless 'proxy_requests = yes'");
 4302             TALLOC_FREE(request->coa);
 4303         return;
 4304     }
 4305 
 4306     coa = request->coa;
 4307     coa->listener = NULL;   /* copied here by request_alloc_fake(), but not needed */
 4308 
 4309     /*
 4310      *  src_ipaddr will be set up in proxy_encode.
 4311      */
 4312     memset(&ipaddr, 0, sizeof(ipaddr));
 4313     vp = fr_pair_find_by_num(coa->proxy->vps, PW_PACKET_DST_IP_ADDRESS, 0, TAG_ANY);
 4314     if (vp) {
 4315         ipaddr.af = AF_INET;
 4316         ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
 4317         ipaddr.prefix = 32;
 4318     } else if ((vp = fr_pair_find_by_num(coa->proxy->vps, PW_PACKET_DST_IPV6_ADDRESS, 0, TAG_ANY)) != NULL) {
 4319         ipaddr.af = AF_INET6;
 4320         ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
 4321         ipaddr.prefix = 128;
 4322     } else if ((vp = fr_pair_find_by_num(coa->proxy->vps, PW_HOME_SERVER_POOL, 0, TAG_ANY)) != NULL) {
 4323         coa->home_pool = home_pool_byname(vp->vp_strvalue,
 4324                           HOME_TYPE_COA);
 4325         if (!coa->home_pool) {
 4326             RWDEBUG2("No such home_server_pool %s",
 4327                    vp->vp_strvalue);
 4328             goto fail;
 4329         }
 4330 
 4331         /*
 4332          *  Prefer the pool to one server
 4333          */
 4334     } else if (request->client->coa_pool) {
 4335         coa->home_pool = request->client->coa_pool;
 4336 
 4337     } else if (request->client->coa_server) {
 4338         coa->home_server = request->client->coa_server;
 4339 
 4340     } else {
 4341         /*
 4342          *  If all else fails, send it to the client that
 4343          *  originated this request.
 4344          */
 4345         memcpy(&ipaddr, &request->packet->src_ipaddr, sizeof(ipaddr));
 4346     }
 4347 
 4348     /*
 4349      *  Use the pool, if it exists.
 4350      */
 4351     if (coa->home_pool) {
 4352         coa->home_server = home_server_ldb(NULL, coa->home_pool, coa);
 4353         if (!coa->home_server) {
 4354             RWDEBUG("No live home server for home_server_pool %s", coa->home_pool->name);
 4355             goto fail;
 4356         }
 4357         home_server_update_request(coa->home_server, coa);
 4358 
 4359     } else if (!coa->home_server) {
 4360         uint16_t port = PW_COA_UDP_PORT;
 4361 
 4362         vp = fr_pair_find_by_num(coa->proxy->vps, PW_PACKET_DST_PORT, 0, TAG_ANY);
 4363         if (vp) port = vp->vp_integer;
 4364 
 4365         coa->home_server = home_server_find(&ipaddr, port, IPPROTO_UDP);
 4366         if (!coa->home_server) {
 4367             RWDEBUG2("Unknown destination %s:%d for CoA request.",
 4368                    inet_ntop(ipaddr.af, &ipaddr.ipaddr,
 4369                      buffer, sizeof(buffer)), port);
 4370             goto fail;
 4371         }
 4372     }
 4373 
 4374     vp = fr_pair_find_by_num(coa->proxy->vps, PW_PACKET_TYPE, 0, TAG_ANY);
 4375     if (vp) {
 4376         switch (vp->vp_integer) {
 4377         case PW_CODE_COA_REQUEST:
 4378         case PW_CODE_DISCONNECT_REQUEST:
 4379             coa->proxy->code = vp->vp_integer;
 4380             break;
 4381 
 4382         default:
 4383             DEBUG("Cannot set CoA Packet-Type to code %d",
 4384                   vp->vp_integer);
 4385             goto fail;
 4386         }
 4387     }
 4388 
 4389     if (!coa->proxy->code) coa->proxy->code = PW_CODE_COA_REQUEST;
 4390 
 4391     /*
 4392      *  The rest of the server code assumes that
 4393      *  request->packet && request->reply exist.  Copy them
 4394      *  from the original request.
 4395      */
 4396     rad_assert(coa->packet != NULL);
 4397     rad_assert(coa->packet->vps == NULL);
 4398 
 4399     coa->packet = rad_copy_packet(coa, request->packet);
 4400     coa->reply = rad_copy_packet(coa, request->reply);
 4401 
 4402     coa->config = fr_pair_list_copy(coa, request->config);
 4403     coa->num_coa_requests = 0;
 4404     coa->number = request->number; /* it's associated with the same request */
 4405 
 4406     /*
 4407      *  Call the pre-proxy routines.
 4408      */
 4409     vp = fr_pair_find_by_num(request->config, PW_PRE_PROXY_TYPE, 0, TAG_ANY);
 4410     if (vp) {
 4411         DICT_VALUE const *dval = dict_valbyattr(vp->da->attr, vp->da->vendor, vp->vp_integer);
 4412         /* Must be a validation issue */
 4413         rad_assert(dval);
 4414         RDEBUG2("Found Pre-Proxy-Type %s", dval->name);
 4415         pre_proxy_type = vp->vp_integer;
 4416     }
 4417 
 4418     /*
 4419      *  Run the request through the virtual server for the
 4420      *  home server, OR through the virtual server for the
 4421      *  home server pool.
 4422      */
 4423     old_server = request->server;
 4424     if (coa->home_server && coa->home_server->server) {
 4425         coa->server = coa->home_server->server;
 4426 
 4427     } else if (coa->home_pool && coa->home_pool->virtual_server) {
 4428         coa->server = coa->home_pool->virtual_server;
 4429     }
 4430 
 4431     RDEBUG2("server %s {", coa->server);
 4432     RINDENT();
 4433     rcode = process_pre_proxy(pre_proxy_type, coa);
 4434     REXDENT();
 4435     RDEBUG2("}");
 4436     coa->server = old_server;
 4437 
 4438     switch (rcode) {
 4439     default:
 4440         goto fail;
 4441 
 4442     /*
 4443      *  Only send the CoA packet if the pre-proxy code succeeded.
 4444      */
 4445     case RLM_MODULE_NOOP:
 4446     case RLM_MODULE_OK:
 4447     case RLM_MODULE_UPDATED:
 4448         break;
 4449     }
 4450 
 4451     /*
 4452      *  Source IP / port is set when the proxy socket
 4453      *  is chosen.
 4454      */
 4455     coa->proxy->dst_ipaddr = coa->home_server->ipaddr;
 4456     coa->proxy->dst_port = coa->home_server->port;
 4457 
 4458     if (!insert_into_proxy_hash(coa)) {
 4459         radlog_request(L_PROXY, 0, coa, "Failed to insert CoA request into proxy list");
 4460         goto fail;
 4461     }
 4462 
 4463     /*
 4464      *  We CANNOT divorce the CoA request from the parent
 4465      *  request.  This function is running in a child thread,
 4466      *  and we need access to the main event loop in order to
 4467      *  to add the timers for the CoA packet.
 4468      *
 4469      *  Instead, we wait for the timer on the parent request
 4470      *  to fire.
 4471      */
 4472     gettimeofday(&coa->proxy->timestamp, NULL);
 4473     coa->packet->timestamp = coa->proxy->timestamp; /* for max_request_time */
 4474     coa->home_server->last_packet_sent = coa->proxy->timestamp.tv_sec;
 4475     coa->delay = 0;     /* need to calculate a new delay */
 4476 
 4477     /*
 4478      *  If requested, put a State attribute into the packet,
 4479      *  and cache the VPS.
 4480      */
 4481     fr_state_put_vps(coa, NULL, coa->packet);
 4482 
 4483     /*
 4484      *  Encode the packet before we do anything else.
 4485      */
 4486     coa->proxy_listener->encode(coa->proxy_listener, coa);
 4487     debug_packet(coa, coa->proxy, false);
 4488 
 4489 #ifdef DEBUG_STATE_MACHINE
 4490     if (rad_debug_lvl) printf("(%u) ********\tSTATE %s C-%s -> C-%s\t********\n", request->number, __FUNCTION__,
 4491                    child_state_names[request->child_state],
 4492                    child_state_names[REQUEST_PROXIED]);
 4493 #endif
 4494 
 4495     /*
 4496      *  Set the state function, then the state, no child, and
 4497      *  send the packet.
 4498      */
 4499     coa->process = coa_wait_for_reply;
 4500     coa->child_state = REQUEST_PROXIED;
 4501 
 4502 #ifdef HAVE_PTHREAD_H
 4503     coa->child_pid = NO_SUCH_CHILD_PID;
 4504 #endif
 4505 
 4506     if (we_are_master()) coa_separate(request->coa, true);
 4507 
 4508     /*
 4509      *  And send the packet.
 4510      */
 4511     coa->proxy_listener->send(coa->proxy_listener, coa);
 4512 }
 4513 
 4514 
 4515 static void coa_retransmit(REQUEST *request)
 4516 {
 4517     uint32_t delay, frac;
 4518     struct timeval now, when, mrd;
 4519     char buffer[128];
 4520 
 4521     VERIFY_REQUEST(request);
 4522 
 4523     /*
 4524      *  Don't do fail-over.  This is a 3.1 feature.
 4525      */
 4526     if (!request->home_server ||
 4527         (request->home_server->state >= HOME_STATE_IS_DEAD) ||
 4528         request->proxy_reply ||
 4529         !request->proxy_listener ||
 4530         (request->proxy_listener->status >= RAD_LISTEN_STATUS_EOL)) {
 4531         request_done(request, FR_ACTION_CANCELLED);
 4532         return;
 4533     }
 4534 
 4535     fr_event_now(el, &now);
 4536 
 4537     /*
 4538      *  Home server has gone away.  The request is done.
 4539      */
 4540     if (!request->home_server) {
 4541         RDEBUG("No home server for CoA packet.  Failing it.");
 4542         goto fail;
 4543     }
 4544 
 4545     if (request->delay == 0) {
 4546         /*
 4547          *  Implement re-transmit algorithm as per RFC 5080
 4548          *  Section 2.2.1.
 4549          *
 4550          *  We want IRT + RAND*IRT
 4551          *  or 0.9 IRT + rand(0,.2) IRT
 4552          *
 4553          *  2^20 ~ USEC, and we want 2.
 4554          *  rand(0,0.2) USEC ~ (rand(0,2^21) / 10)
 4555          */
 4556         delay = (fr_rand() & ((1 << 22) - 1)) / 10;
 4557         request->delay = delay * request->home_server->coa_irt;
 4558         delay = request->home_server->coa_irt * USEC;
 4559         delay -= delay / 10;
 4560         delay += request->delay;
 4561         request->delay = delay;
 4562 
 4563         when = request->proxy->timestamp;
 4564         tv_add(&when, delay);
 4565 
 4566         if (timercmp(&when, &now, >)) {
 4567             STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 4568             return;
 4569         }
 4570     }
 4571 
 4572     /*
 4573      *  Retransmit CoA request.
 4574      */
 4575 
 4576     /*
 4577      *  Cap count at MRC, if it is non-zero.
 4578      */
 4579     if (request->home_server->coa_mrc &&
 4580         (request->num_coa_requests >= request->home_server->coa_mrc)) {
 4581         RERROR("Failing request - originate-coa ID %u, due to lack of any response from coa server %s port %d",
 4582                request->proxy->id,
 4583                    inet_ntop(request->proxy->dst_ipaddr.af,
 4584                      &request->proxy->dst_ipaddr.ipaddr,
 4585                      buffer, sizeof(buffer)),
 4586                    request->proxy->dst_port);
 4587 
 4588     fail:
 4589         if (setup_post_proxy_fail(request)) {
 4590             request_queue_or_run(request, coa_no_reply);
 4591         } else {
 4592             request_done(request, FR_ACTION_DONE);
 4593         }
 4594         return;
 4595     }
 4596 
 4597     /*
 4598      *  RFC 5080 Section 2.2.1
 4599      *
 4600      *  RT = 2*RTprev + RAND*RTprev
 4601      *     = 1.9 * RTprev + rand(0,.2) * RTprev
 4602      *     = 1.9 * RTprev + rand(0,1) * (RTprev / 5)
 4603      */
 4604     delay = fr_rand();
 4605     delay ^= (delay >> 16);
 4606     delay &= 0xffff;
 4607     frac = request->delay / 5;
 4608     delay = ((frac >> 16) * delay) + (((frac & 0xffff) * delay) >> 16);
 4609 
 4610     delay += (2 * request->delay) - (request->delay / 10);
 4611 
 4612     /*
 4613      *  Cap delay at MRT, if MRT is non-zero.
 4614      */
 4615     if (request->home_server->coa_mrt &&
 4616         (delay > (request->home_server->coa_mrt * USEC))) {
 4617         int mrt_usec = request->home_server->coa_mrt * USEC;
 4618 
 4619         /*
 4620          *  delay = MRT + RAND * MRT
 4621          *        = 0.9 MRT + rand(0,.2)  * MRT
 4622          */
 4623         delay = fr_rand();
 4624         delay ^= (delay >> 15);
 4625         delay &= 0x1ffff;
 4626         delay = ((mrt_usec >> 16) * delay) + (((mrt_usec & 0xffff) * delay) >> 16);
 4627         delay += mrt_usec - (mrt_usec / 10);
 4628     }
 4629 
 4630     request->delay = delay;
 4631     when = now;
 4632     tv_add(&when, request->delay);
 4633     mrd = request->proxy->timestamp;
 4634     mrd.tv_sec += request->home_server->coa_mrd;
 4635 
 4636     /*
 4637      *  Cap duration at MRD.
 4638      */
 4639     if (timercmp(&mrd, &when, <)) {
 4640         when = mrd;
 4641     }
 4642     STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 4643 
 4644     request->num_coa_requests++; /* is NOT reset by code 3 lines above! */
 4645 
 4646     FR_STATS_TYPE_INC(request->home_server->stats.total_requests);
 4647 
 4648     RDEBUG2("Sending duplicate CoA request to home server %s port %d - ID: %d",
 4649         inet_ntop(request->proxy->dst_ipaddr.af,
 4650               &request->proxy->dst_ipaddr.ipaddr,
 4651               buffer, sizeof(buffer)),
 4652         request->proxy->dst_port,
 4653         request->proxy->id);
 4654 
 4655     request->proxy_listener->send(request->proxy_listener,
 4656                       request);
 4657 }
 4658 
 4659 
 4660 /*
 4661  *  Enforce maximum time for CoA packets
 4662  */
 4663 static bool coa_max_time(REQUEST *request)
 4664 {
 4665     struct timeval now, when;
 4666     rad_assert(request->magic == REQUEST_MAGIC);
 4667 #ifdef DEBUG_STATE_MACHINE
 4668     int action = FR_ACTION_TIMER;
 4669 #endif
 4670     int mrd;
 4671 
 4672     VERIFY_REQUEST(request);
 4673 
 4674     TRACE_STATE_MACHINE;
 4675     ASSERT_MASTER;
 4676 
 4677     /*
 4678      *  The child thread has acknowledged it's done.
 4679      *  Transition to the DONE state.
 4680      *
 4681      *  If the request was marked STOP, then the "check for
 4682      *  stop" macro already took care of it.
 4683      */
 4684     if (request->child_state == REQUEST_DONE) {
 4685     done:
 4686         request_done(request, FR_ACTION_CANCELLED);
 4687         return true;
 4688     }
 4689 
 4690     /*
 4691      *  The request is still running.  Enforce max_request_time.
 4692      *
 4693      *  Note that the *proxy* timestamp is the one we use, as
 4694      *  that's when the CoA packet was sent.
 4695      *
 4696      *  Note also that if there's an error, the home server
 4697      *  may not exist.
 4698      */
 4699     fr_event_now(el, &now);
 4700     when = request->proxy->timestamp;
 4701     if (request->home_server && (request->process != coa_running)) {
 4702         mrd = request->home_server->coa_mrd;
 4703     } else {
 4704         mrd = request->root->max_request_time;
 4705     }
 4706     when.tv_sec += mrd;
 4707 
 4708     /*
 4709      *  Taking too long: tell it to die.
 4710      */
 4711     if (timercmp(&now, &when, >=)) {
 4712         char buffer[256];
 4713 
 4714         if (request->process != coa_running) {
 4715             RERROR("Failing request - originate-coa ID %u, due to lack of any response from coa server %s port %d within %d seconds",
 4716                    request->proxy->id,
 4717                    inet_ntop(request->proxy->dst_ipaddr.af,
 4718                      &request->proxy->dst_ipaddr.ipaddr,
 4719                      buffer, sizeof(buffer)),
 4720                    request->proxy->dst_port,
 4721                    mrd);
 4722             goto done;
 4723         }
 4724 
 4725 #ifdef HAVE_PTHREAD_H
 4726         /*
 4727          *  If there's a child thread processing it,
 4728          *  complain.
 4729          */
 4730         if (spawn_flag &&
 4731             (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0)) {
 4732             RERROR("Unresponsive child for originate-coa, in component %s module %s",
 4733                   request->component ? request->component : "<core>",
 4734                   request->module ? request->module : "<core>");
 4735             exec_trigger(request, NULL, "server.thread.unresponsive", true);
 4736         } else
 4737 #endif
 4738         {
 4739             RERROR("originate-coa hit max_request_time.  Cancelling it.");
 4740         }
 4741 
 4742         /*
 4743          *  Tell the request that it's done.
 4744          */
 4745         goto done;
 4746     }
 4747 
 4748     /*
 4749      *  Let coa_retransmit() handle the retransmission timers.
 4750      */
 4751     if (request->process != coa_running) return false;
 4752 
 4753     /*
 4754      *  Sleep for some more.  We HOPE that the child will
 4755      *  become responsive at some point in the future.  We do
 4756      *  this by adding 50% to the current timer.
 4757      */
 4758     when = now;
 4759     tv_add(&when, request->delay);
 4760     request->delay += request->delay >> 1;
 4761     STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 4762     return false;
 4763 }
 4764 
 4765 
 4766 /** Wait for a reply after originating a CoA a request.
 4767  *
 4768  *  Retransmit the proxied packet, or time out and go to
 4769  *  coa_no_reply.  Mark the home server unresponsive, etc.
 4770  *
 4771  *  If we do receive a reply, we transition to coa_running.
 4772  *
 4773  *  \dot
 4774  *  digraph coa_wait_for_reply {
 4775  *      coa_wait_for_reply;
 4776  *
 4777  *      coa_wait_for_reply -> coa_no_reply [ label = "TIMER >= response_window" ];
 4778  *      coa_wait_for_reply -> timer [ label = "TIMER < max_request_time" ];
 4779  *      coa_wait_for_reply -> coa_running [ label = "PROXY_REPLY" arrowhead = "none"];
 4780  *      coa_wait_for_reply -> done [ label = "TIMER >= max_request_time" ];
 4781  *  }
 4782  *  \enddot
 4783  */
 4784 static void coa_wait_for_reply(REQUEST *request, int action)
 4785 {
 4786     VERIFY_REQUEST(request);
 4787 
 4788     TRACE_STATE_MACHINE;
 4789     ASSERT_MASTER;
 4790     CHECK_FOR_STOP;
 4791 
 4792     if (request->parent) coa_separate(request, false);
 4793 
 4794     switch (action) {
 4795     case FR_ACTION_TIMER:
 4796         if (coa_max_time(request)) break;
 4797 
 4798         coa_retransmit(request);
 4799         break;
 4800 
 4801     case FR_ACTION_PROXY_REPLY:
 4802         /*
 4803          *  Reset the initial delay for checking if we
 4804          *  should still run.
 4805          */
 4806         request->delay = (int)request->root->init_delay.tv_sec * USEC +
 4807             (int)request->root->init_delay.tv_usec;
 4808 
 4809         request_queue_or_run(request, coa_running);
 4810         break;
 4811 
 4812     default:
 4813         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 4814         break;
 4815     }
 4816 }
 4817 
 4818 static void coa_separate(REQUEST *request, bool retransmit)
 4819 {
 4820     VERIFY_REQUEST(request);
 4821 #ifdef DEBUG_STATE_MACHINE
 4822     int action = FR_ACTION_TIMER;
 4823 #endif
 4824 
 4825     TRACE_STATE_MACHINE;
 4826     ASSERT_MASTER;
 4827 
 4828     rad_assert(request->parent != NULL);
 4829     rad_assert(request->parent->coa == request);
 4830     rad_assert(request->ev == NULL);
 4831     rad_assert(!request->in_request_hash);
 4832     rad_assert(request->coa == NULL);
 4833 
 4834     (void) talloc_steal(NULL, request);
 4835     request->parent->coa = NULL;
 4836     request->parent = NULL;
 4837 
 4838     if (retransmit && (request->delay == 0) && !request->proxy_reply) {
 4839         coa_retransmit(request);
 4840     }
 4841 }
 4842 
 4843 
 4844 /** Process a request after the CoA has timed out.
 4845  *
 4846  *  Run the packet through Post-Proxy-Type Fail
 4847  *
 4848  *  \dot
 4849  *  digraph coa_no_reply {
 4850  *      coa_no_reply;
 4851  *
 4852  *      coa_no_reply -> dup [ label = "DUP", arrowhead = "none" ];
 4853  *      coa_no_reply -> timer [ label = "TIMER < max_request_time" ];
 4854  *      coa_no_reply -> coa_reply_too_late [ label = "PROXY_REPLY" arrowhead = "none"];
 4855  *      coa_no_reply -> process_proxy_reply [ label = "RUN" ];
 4856  *      coa_no_reply -> done [ label = "TIMER >= timeout" ];
 4857  *  }
 4858  *  \enddot
 4859  */
 4860 static void coa_no_reply(REQUEST *request, int action)
 4861 {
 4862     char buffer[128];
 4863 
 4864     VERIFY_REQUEST(request);
 4865 
 4866     TRACE_STATE_MACHINE;
 4867     CHECK_FOR_STOP;
 4868 
 4869     switch (action) {
 4870     case FR_ACTION_TIMER:
 4871         (void) coa_max_time(request);
 4872         break;
 4873 
 4874     case FR_ACTION_PROXY_REPLY: /* too late! */
 4875         RDEBUG2("Reply from CoA server %s port %d  - ID: %d arrived too late.",
 4876             inet_ntop(request->proxy->src_ipaddr.af,
 4877                   &request->proxy->src_ipaddr.ipaddr,
 4878                   buffer, sizeof(buffer)),
 4879             request->proxy->dst_port, request->proxy->id);
 4880         break;
 4881 
 4882     case FR_ACTION_RUN:
 4883         if (process_proxy_reply(request, NULL)) {
 4884             request->handle(request);
 4885         }
 4886         request_done(request, FR_ACTION_DONE);
 4887         break;
 4888 
 4889     default:
 4890         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 4891         break;
 4892     }
 4893 }
 4894 
 4895 
 4896 /** Process the request after receiving a coa reply.
 4897  *
 4898  *  Throught the post-proxy section, and the through the handler
 4899  *  function.
 4900  *
 4901  *  \dot
 4902  *  digraph coa_running {
 4903  *      coa_running;
 4904  *
 4905  *      coa_running -> timer [ label = "TIMER < max_request_time" ];
 4906  *      coa_running -> process_proxy_reply [ label = "RUN" ];
 4907  *      coa_running -> done [ label = "TIMER >= timeout" ];
 4908  *  }
 4909  *  \enddot
 4910  */
 4911 static void coa_running(REQUEST *request, int action)
 4912 {
 4913     VERIFY_REQUEST(request);
 4914 
 4915     TRACE_STATE_MACHINE;
 4916     CHECK_FOR_STOP;
 4917 
 4918     switch (action) {
 4919     case FR_ACTION_TIMER:
 4920         (void) coa_max_time(request);
 4921         break;
 4922 
 4923     case FR_ACTION_RUN:
 4924         if (process_proxy_reply(request, request->proxy_reply)) {
 4925             request->handle(request);
 4926         }
 4927         request_done(request, FR_ACTION_DONE);
 4928         break;
 4929 
 4930     default:
 4931         RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
 4932         break;
 4933     }
 4934 }
 4935 #endif  /* WITH_COA */
 4936 
 4937 /***********************************************************************
 4938  *
 4939  *  End of the State machine.  Start of additional helper code.
 4940  *
 4941  ***********************************************************************/
 4942 
 4943 /***********************************************************************
 4944  *
 4945  *  Event handlers.
 4946  *
 4947  ***********************************************************************/
 4948 static void event_socket_handler(fr_event_list_t *xel, UNUSED int fd, void *ctx)
 4949 {
 4950     rad_listen_t *listener = talloc_get_type_abort(ctx, rad_listen_t);
 4951 
 4952     rad_assert(xel == el);
 4953 
 4954     if ((listener->fd < 0)
 4955 #ifdef WITH_DETAIL
 4956 #ifndef WITH_DETAIL_THREAD
 4957         && (listener->type != RAD_LISTEN_DETAIL)
 4958 #endif
 4959 #endif
 4960         ) {
 4961         char buffer[256];
 4962 
 4963         listener->print(listener, buffer, sizeof(buffer));
 4964         ERROR("FATAL: Asked to read from closed socket: %s",
 4965                buffer);
 4966 
 4967         rad_panic("Socket was closed on us!");
 4968         fr_exit_now(1);
 4969     }
 4970 
 4971     listener->recv(listener);
 4972 }
 4973 
 4974 #ifdef WITH_DETAIL
 4975 #ifdef WITH_DETAIL_THREAD
 4976 #else
 4977 /*
 4978  *  This function is called periodically to see if this detail
 4979  *  file is available for reading.
 4980  */
 4981 static void event_poll_detail(void *ctx)
 4982 {
 4983     int delay;
 4984     rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
 4985     struct timeval when, now;
 4986     listen_detail_t *detail = this->data;
 4987 
 4988     rad_assert(this->type == RAD_LISTEN_DETAIL);
 4989 
 4990  redo:
 4991     event_socket_handler(el, this->fd, this);
 4992 
 4993     fr_event_now(el, &now);
 4994     when = now;
 4995 
 4996     /*
 4997      *  Backdoor API to get the delay until the next poll
 4998      *  time.
 4999      */
 5000     delay = this->encode(this, NULL);
 5001     if (delay == 0) goto redo;
 5002 
 5003     tv_add(&when, delay);
 5004 
 5005     ASSERT_MASTER;
 5006     if (!fr_event_insert(el, event_poll_detail, this,
 5007                  &when, &detail->ev)) {
 5008         ERROR("Failed creating handler");
 5009         fr_exit(1);
 5010     }
 5011 }
 5012 #endif  /* WITH_DETAIL_THREAD */
 5013 #endif  /* WITH_DETAIL */
 5014 
 5015 static void event_status(struct timeval *wake)
 5016 {
 5017     if (rad_debug_lvl == 0) {
 5018         if (just_started) {
 5019             INFO("Ready to process requests");
 5020             just_started = false;
 5021         }
 5022         return;
 5023     }
 5024 
 5025     if (!wake) {
 5026         INFO("Ready to process requests");
 5027 
 5028     } else if ((wake->tv_sec != 0) ||
 5029            (wake->tv_usec >= 100000)) {
 5030         DEBUG("Waking up in %d.%01u seconds.",
 5031               (int) wake->tv_sec, (unsigned int) wake->tv_usec / 100000);
 5032     }
 5033 
 5034 
 5035     /*
 5036      *  FIXME: Put this somewhere else, where it isn't called
 5037      *  all of the time...
 5038      */
 5039 
 5040     if (!spawn_flag) {
 5041         int argval;
 5042 
 5043         /*
 5044          *  If there are no child threads, then there may
 5045          *  be child processes.  In that case, wait for
 5046          *  their exit status, and throw that exit status
 5047          *  away.  This helps get rid of zxombie children.
 5048          */
 5049         while (waitpid(-1, &argval, WNOHANG) > 0) {
 5050             /* do nothing */
 5051         }
 5052     }
 5053 }
 5054 
 5055 #ifdef WITH_TCP
 5056 static void listener_free_cb(void *ctx)
 5057 {
 5058     rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
 5059     char buffer[1024];
 5060 
 5061     if (this->count > 0) {
 5062         struct timeval when;
 5063         listen_socket_t *sock = this->data;
 5064 
 5065         fr_event_now(el, &when);
 5066         when.tv_sec += 3;
 5067 
 5068         ASSERT_MASTER;
 5069         if (!fr_event_insert(el, listener_free_cb, this, &when,
 5070                      &(sock->ev))) {
 5071             rad_panic("Failed to insert event");
 5072         }
 5073 
 5074         return;
 5075     }
 5076 
 5077     /*
 5078      *  It's all free, close the socket.
 5079      */
 5080 
 5081     this->print(this, buffer, sizeof(buffer));
 5082     DEBUG("... cleaning up socket %s", buffer);
 5083     rad_assert(this->next == NULL);
 5084     talloc_free(this);
 5085 }
 5086 
 5087 #ifdef WITH_PROXY
 5088 static int proxy_eol_cb(void *ctx, void *data)
 5089 {
 5090     struct timeval when;
 5091     REQUEST *request = fr_packet2myptr(REQUEST, proxy, data);
 5092 
 5093     if (request->proxy_listener != ctx) return 0;
 5094 
 5095     /*
 5096      *  We don't care if it's being processed in a child thread.
 5097      */
 5098 
 5099 #ifdef WITH_ACCOUNTING
 5100     /*
 5101      *  Accounting packets should be deleted immediately.
 5102      *  They will never be retransmitted by the client.
 5103      */
 5104     if (request->proxy->code == PW_CODE_ACCOUNTING_REQUEST) {
 5105         RDEBUG("Stopping request due to failed connection to home server");
 5106         request->master_state = REQUEST_STOP_PROCESSING;
 5107     }
 5108 #endif
 5109 
 5110     /*
 5111      *  Reset the timer to be now, so that the request is
 5112      *  quickly updated.  But spread the requests randomly
 5113      *  over the next second, so that we don't overload the
 5114      *  server.
 5115      */
 5116     fr_event_now(el, &when);
 5117     tv_add(&when, fr_rand() % USEC);
 5118     STATE_MACHINE_TIMER(FR_ACTION_TIMER);
 5119 
 5120     /*
 5121      *  Don't delete it from the list.
 5122      */
 5123     return 0;
 5124 }
 5125 #endif  /* WITH_PROXY */
 5126 #endif  /* WITH_TCP */
 5127 
 5128 static void event_new_fd(rad_listen_t *this)
 5129 {
 5130     char buffer[1024];
 5131 
 5132     ASSERT_MASTER;
 5133 
 5134     if (this->status == RAD_LISTEN_STATUS_KNOWN) return;
 5135 
 5136     this->print(this, buffer, sizeof(buffer));
 5137 
 5138     if (this->status == RAD_LISTEN_STATUS_INIT) {
 5139         listen_socket_t *sock = this->data;
 5140 
 5141         rad_assert(sock != NULL);
 5142         if (just_started) {
 5143             DEBUG("Listening on %s", buffer);
 5144         } else {
 5145             INFO(" ... adding new socket %s", buffer);
 5146         }
 5147 
 5148 #ifdef WITH_PROXY
 5149         if (!just_started && (this->type == RAD_LISTEN_PROXY)) {
 5150             home_server_t *home;
 5151             
 5152             home = sock->home;
 5153             if (!home || !home->limit.max_connections) {
 5154                 INFO(" ... adding new socket %s", buffer);
 5155             } else {
 5156                 INFO(" ... adding new socket %s (%u of %u)", buffer,
 5157                      home->limit.num_connections, home->limit.max_connections);
 5158             }
 5159 
 5160 #endif
 5161         }
 5162 
 5163         switch (this->type) {
 5164 #ifdef WITH_DETAIL
 5165         /*
 5166          *  Detail files are always known, and aren't
 5167          *  put into the socket event loop.
 5168          */
 5169         case RAD_LISTEN_DETAIL:
 5170             this->status = RAD_LISTEN_STATUS_KNOWN;
 5171 
 5172 #ifndef WITH_DETAIL_THREAD
 5173             /*
 5174              *  Set up the first poll interval.
 5175              */
 5176             event_poll_detail(this);
 5177             return;
 5178 #else
 5179             break;  /* add the FD to the list */
 5180 #endif
 5181 #endif  /* WITH_DETAIL */
 5182 
 5183 #ifdef WITH_PROXY
 5184         /*
 5185          *  Add it to the list of sockets we can use.
 5186          *  Server sockets (i.e. auth/acct) are never
 5187          *  added to the packet list.
 5188          */
 5189         case RAD_LISTEN_PROXY:
 5190 #ifdef WITH_TCP
 5191             rad_assert((sock->proto == IPPROTO_UDP) || (sock->home != NULL));
 5192 
 5193             /*
 5194              *  Add timers to outgoing child sockets, if necessary.
 5195              */
 5196             if (sock->proto == IPPROTO_TCP && sock->opened &&
 5197                 (sock->home->limit.lifetime || sock->home->limit.idle_timeout)) {
 5198                 struct timeval when;
 5199 
 5200                 when.tv_sec = sock->opened + 1;
 5201                 when.tv_usec = 0;
 5202 
 5203                 ASSERT_MASTER;
 5204                 if (!fr_event_insert(el, tcp_socket_timer, this, &when,
 5205                              &(sock->ev))) {
 5206                     rad_panic("Failed to insert event");
 5207                 }
 5208             }
 5209 #endif  /* WITH_TCP */
 5210             break;
 5211 #endif  /* WITH_PROXY */
 5212 
 5213             /*
 5214              *  FIXME: put idle timers on command sockets.
 5215              */
 5216 
 5217         default:
 5218 #ifdef WITH_TCP
 5219             /*
 5220              *  Add timers to incoming child sockets, if necessary.
 5221              */
 5222             if (sock->proto == IPPROTO_TCP && sock->opened &&
 5223                 (sock->limit.lifetime || sock->limit.idle_timeout)) {
 5224                 struct timeval when;
 5225 
 5226                 when.tv_sec = sock->opened + 1;
 5227                 when.tv_usec = 0;
 5228 
 5229                 ASSERT_MASTER;
 5230                 if (!fr_event_insert(el, tcp_socket_timer, this, &when,
 5231                              &(sock->ev))) {
 5232                     ERROR("Failed adding timer for socket: %s", fr_strerror());
 5233                     fr_exit(1);
 5234                 }
 5235             }
 5236 #endif  /* WITH_TCP */
 5237             break;
 5238         } /* switch over listener types */
 5239 
 5240         /*
 5241          *  All sockets: add the FD to the event handler.
 5242          */
 5243         if (fr_event_fd_insert(el, 0, this->fd,
 5244                        event_socket_handler, this)) {
 5245             this->status = RAD_LISTEN_STATUS_KNOWN;
 5246             return;
 5247         }
 5248 
 5249         ERROR("Failed adding event handler for socket: %s", fr_strerror());
 5250         this->status = RAD_LISTEN_STATUS_REMOVE_NOW;
 5251     } /* end of INIT */
 5252 
 5253 #ifdef WITH_TCP
 5254     /*
 5255      *  The socket has reached a timeout.  Try to close it.
 5256      */
 5257     if (this->status == RAD_LISTEN_STATUS_FROZEN) {
 5258         /*
 5259          *  Requests are still using the socket.  Wait for
 5260          *  them to finish.
 5261          */
 5262         if (this->count > 0) {
 5263             struct timeval when;
 5264             listen_socket_t *sock = this->data;
 5265 
 5266             /*
 5267              *  Try again to clean up the socket in 30
 5268              *  seconds.
 5269              */
 5270             gettimeofday(&when, NULL);
 5271             when.tv_sec += 30;
 5272 
 5273             ASSERT_MASTER;
 5274             if (!fr_event_insert(el,
 5275                          (fr_event_callback_t) event_new_fd,
 5276                          this, &when, &sock->ev)) {
 5277                 rad_panic("Failed to insert event");
 5278             }
 5279 
 5280             return;
 5281         }
 5282 
 5283         fr_event_fd_delete(el, 0, this->fd);
 5284         this->status = RAD_LISTEN_STATUS_REMOVE_NOW;
 5285     }
 5286 
 5287     /*
 5288      *  The socket has had a catastrophic error.  Close it.
 5289      */
 5290     if (this->status == RAD_LISTEN_STATUS_EOL) {
 5291         /*
 5292          *  Remove it from the list of live FD's.
 5293          */
 5294         fr_event_fd_delete(el, 0, this->fd);
 5295 
 5296 #ifdef WITH_PROXY
 5297         /*
 5298          *  Tell all requests using this socket that the socket is dead.
 5299          */
 5300         if (this->type == RAD_LISTEN_PROXY) {
 5301             PTHREAD_MUTEX_LOCK(&proxy_mutex);
 5302             if (!fr_packet_list_socket_freeze(proxy_list,
 5303                               this->fd)) {
 5304                 ERROR("Fatal error freezing socket: %s", fr_strerror());
 5305                 fr_exit(1);
 5306             }
 5307 
 5308             if (this->count > 0) {
 5309                 fr_packet_list_walk(proxy_list, this, proxy_eol_cb);
 5310             }
 5311             PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 5312         }
 5313 #endif  /* WITH_PROXY */
 5314 
 5315         /*
 5316          *  Requests are still using the socket.  Wait for
 5317          *  them to finish.
 5318          */
 5319         if (this->count > 0) {
 5320             struct timeval when;
 5321             listen_socket_t *sock = this->data;
 5322 
 5323             /*
 5324              *  Try again to clean up the socket in 30
 5325              *  seconds.
 5326              */
 5327             gettimeofday(&when, NULL);
 5328             when.tv_sec += 30;
 5329 
 5330             ASSERT_MASTER;
 5331             if (!fr_event_insert(el,
 5332                          (fr_event_callback_t) event_new_fd,
 5333                          this, &when, &sock->ev)) {
 5334                 rad_panic("Failed to insert event");
 5335             }
 5336 
 5337             return;
 5338         }
 5339 
 5340         /*
 5341          *  No one is using the socket.  We can remove it now.
 5342          */
 5343         this->status = RAD_LISTEN_STATUS_REMOVE_NOW;
 5344     } /* socket is at EOL */
 5345 #endif    /* WITH_TCP */
 5346 
 5347     /*
 5348      *  Nuke the socket.
 5349      */
 5350     if (this->status == RAD_LISTEN_STATUS_REMOVE_NOW) {
 5351         int devnull;
 5352 #ifdef WITH_TCP
 5353         listen_socket_t *sock = this->data;
 5354         struct timeval when;
 5355 #endif
 5356 
 5357         /*
 5358          *      Re-open the socket, pointing it to /dev/null.
 5359          *      This means that all writes proceed without
 5360          *      blocking, and all reads return "no data".
 5361          *
 5362          *      This leaves the socket active, so any child
 5363          *      threads won't go insane.  But it means that
 5364          *      they cannot send or receive any packets.
 5365          *
 5366          *  This is EXTRA work in the normal case, when
 5367          *  sockets are closed without error.  But it lets
 5368          *  us have one simple processing method for all
 5369          *  sockets.
 5370          */
 5371         devnull = open("/dev/null", O_RDWR);
 5372         if (devnull < 0) {
 5373             ERROR("FATAL failure opening /dev/null: %s",
 5374                    fr_syserror(errno));
 5375             fr_exit(1);
 5376         }
 5377         if (dup2(devnull, this->fd) < 0) {
 5378             ERROR("FATAL failure closing socket: %s",
 5379                    fr_syserror(errno));
 5380             fr_exit(1);
 5381         }
 5382         close(devnull);
 5383 
 5384 #ifdef WITH_DETAIL
 5385         rad_assert(this->type != RAD_LISTEN_DETAIL);
 5386 #endif
 5387 
 5388 #ifdef WITH_TCP
 5389 #ifdef WITH_PROXY
 5390         /*
 5391          *  The socket is dead.  Force all proxied packets
 5392          *  to stop using it.  And then remove it from the
 5393          *  list of outgoing sockets.
 5394          */
 5395         if (this->type == RAD_LISTEN_PROXY) {
 5396             home_server_t *home;
 5397 
 5398             home = sock->home;
 5399             if (!home || !home->limit.max_connections) {
 5400                 INFO(" ... shutting down socket %s", buffer);
 5401             } else {
 5402                 INFO(" ... shutting down socket %s (%u of %u)", buffer,
 5403                      home->limit.num_connections, home->limit.max_connections);
 5404             }
 5405 
 5406             PTHREAD_MUTEX_LOCK(&proxy_mutex);
 5407             fr_packet_list_walk(proxy_list, this, eol_proxy_listener);
 5408 
 5409             if (!fr_packet_list_socket_del(proxy_list, this->fd)) {
 5410                 ERROR("Fatal error removing socket %s: %s",
 5411                       buffer, fr_strerror());
 5412                 fr_exit(1);
 5413             }
 5414             PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 5415         } else
 5416 #endif  /* WITH_PROXY */
 5417         {
 5418             INFO(" ... shutting down socket %s", buffer);
 5419 
 5420             /*
 5421              *  EOL all requests using this socket.
 5422              */
 5423             rbtree_walk(pl, RBTREE_DELETE_ORDER, eol_listener, this);
 5424         }
 5425 
 5426         /*
 5427          *  No child threads, clean it up now.
 5428          */
 5429         if (!spawn_flag) {
 5430             ASSERT_MASTER;
 5431             if (sock->ev) fr_event_delete(el, &sock->ev);
 5432             listen_free(&this);
 5433             return;
 5434         }
 5435 
 5436         /*
 5437          *  Wait until all requests using this socket are done.
 5438          */
 5439         gettimeofday(&when, NULL);
 5440         when.tv_sec += 3;
 5441 
 5442         ASSERT_MASTER;
 5443         if (!fr_event_insert(el, listener_free_cb, this, &when,
 5444                      &(sock->ev))) {
 5445             rad_panic("Failed to insert event");
 5446         }
 5447 #endif  /* WITH_TCP */
 5448     }
 5449 
 5450     return;
 5451 }
 5452 
 5453 /***********************************************************************
 5454  *
 5455  *  Signal handlers.
 5456  *
 5457  ***********************************************************************/
 5458 
 5459 static void handle_signal_self(int flag)
 5460 {
 5461     ASSERT_MASTER;
 5462 
 5463     if ((flag & (RADIUS_SIGNAL_SELF_EXIT | RADIUS_SIGNAL_SELF_TERM)) != 0) {
 5464         if ((flag & RADIUS_SIGNAL_SELF_EXIT) != 0) {
 5465             INFO("Signalled to exit");
 5466             fr_event_loop_exit(el, 1);
 5467         } else {
 5468             INFO("Signalled to terminate");
 5469             fr_event_loop_exit(el, 2);
 5470         }
 5471 
 5472         return;
 5473     } /* else exit/term flags weren't set */
 5474 
 5475     /*
 5476      *  Tell the even loop to stop processing.
 5477      */
 5478     if ((flag & RADIUS_SIGNAL_SELF_HUP) != 0) {
 5479         time_t when;
 5480         static time_t last_hup = 0;
 5481 
 5482         when = time(NULL);
 5483         if ((int) (when - last_hup) < 5) {
 5484             INFO("Ignoring HUP (less than 5s since last one)");
 5485             return;
 5486         }
 5487 
 5488         INFO("Received HUP signal");
 5489 
 5490         last_hup = when;
 5491 
 5492         exec_trigger(NULL, NULL, "server.signal.hup", true);
 5493         fr_event_loop_exit(el, 0x80);
 5494     }
 5495 
 5496 #if defined(WITH_DETAIL) && !defined(WITH_DETAIL_THREAD)
 5497     if ((flag & RADIUS_SIGNAL_SELF_DETAIL) != 0) {
 5498         rad_listen_t *this;
 5499 
 5500         /*
 5501          *  FIXME: O(N) loops suck.
 5502          */
 5503         for (this = main_config.listen;
 5504              this != NULL;
 5505              this = this->next) {
 5506             if (this->type != RAD_LISTEN_DETAIL) continue;
 5507 
 5508             /*
 5509              *  This one didn't send the signal, skip
 5510              *  it.
 5511              */
 5512             if (!this->decode(this, NULL)) continue;
 5513 
 5514             /*
 5515              *  Go service the interrupt.
 5516              */
 5517             event_poll_detail(this);
 5518         }
 5519     }
 5520 #endif
 5521 
 5522 #if defined(WITH_PROXY) && defined(HAVE_PTHREAD_H)
 5523     /*
 5524      *  There are new listeners in the list.  Run
 5525      *  event_new_fd() on them.
 5526      */
 5527     if ((flag & RADIUS_SIGNAL_SELF_NEW_FD) != 0) {
 5528         rad_listen_t *this, *next;
 5529 
 5530         FD_MUTEX_LOCK(&fd_mutex);
 5531 
 5532         /*
 5533          *  FIXME: unlock the mutex before calling
 5534          *  event_new_fd()?
 5535          */
 5536         for (this = new_listeners; this != NULL; this = next) {
 5537             next = this->next;
 5538             this->next = NULL;
 5539 
 5540             event_new_fd(this);
 5541         }
 5542 
 5543         new_listeners = NULL;
 5544         FD_MUTEX_UNLOCK(&fd_mutex);
 5545     }
 5546 #endif
 5547 }
 5548 
 5549 #ifndef HAVE_PTHREAD_H
 5550 void radius_signal_self(int flag)
 5551 {
 5552     if (flag == RADIUS_SIGNAL_SELF_TERM) {
 5553         main_config.exiting = true;
 5554     }
 5555 
 5556     return handle_signal_self(flag);
 5557 }
 5558 
 5559 #else
 5560 static int self_pipe[2] = { -1, -1 };
 5561 
 5562 /*
 5563  *  Inform ourselves that we received a signal.
 5564  */
 5565 void radius_signal_self(int flag)
 5566 {
 5567     ssize_t rcode;
 5568     uint8_t buffer[16];
 5569 
 5570     if (flag == RADIUS_SIGNAL_SELF_TERM) {
 5571         main_config.exiting = true;
 5572     }
 5573 
 5574     /*
 5575      *  The read MUST be non-blocking for this to work.
 5576      */
 5577     rcode = read(self_pipe[0], buffer, sizeof(buffer));
 5578     if (rcode > 0) {
 5579         ssize_t i;
 5580 
 5581         for (i = 0; i < rcode; i++) {
 5582             buffer[0] |= buffer[i];
 5583         }
 5584     } else {
 5585         buffer[0] = 0;
 5586     }
 5587 
 5588     buffer[0] |= flag;
 5589 
 5590     if (write(self_pipe[1], buffer, 1) < 0) fr_exit(0);
 5591 }
 5592 
 5593 
 5594 static void event_signal_handler(UNUSED fr_event_list_t *xel,
 5595                  UNUSED int fd, UNUSED void *ctx)
 5596 {
 5597     ssize_t i, rcode;
 5598     uint8_t buffer[32];
 5599 
 5600     rcode = read(self_pipe[0], buffer, sizeof(buffer));
 5601     if (rcode <= 0) return;
 5602 
 5603     /*
 5604      *  Merge pending signals.
 5605      */
 5606     for (i = 0; i < rcode; i++) {
 5607         buffer[0] |= buffer[i];
 5608     }
 5609 
 5610     handle_signal_self(buffer[0]);
 5611 }
 5612 #endif  /* HAVE_PTHREAD_H */
 5613 
 5614 /***********************************************************************
 5615  *
 5616  *  Bootstrapping code.
 5617  *
 5618  ***********************************************************************/
 5619 
 5620 /*
 5621  *  Externally-visibly functions.
 5622  */
 5623 int radius_event_init(TALLOC_CTX *ctx) {
 5624     el = fr_event_list_create(ctx, event_status);
 5625     if (!el) return 0;
 5626 
 5627 #ifdef HAVE_SYSTEMD_WATCHDOG
 5628     if (sd_watchdog_interval.tv_sec || sd_watchdog_interval.tv_usec) {
 5629         struct timeval now;
 5630 
 5631         fr_event_now(el, &now);
 5632 
 5633         sdwd.when = now;
 5634         sdwd.el = el;
 5635 
 5636         sd_watchdog_event(&sdwd);
 5637     }
 5638 #endif
 5639 
 5640     return 1;
 5641 }
 5642 
 5643 static int packet_entry_cmp(void const *one, void const *two)
 5644 {
 5645     RADIUS_PACKET const * const *a = one;
 5646     RADIUS_PACKET const * const *b = two;
 5647 
 5648     return fr_packet_cmp(*a, *b);
 5649 }
 5650 
 5651 #ifdef WITH_PROXY
 5652 /*
 5653  *  They haven't defined a proxy listener.  Automatically
 5654  *  add one for them, with the correct address family.
 5655  */
 5656 static void create_default_proxy_listener(int af)
 5657 {
 5658     uint16_t    port = 0;
 5659     home_server_t   home;
 5660     listen_socket_t *sock;
 5661     rad_listen_t    *this;
 5662 
 5663     memset(&home, 0, sizeof(home));
 5664 
 5665     /*
 5666      *  Open a default UDP port
 5667      */
 5668     home.proto = IPPROTO_UDP;
 5669     port = 0;
 5670 
 5671     /*
 5672      *  Set the address family.
 5673      */
 5674     home.src_ipaddr.af = af;
 5675     home.ipaddr.af = af;
 5676 
 5677     /*
 5678      *  Get the correct listener.
 5679      */
 5680     this = proxy_new_listener(proxy_ctx, &home, port);
 5681     if (!this) {
 5682         fr_exit_now(1);
 5683     }
 5684 
 5685     sock = this->data;
 5686     if (!fr_packet_list_socket_add(proxy_list, this->fd,
 5687                        sock->proto,
 5688                        &sock->other_ipaddr, sock->other_port,
 5689                        this)) {
 5690         ERROR("Failed adding proxy socket");
 5691         fr_exit_now(1);
 5692     }
 5693 
 5694     /*
 5695      *  Insert the FD into list of FDs to listen on.
 5696      */
 5697     radius_update_listener(this);
 5698 }
 5699 
 5700 /*
 5701  *  See if we automatically need to open a proxy socket.
 5702  */
 5703 static void check_proxy(rad_listen_t *head)
 5704 {
 5705     bool        defined_proxy;
 5706     bool        has_v4, has_v6;
 5707     rad_listen_t    *this;
 5708 
 5709     if (check_config) return;
 5710     if (!main_config.proxy_requests) return;
 5711     if (!head) return;
 5712 #ifdef WITH_TCP
 5713     if (!home_servers_udp) return;
 5714 #endif
 5715 
 5716     /*
 5717      *  We passed "-i" on the command line.  Use that address
 5718      *  family for the proxy socket.
 5719      */
 5720     if (main_config.myip.af != AF_UNSPEC) {
 5721         create_default_proxy_listener(main_config.myip.af);
 5722         return;
 5723     }
 5724 
 5725     defined_proxy = has_v4 = has_v6 = false;
 5726 
 5727     /*
 5728      *  Figure out if we need to open a proxy socket, and if
 5729      *  so, which one.
 5730      */
 5731     for (this = head; this != NULL; this = this->next) {
 5732         listen_socket_t *sock;
 5733 
 5734         switch (this->type) {
 5735         case RAD_LISTEN_PROXY:
 5736             defined_proxy = true;
 5737             break;
 5738 
 5739         case RAD_LISTEN_AUTH:
 5740 #ifdef WITH_ACCT
 5741         case RAD_LISTEN_ACCT:
 5742 #endif
 5743 #ifdef WITH_COA
 5744         case RAD_LISTEN_COA:
 5745 #endif
 5746             sock = this->data;
 5747             if (sock->my_ipaddr.af == AF_INET) has_v4 = true;
 5748             if (sock->my_ipaddr.af == AF_INET6) has_v6 = true;
 5749             break;
 5750             
 5751         default:
 5752             break;
 5753         }
 5754     }
 5755 
 5756     /*
 5757      *  Assume they know what they're doing.
 5758      */
 5759     if (defined_proxy) return;
 5760 
 5761     if (has_v4) create_default_proxy_listener(AF_INET);
 5762 
 5763     if (has_v6) create_default_proxy_listener(AF_INET6);
 5764 }
 5765 #endif
 5766 
 5767 int radius_event_start(CONF_SECTION *cs, bool have_children)
 5768 {
 5769     rad_listen_t *head = NULL;
 5770 
 5771     if (fr_start_time != (time_t)-1) return 0;
 5772 
 5773     time(&fr_start_time);
 5774 
 5775     if (!check_config) {
 5776         /*
 5777          *  radius_event_init() must be called first
 5778          */
 5779         rad_assert(el);
 5780 
 5781         pl = rbtree_create(NULL, packet_entry_cmp, NULL, 0);
 5782         if (!pl) return 0;  /* leak el */
 5783     }
 5784 
 5785     request_num_counter = 0;
 5786 
 5787 #ifdef WITH_PROXY
 5788     if (main_config.proxy_requests && !check_config) {
 5789         /*
 5790          *  Create the tree for managing proxied requests and
 5791          *  responses.
 5792          */
 5793         proxy_list = fr_packet_list_create(1);
 5794         if (!proxy_list) return 0;
 5795 
 5796 #ifdef HAVE_PTHREAD_H
 5797         if (pthread_mutex_init(&proxy_mutex, NULL) != 0) {
 5798             ERROR("FATAL: Failed to initialize proxy mutex: %s",
 5799                    fr_syserror(errno));
 5800             fr_exit(1);
 5801         }
 5802 #endif
 5803 
 5804         /*
 5805          *  The "init_delay" is set to "response_window".
 5806          *  Reset it to half of "response_window" in order
 5807          *  to give the event loop enough time to service
 5808          *  the event before hitting "response_window".
 5809          */
 5810         main_config.init_delay.tv_usec += (main_config.init_delay.tv_sec & 0x01) * USEC;
 5811         main_config.init_delay.tv_usec >>= 1;
 5812         main_config.init_delay.tv_sec >>= 1;
 5813 
 5814         proxy_ctx = talloc_init("proxy");
 5815     }
 5816 #endif
 5817 
 5818     /*
 5819      *  Move all of the thread calls to this file?
 5820      *
 5821      *  It may be best for the mutexes to be in this file...
 5822      */
 5823     spawn_flag = have_children;
 5824 
 5825 #ifdef HAVE_PTHREAD_H
 5826     NO_SUCH_CHILD_PID = pthread_self(); /* not a child thread */
 5827 
 5828     /*
 5829      *  Initialize the threads ONLY if we're spawning, AND
 5830      *  we're running normally.
 5831      */
 5832     if (have_children && !check_config &&
 5833         (thread_pool_init(cs, &spawn_flag) < 0)) {
 5834         fr_exit(1);
 5835     }
 5836 #endif
 5837 
 5838     if (check_config) {
 5839         DEBUG("%s: #### Skipping IP addresses and Ports ####",
 5840                main_config.name);
 5841         if (listen_init(cs, &head, spawn_flag) < 0) {
 5842             fflush(NULL);
 5843             fr_exit(1);
 5844         }
 5845         return 1;
 5846     }
 5847 
 5848 #ifdef HAVE_PTHREAD_H
 5849     /*
 5850      *  Child threads need a pipe to signal us, as do the
 5851      *  signal handlers.
 5852      */
 5853     if (pipe(self_pipe) < 0) {
 5854         ERROR("Error opening internal pipe: %s", fr_syserror(errno));
 5855         fr_exit(1);
 5856     }
 5857     if ((fcntl(self_pipe[0], F_SETFL, O_NONBLOCK) < 0) ||
 5858         (fcntl(self_pipe[0], F_SETFD, FD_CLOEXEC) < 0)) {
 5859         ERROR("Error setting internal flags: %s", fr_syserror(errno));
 5860         fr_exit(1);
 5861