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