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