Make tls-psk-identity available during request processing
[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 = paircopy2(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 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                 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         if (!request) return 1;
1705
1706         /*
1707          *      Remember the request in the list.
1708          */
1709         if (!listener->nodup) {
1710                 if (!fr_packet_list_insert(pl, &request->packet)) {
1711                         RERROR("Failed to insert request in the list of live requests: discarding it");
1712                         request_done(request, FR_ACTION_DONE);
1713                         return 1;
1714                 }
1715
1716                 request->in_request_hash = true;
1717         }
1718
1719         /*
1720          *      Process it.  Send a response, and free it.
1721          */
1722         if (listener->synchronous) {
1723                 request->listener->decode(request->listener, request);
1724                 request->username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
1725                 request->password = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY);
1726
1727                 fun(request);
1728
1729                 if (request->reply->code != 0) {
1730                         request->listener->send(request->listener, request);
1731                 } else {
1732                         RDEBUG("Not sending reply");
1733                 }
1734                 talloc_free(request);
1735                 return 1;
1736         }
1737
1738         /*
1739          *      Otherwise, insert it into the state machine.
1740          *      The child threads will take care of processing it.
1741          */
1742         request_queue_or_run(request, request_running);
1743
1744         return 1;
1745 }
1746
1747
1748 static REQUEST *request_setup(rad_listen_t *listener, RADIUS_PACKET *packet,
1749                               RADCLIENT *client, RAD_REQUEST_FUNP fun)
1750 {
1751         REQUEST *request;
1752
1753         /*
1754          *      Create and initialize the new request.
1755          */
1756         request = request_alloc(NULL);
1757         request->reply = rad_alloc(request, false);
1758         if (!request->reply) {
1759                 ERROR("No memory");
1760                 talloc_free(request);
1761                 return NULL;
1762         }
1763
1764         request->listener = listener;
1765         request->client = client;
1766         request->packet = talloc_steal(request, packet);
1767         request->number = request_num_counter++;
1768         request->priority = listener->type;
1769         request->master_state = REQUEST_ACTIVE;
1770 #ifdef DEBUG_STATE_MACHINE
1771         if (debug_flag) printf("(%u) ********\tSTATE %s C-%s -> C-%s\t********\n",
1772                                request->number, __FUNCTION__,
1773                                child_state_names[request->child_state],
1774                                child_state_names[REQUEST_RUNNING]);
1775 #endif
1776         request->child_state = REQUEST_RUNNING;
1777         request->handle = fun;
1778         NO_CHILD_THREAD;
1779
1780 #ifdef WITH_STATS
1781         request->listener->stats.last_packet = request->packet->timestamp.tv_sec;
1782         if (packet->code == PW_CODE_ACCESS_REQUEST) {
1783                 request->client->auth.last_packet = request->packet->timestamp.tv_sec;
1784                 radius_auth_stats.last_packet = request->packet->timestamp.tv_sec;
1785 #ifdef WITH_ACCOUNTING
1786         } else if (packet->code == PW_CODE_ACCOUNTING_REQUEST) {
1787                 request->client->acct.last_packet = request->packet->timestamp.tv_sec;
1788                 radius_acct_stats.last_packet = request->packet->timestamp.tv_sec;
1789 #endif
1790         }
1791 #endif  /* WITH_STATS */
1792
1793         /*
1794          *      Status-Server packets go to the head of the queue.
1795          */
1796         if (request->packet->code == PW_CODE_STATUS_SERVER) request->priority = 0;
1797
1798         /*
1799          *      Set virtual server identity
1800          */
1801         if (client->server) {
1802                 request->server = client->server;
1803         } else if (listener->server) {
1804                 request->server = listener->server;
1805         } else {
1806                 request->server = NULL;
1807         }
1808
1809         request->root = &main_config;
1810 #ifdef WITH_TCP
1811         request->listener->count++;
1812 #endif
1813
1814         /*
1815          *      The request passes many of our sanity checks.
1816          *      From here on in, if anything goes wrong, we
1817          *      send a reject message, instead of dropping the
1818          *      packet.
1819          */
1820
1821         /*
1822          *      Build the reply template from the request.
1823          */
1824
1825         request->reply->sockfd = request->packet->sockfd;
1826         request->reply->dst_ipaddr = request->packet->src_ipaddr;
1827         request->reply->src_ipaddr = request->packet->dst_ipaddr;
1828         request->reply->dst_port = request->packet->src_port;
1829         request->reply->src_port = request->packet->dst_port;
1830         request->reply->id = request->packet->id;
1831         request->reply->code = 0; /* UNKNOWN code */
1832         memcpy(request->reply->vector, request->packet->vector,
1833                sizeof(request->reply->vector));
1834         request->reply->vps = NULL;
1835         request->reply->data = NULL;
1836         request->reply->data_len = 0;
1837
1838         return request;
1839 }
1840
1841 #ifdef WITH_TCP
1842 /***********************************************************************
1843  *
1844  *      TCP Handlers.
1845  *
1846  ***********************************************************************/
1847
1848 /*
1849  *      Timer function for all TCP sockets.
1850  */
1851 static void tcp_socket_timer(void *ctx)
1852 {
1853         rad_listen_t *listener = talloc_get_type_abort(ctx, rad_listen_t);
1854         listen_socket_t *sock = listener->data;
1855         struct timeval end, now;
1856         char buffer[256];
1857         fr_socket_limit_t *limit;
1858
1859         ASSERT_MASTER;
1860
1861         fr_event_now(el, &now);
1862
1863         if (listener->status != RAD_LISTEN_STATUS_KNOWN) return;
1864
1865         switch (listener->type) {
1866 #ifdef WITH_PROXY
1867         case RAD_LISTEN_PROXY:
1868                 limit = &sock->home->limit;
1869                 break;
1870 #endif
1871
1872         case RAD_LISTEN_AUTH:
1873 #ifdef WITH_ACCOUNTING
1874         case RAD_LISTEN_ACCT:
1875 #endif
1876                 limit = &sock->limit;
1877                 break;
1878
1879         default:
1880                 return;
1881         }
1882
1883         /*
1884          *      If we enforce a lifetime, do it now.
1885          */
1886         if (limit->lifetime > 0) {
1887                 end.tv_sec = sock->opened + limit->lifetime;
1888                 end.tv_usec = 0;
1889
1890                 if (timercmp(&end, &now, <=)) {
1891                         listener->print(listener, buffer, sizeof(buffer));
1892                         DEBUG("Reached maximum lifetime on socket %s", buffer);
1893
1894                 do_close:
1895
1896                         listener->status = RAD_LISTEN_STATUS_EOL;
1897                         event_new_fd(listener);
1898                         return;
1899                 }
1900         } else {
1901                 end = now;
1902                 end.tv_sec += 3600;
1903         }
1904
1905         /*
1906          *      Enforce an idle timeout.
1907          */
1908         if (limit->idle_timeout > 0) {
1909                 struct timeval idle;
1910
1911                 rad_assert(sock->last_packet != 0);
1912                 idle.tv_sec = sock->last_packet + limit->idle_timeout;
1913                 idle.tv_usec = 0;
1914
1915                 if (timercmp(&idle, &now, <=)) {
1916                         listener->print(listener, buffer, sizeof(buffer));
1917                         DEBUG("Reached idle timeout on socket %s", buffer);
1918                         goto do_close;
1919                 }
1920
1921                 /*
1922                  *      Enforce the minimum of idle timeout or lifetime.
1923                  */
1924                 if (timercmp(&idle, &end, <)) {
1925                         end = idle;
1926                 }
1927         }
1928
1929         /*
1930          *      Wake up at t + 0.5s.  The code above checks if the timers
1931          *      are <= t.  This addition gives us a bit of leeway.
1932          */
1933         end.tv_usec = USEC / 2;
1934
1935         if (!fr_event_insert(el, tcp_socket_timer, listener, &end, &sock->ev)) {
1936                 rad_panic("Failed to insert event");
1937         }
1938 }
1939
1940
1941 #ifdef WITH_PROXY
1942 /*
1943  *      Add +/- 2s of jitter, as suggested in RFC 3539
1944  *      and in RFC 5080.
1945  */
1946 static void add_jitter(struct timeval *when)
1947 {
1948         uint32_t jitter;
1949
1950         when->tv_sec -= 2;
1951
1952         jitter = fr_rand();
1953         jitter ^= (jitter >> 10);
1954         jitter &= ((1 << 22) - 1); /* 22 bits of 1 */
1955
1956         /*
1957          *      Add in ~ (4 * USEC) of jitter.
1958          */
1959         tv_add(when, jitter);
1960 }
1961
1962 /*
1963  *      Called by socket_del to remove requests with this socket
1964  */
1965 static int eol_proxy_listener(void *ctx, void *data)
1966 {
1967         rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
1968         RADIUS_PACKET **proxy_p = data;
1969         REQUEST *request;
1970
1971         request = fr_packet2myptr(REQUEST, proxy, proxy_p);
1972         if (request->proxy_listener != this) return 0;
1973
1974         /*
1975          *      The normal "remove_from_proxy_hash" tries to grab the
1976          *      proxy mutex.  We already have it held, so grabbing it
1977          *      again will cause a deadlock.  Instead, call the "no
1978          *      lock" version of the function.
1979          */
1980         rad_assert(request->in_proxy_hash == true);
1981         remove_from_proxy_hash_nl(request, false);
1982
1983         /*
1984          *      Don't mark it as DONE.  The client can retransmit, and
1985          *      the packet SHOULD be re-proxied somewhere else.
1986          *
1987          *      Return "2" means that the rbtree code will remove it
1988          *      from the tree, and we don't need to do it ourselves.
1989          */
1990         return 2;
1991 }
1992 #endif  /* WITH_PROXY */
1993
1994 static int eol_listener(void *ctx, void *data)
1995 {
1996         rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
1997         RADIUS_PACKET **packet_p = data;
1998         REQUEST *request;
1999
2000         request = fr_packet2myptr(REQUEST, packet, packet_p);
2001         if (request->listener != this) return 0;
2002
2003         request->master_state = REQUEST_STOP_PROCESSING;
2004
2005         return 0;
2006 }
2007 #endif  /* WITH_TCP */
2008
2009 #ifdef WITH_PROXY
2010 /***********************************************************************
2011  *
2012  *      Proxy handlers for the state machine.
2013  *
2014  ***********************************************************************/
2015
2016 /*
2017  *      Called with the proxy mutex held
2018  */
2019 static void remove_from_proxy_hash_nl(REQUEST *request, bool yank)
2020 {
2021         VERIFY_REQUEST(request);
2022
2023         if (!request->in_proxy_hash) return;
2024
2025         fr_packet_list_id_free(proxy_list, request->proxy, yank);
2026         request->in_proxy_hash = false;
2027
2028         /*
2029          *      On the FIRST reply, decrement the count of outstanding
2030          *      requests.  Note that this is NOT the count of sent
2031          *      packets, but whether or not the home server has
2032          *      responded at all.
2033          */
2034         if (request->home_server &&
2035             request->home_server->currently_outstanding) {
2036                 request->home_server->currently_outstanding--;
2037
2038                 /*
2039                  *      If we're NOT sending it packets, then we don't know
2040                  *      if it's alive or dead.
2041                  */
2042                 if ((request->home_server->currently_outstanding == 0) &&
2043                     (request->home_server->state == HOME_STATE_ALIVE)) {
2044                         request->home_server->state = HOME_STATE_UNKNOWN;
2045                         request->home_server->last_packet_sent = 0;
2046                         request->home_server->last_packet_recv = 0;
2047                 }
2048         }
2049
2050 #ifdef WITH_TCP
2051         rad_assert(request->proxy_listener != NULL);
2052         request->proxy_listener->count--;
2053 #endif
2054         request->proxy_listener = NULL;
2055
2056         /*
2057          *      Got from YES in hash, to NO, not in hash while we hold
2058          *      the mutex.  This guarantees that when another thread
2059          *      grabs the mutex, the "not in hash" flag is correct.
2060          */
2061         RDEBUG3("proxy: request is no longer in proxy hash");
2062 }
2063
2064 static void remove_from_proxy_hash(REQUEST *request)
2065 {
2066         VERIFY_REQUEST(request);
2067
2068         /*
2069          *      Check this without grabbing the mutex because it's a
2070          *      lot faster that way.
2071          */
2072         if (!request->in_proxy_hash) return;
2073
2074         /*
2075          *      The "not in hash" flag is definitive.  However, if the
2076          *      flag says that it IS in the hash, there might still be
2077          *      a race condition where it isn't.
2078          */
2079         PTHREAD_MUTEX_LOCK(&proxy_mutex);
2080
2081         if (!request->in_proxy_hash) {
2082                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2083                 return;
2084         }
2085
2086         remove_from_proxy_hash_nl(request, true);
2087
2088         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2089 }
2090
2091 static int insert_into_proxy_hash(REQUEST *request)
2092 {
2093         char buf[128];
2094         int rcode, tries;
2095         void *proxy_listener;
2096
2097         VERIFY_REQUEST(request);
2098
2099         rad_assert(request->proxy != NULL);
2100         rad_assert(request->home_server != NULL);
2101         rad_assert(proxy_list != NULL);
2102
2103
2104         PTHREAD_MUTEX_LOCK(&proxy_mutex);
2105         proxy_listener = NULL;
2106         request->num_proxied_requests = 1;
2107         request->num_proxied_responses = 0;
2108
2109         for (tries = 0; tries < 2; tries++) {
2110                 rad_listen_t *this;
2111                 listen_socket_t *sock;
2112
2113                 RDEBUG3("proxy: Trying to allocate ID (%d/2)", tries);
2114                 rcode = fr_packet_list_id_alloc(proxy_list,
2115                                                 request->home_server->proto,
2116                                                 &request->proxy, &proxy_listener);
2117                 if ((debug_flag > 2) && (rcode == 0)) {
2118                         RDEBUG("proxy: Failed allocating ID: %s", fr_strerror());
2119                 }
2120                 if (rcode > 0) break;
2121                 if (tries > 0) continue; /* try opening new socket only once */
2122
2123 #ifdef HAVE_PTHREAD_H
2124                 if (proxy_no_new_sockets) break;
2125 #endif
2126
2127                 RDEBUG3("proxy: Trying to open a new listener to the home server");
2128                 this = proxy_new_listener(request->home_server, 0);
2129                 if (!this) {
2130                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2131                         goto fail;
2132                 }
2133
2134                 request->proxy->src_port = 0; /* Use any new socket */
2135                 proxy_listener = this;
2136
2137                 sock = this->data;
2138                 if (!fr_packet_list_socket_add(proxy_list, this->fd,
2139                                                sock->proto,
2140                                                &sock->other_ipaddr, sock->other_port,
2141                                                this)) {
2142
2143 #ifdef HAVE_PTHREAD_H
2144                         proxy_no_new_sockets = true;
2145 #endif
2146                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2147
2148                         /*
2149                          *      This is bad.  However, the
2150                          *      packet list now supports 256
2151                          *      open sockets, which should
2152                          *      minimize this problem.
2153                          */
2154                         ERROR("Failed adding proxy socket: %s",
2155                               fr_strerror());
2156                         goto fail;
2157                 }
2158
2159                 /*
2160                  *      Add it to the event loop.  Ensure that we have
2161                  *      only one mutex locked at a time.
2162                  */
2163                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2164                 radius_update_listener(this);
2165                 PTHREAD_MUTEX_LOCK(&proxy_mutex);
2166         }
2167
2168         if (!proxy_listener || (rcode == 0)) {
2169                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2170                 REDEBUG2("proxy: Failed allocating Id for proxied request");
2171         fail:
2172                 request->proxy_listener = NULL;
2173                 request->in_proxy_hash = false;
2174                 return 0;
2175         }
2176
2177         rad_assert(request->proxy->id >= 0);
2178
2179         request->proxy_listener = proxy_listener;
2180         request->in_proxy_hash = true;
2181         RDEBUG3("proxy: request is now in proxy hash");
2182
2183         /*
2184          *      Keep track of maximum outstanding requests to a
2185          *      particular home server.  'max_outstanding' is
2186          *      enforced in home_server_ldb(), in realms.c.
2187          */
2188         request->home_server->currently_outstanding++;
2189
2190 #ifdef WITH_TCP
2191         request->proxy_listener->count++;
2192 #endif
2193
2194         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2195
2196         RDEBUG3("proxy: allocating destination %s port %d - Id %d",
2197                inet_ntop(request->proxy->dst_ipaddr.af,
2198                          &request->proxy->dst_ipaddr.ipaddr, buf, sizeof(buf)),
2199                request->proxy->dst_port,
2200                request->proxy->id);
2201
2202         return 1;
2203 }
2204
2205 static int process_proxy_reply(REQUEST *request, RADIUS_PACKET *reply)
2206 {
2207         int rcode;
2208         int post_proxy_type = 0;
2209         VALUE_PAIR *vp;
2210
2211         VERIFY_REQUEST(request);
2212
2213         /*
2214          *      There may be a proxy reply, but it may be too late.
2215          */
2216         if (!request->proxy_listener) return 0;
2217
2218         /*
2219          *      Delete any reply we had accumulated until now.
2220          */
2221         pairfree(&request->reply->vps);
2222
2223         /*
2224          *      Run the packet through the post-proxy stage,
2225          *      BEFORE playing games with the attributes.
2226          */
2227         vp = pairfind(request->config_items, PW_POST_PROXY_TYPE, 0, TAG_ANY);
2228
2229         /*
2230          *      If we have a proxy_reply, and it was a reject, setup
2231          *      post-proxy-type Reject
2232          */
2233         if (!vp && reply &&
2234             reply->code == PW_CODE_ACCESS_REJECT) {
2235                 DICT_VALUE      *dval;
2236
2237                 dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Reject");
2238                 if (dval) {
2239                         vp = radius_paircreate(request, &request->config_items,
2240                                                PW_POST_PROXY_TYPE, 0);
2241
2242                         vp->vp_integer = dval->value;
2243                 }
2244         }
2245
2246         if (vp) {
2247                 post_proxy_type = vp->vp_integer;
2248
2249                 RDEBUG2("Found Post-Proxy-Type %s", dict_valnamebyattr(PW_POST_PROXY_TYPE, 0, post_proxy_type));
2250         }
2251
2252         if (reply) {
2253                 VERIFY_PACKET(reply);
2254                 /*
2255                  *      Decode the packet.
2256                  */
2257                 rcode = request->proxy_listener->decode(request->proxy_listener, request);
2258                 DEBUG_PACKET(request, reply, 0);
2259
2260                 /*
2261                  *      Pro-actively remove it from the proxy hash.
2262                  *      This is later than in 2.1.x, but it means that
2263                  *      the replies are authenticated before being
2264                  *      removed from the hash.
2265                  */
2266                 if ((rcode == 0) &&
2267                     (request->num_proxied_requests <= request->num_proxied_responses)) {
2268                         remove_from_proxy_hash(request);
2269                 }
2270         } else {
2271                 remove_from_proxy_hash(request);
2272         }
2273
2274         if (request->home_pool && request->home_pool->virtual_server) {
2275                 char const *old_server = request->server;
2276
2277                 request->server = request->home_pool->virtual_server;
2278                 RDEBUG2("server %s {", request->server);
2279                 RINDENT();
2280                 rcode = process_post_proxy(post_proxy_type, request);
2281                 REXDENT();
2282                 RDEBUG2("}");
2283                 request->server = old_server;
2284         } else {
2285                 rcode = process_post_proxy(post_proxy_type, request);
2286         }
2287
2288 #ifdef WITH_COA
2289         if (request->packet->code == request->proxy->code)
2290           /*
2291            *    Don't run the next bit if we originated a CoA
2292            *    packet, after receiving an Access-Request or
2293            *    Accounting-Request.
2294            */
2295 #endif
2296
2297         /*
2298          *      There may NOT be a proxy reply, as we may be
2299          *      running Post-Proxy-Type = Fail.
2300          */
2301         if (reply) {
2302                 pairadd(&request->reply->vps, paircopy(request->reply, reply->vps));
2303
2304                 /*
2305                  *      Delete the Proxy-State Attributes from
2306                  *      the reply.  These include Proxy-State
2307                  *      attributes from us and remote server.
2308                  */
2309                 pairdelete(&request->reply->vps, PW_PROXY_STATE, 0, TAG_ANY);
2310         }
2311
2312         switch (rcode) {
2313         default:  /* Don't do anything */
2314                 break;
2315         case RLM_MODULE_FAIL:
2316                 return 0;
2317
2318         case RLM_MODULE_HANDLED:
2319                 return 0;
2320         }
2321
2322         return 1;
2323 }
2324
2325 int request_proxy_reply(RADIUS_PACKET *packet)
2326 {
2327         RADIUS_PACKET **proxy_p;
2328         REQUEST *request;
2329         struct timeval now;
2330         char buffer[128];
2331
2332         VERIFY_PACKET(packet);
2333
2334         PTHREAD_MUTEX_LOCK(&proxy_mutex);
2335         proxy_p = fr_packet_list_find_byreply(proxy_list, packet);
2336
2337         if (!proxy_p) {
2338                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2339                 PROXY( "No outstanding request was found for reply from host %s port %d - ID %u",
2340                        inet_ntop(packet->src_ipaddr.af,
2341                                  &packet->src_ipaddr.ipaddr,
2342                                  buffer, sizeof(buffer)),
2343                        packet->src_port, packet->id);
2344                 return 0;
2345         }
2346
2347         request = fr_packet2myptr(REQUEST, proxy, proxy_p);
2348         request->num_proxied_responses++; /* needs to be protected by lock */
2349
2350         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2351
2352         /*
2353          *      No reply, BUT the current packet fails verification:
2354          *      ignore it.  This does the MD5 calculations in the
2355          *      server core, but I guess we can fix that later.
2356          */
2357         if (!request->proxy_reply &&
2358             (rad_verify(packet, request->proxy,
2359                         request->home_server->secret) != 0)) {
2360                 DEBUG("Ignoring spoofed proxy reply.  Signature is invalid");
2361                 return 0;
2362         }
2363
2364         /*
2365          *      The home server sent us a packet which doesn't match
2366          *      something we have: ignore it.  This is done only to
2367          *      catch the case of broken systems.
2368          */
2369         if (request->proxy_reply &&
2370             (memcmp(request->proxy_reply->vector,
2371                     packet->vector,
2372                     sizeof(request->proxy_reply->vector)) != 0)) {
2373                 RDEBUG2("Ignoring conflicting proxy reply");
2374                 return 0;
2375         }
2376
2377         gettimeofday(&now, NULL);
2378
2379         /*
2380          *      Status-Server packets don't count as real packets.
2381          */
2382         if (request->proxy->code != PW_CODE_STATUS_SERVER) {
2383                 listen_socket_t *sock = request->proxy_listener->data;
2384
2385                 request->home_server->last_packet_recv = now.tv_sec;
2386                 sock->last_packet = now.tv_sec;
2387         }
2388
2389         /*
2390          *      If we have previously seen a reply, ignore the
2391          *      duplicate.
2392          */
2393         if (request->proxy_reply) {
2394                 RDEBUG2("Discarding duplicate reply from host %s port %d  - ID: %d",
2395                         inet_ntop(packet->src_ipaddr.af,
2396                                   &packet->src_ipaddr.ipaddr,
2397                                   buffer, sizeof(buffer)),
2398                         packet->src_port, packet->id);
2399                 return 0;
2400         }
2401
2402         /*
2403          *      Call the state machine to do something useful with the
2404          *      request.
2405          */
2406         request->proxy_reply = talloc_steal(request, packet);
2407         packet->timestamp = now;
2408         request->priority = RAD_LISTEN_PROXY;
2409
2410         /*
2411          *      We've received a reply.  If we hadn't been sending it
2412          *      packets for a while, just mark it alive.
2413          */
2414         if (request->home_server->state == HOME_STATE_UNKNOWN) {
2415                 request->home_server->state = HOME_STATE_ALIVE;
2416                 request->home_server->response_timeouts = 0;
2417         }
2418
2419 #ifdef WITH_STATS
2420         request->home_server->stats.last_packet = packet->timestamp.tv_sec;
2421         request->proxy_listener->stats.last_packet = packet->timestamp.tv_sec;
2422
2423         if (request->proxy->code == PW_CODE_ACCESS_REQUEST) {
2424                 proxy_auth_stats.last_packet = packet->timestamp.tv_sec;
2425 #ifdef WITH_ACCOUNTING
2426         } else if (request->proxy->code == PW_CODE_ACCOUNTING_REQUEST) {
2427                 proxy_acct_stats.last_packet = packet->timestamp.tv_sec;
2428 #endif
2429         }
2430 #endif  /* WITH_STATS */
2431
2432 #ifdef WITH_COA
2433         /*
2434          *      When we originate CoA requests, we patch them in here
2435          *      so that they don't affect the rest of the state
2436          *      machine.
2437          */
2438         if (request->parent) {
2439                 rad_assert(request->parent->coa == request);
2440                 rad_assert((request->proxy->code == PW_CODE_COA_REQUEST) ||
2441                            (request->proxy->code == PW_CODE_DISCONNECT_REQUEST));
2442                 rad_assert(request->process != NULL);
2443                 request_coa_separate(request);
2444         }
2445 #endif
2446
2447         request->process(request, FR_ACTION_PROXY_REPLY);
2448
2449         return 1;
2450 }
2451
2452
2453 static int setup_post_proxy_fail(REQUEST *request)
2454 {
2455         DICT_VALUE const *dval = NULL;
2456         VALUE_PAIR *vp;
2457
2458         VERIFY_REQUEST(request);
2459
2460         if (request->proxy->code == PW_CODE_ACCESS_REQUEST) {
2461                 dval = dict_valbyname(PW_POST_PROXY_TYPE, 0,
2462                                       "Fail-Authentication");
2463
2464         } else if (request->proxy->code == PW_CODE_ACCOUNTING_REQUEST) {
2465                 dval = dict_valbyname(PW_POST_PROXY_TYPE, 0,
2466                                       "Fail-Accounting");
2467 #ifdef WITH_COA
2468         } else if (request->proxy->code == PW_CODE_COA_REQUEST) {
2469                 dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail-CoA");
2470
2471         } else if (request->proxy->code == PW_CODE_DISCONNECT_REQUEST) {
2472                 dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail-Disconnect");
2473 #endif
2474         } else {
2475                 WARN("Unknown packet type in Post-Proxy-Type Fail: ignoring");
2476                 return 0;
2477         }
2478
2479         if (!dval) dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail");
2480
2481         if (!dval) {
2482                 pairdelete(&request->config_items, PW_POST_PROXY_TYPE, 0, TAG_ANY);
2483                 return 0;
2484         }
2485
2486         vp = pairfind(request->config_items, PW_POST_PROXY_TYPE, 0, TAG_ANY);
2487         if (!vp) vp = radius_paircreate(request, &request->config_items,
2488                                         PW_POST_PROXY_TYPE, 0);
2489         vp->vp_integer = dval->value;
2490
2491         return 1;
2492 }
2493
2494 STATE_MACHINE_DECL(proxy_no_reply)
2495 {
2496         VERIFY_REQUEST(request);
2497
2498         TRACE_STATE_MACHINE;
2499
2500         switch (action) {
2501         case FR_ACTION_CONFLICTING:
2502         case FR_ACTION_DUP:
2503         case FR_ACTION_TIMER:
2504         case FR_ACTION_PROXY_REPLY:
2505                 request_common(request, action);
2506                 break;
2507
2508         case FR_ACTION_RUN:
2509                 if (process_proxy_reply(request, NULL)) {
2510                         request_finish(request, action);
2511                 }
2512                 request_done(request, FR_ACTION_DONE);
2513                 break;
2514
2515         default:
2516                 RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
2517                 break;
2518         }
2519 }
2520
2521 STATE_MACHINE_DECL(proxy_running)
2522 {
2523         VERIFY_REQUEST(request);
2524
2525         TRACE_STATE_MACHINE;
2526
2527         switch (action) {
2528         case FR_ACTION_CONFLICTING:
2529         case FR_ACTION_DUP:
2530         case FR_ACTION_TIMER:
2531         case FR_ACTION_PROXY_REPLY:
2532                 request_common(request, action);
2533                 break;
2534
2535         case FR_ACTION_RUN:
2536                 if (process_proxy_reply(request, request->proxy_reply)) {
2537                         request->handle(request);
2538                         request_finish(request, action);
2539                 } else {
2540                         request_done(request, FR_ACTION_DONE);
2541                 }
2542                 break;
2543
2544         default:
2545                 RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
2546                 break;
2547         }
2548 }
2549
2550 static int request_will_proxy(REQUEST *request)
2551 {
2552         int rcode, pre_proxy_type = 0;
2553         char const *realmname = NULL;
2554         VALUE_PAIR *vp, *strippedname;
2555         home_server_t *home;
2556         REALM *realm = NULL;
2557         home_pool_t *pool = NULL;
2558
2559         VERIFY_REQUEST(request);
2560
2561         if (!request->root->proxy_requests) return 0;
2562         if (request->packet->dst_port == 0) return 0;
2563         if (request->packet->code == PW_CODE_STATUS_SERVER) return 0;
2564         if (request->in_proxy_hash) return 0;
2565
2566         /*
2567          *      FIXME: for 3.0, allow this only for rejects?
2568          */
2569         if (request->reply->code != 0) return 0;
2570
2571         vp = pairfind(request->config_items, PW_PROXY_TO_REALM, 0, TAG_ANY);
2572         if (vp) {
2573                 realm = realm_find2(vp->vp_strvalue);
2574                 if (!realm) {
2575                         REDEBUG2("Cannot proxy to unknown realm %s",
2576                                 vp->vp_strvalue);
2577                         return 0;
2578                 }
2579
2580                 realmname = vp->vp_strvalue;
2581
2582                 /*
2583                  *      Figure out which pool to use.
2584                  */
2585                 if (request->packet->code == PW_CODE_ACCESS_REQUEST) {
2586                         pool = realm->auth_pool;
2587
2588 #ifdef WITH_ACCOUNTING
2589                 } else if (request->packet->code == PW_CODE_ACCOUNTING_REQUEST) {
2590                         pool = realm->acct_pool;
2591 #endif
2592
2593 #ifdef WITH_COA
2594                 } else if ((request->packet->code == PW_CODE_COA_REQUEST) ||
2595                            (request->packet->code == PW_CODE_DISCONNECT_REQUEST)) {
2596                         pool = realm->coa_pool;
2597 #endif
2598
2599                 } else {
2600                         return 0;
2601                 }
2602
2603         } else {
2604                 int pool_type;
2605
2606                 vp = pairfind(request->config_items, PW_HOME_SERVER_POOL, 0, TAG_ANY);
2607                 if (!vp) return 0;
2608
2609                 switch (request->packet->code) {
2610                 case PW_CODE_ACCESS_REQUEST:
2611                         pool_type = HOME_TYPE_AUTH;
2612                         break;
2613
2614 #ifdef WITH_ACCOUNTING
2615                 case PW_CODE_ACCOUNTING_REQUEST:
2616                         pool_type = HOME_TYPE_ACCT;
2617                         break;
2618 #endif
2619
2620 #ifdef WITH_COA
2621                 case PW_CODE_COA_REQUEST:
2622                 case PW_CODE_DISCONNECT_REQUEST:
2623                         pool_type = HOME_TYPE_COA;
2624                         break;
2625 #endif
2626
2627                 default:
2628                         return 0;
2629                 }
2630
2631                 pool = home_pool_byname(vp->vp_strvalue, pool_type);
2632         }
2633
2634         if (!pool) {
2635                 RWDEBUG2("Cancelling proxy as no home pool exists");
2636                 return 0;
2637         }
2638
2639         if (request->listener->synchronous) {
2640                 WARN("Cannot proxy a request which is from a 'synchronous' socket");
2641                 return 0;
2642         }
2643
2644         request->home_pool = pool;
2645
2646         home = home_server_ldb(realmname, pool, request);
2647         if (!home) {
2648                 REDEBUG2("Failed to find live home server: Cancelling proxy");
2649                 return 0;
2650         }
2651         home_server_update_request(home, request);
2652
2653 #ifdef WITH_COA
2654         /*
2655          *      Once we've decided to proxy a request, we cannot send
2656          *      a CoA packet.  So we free up any CoA packet here.
2657          */
2658         if (request->coa) request_done(request->coa, FR_ACTION_DONE);
2659 #endif
2660
2661         /*
2662          *      Remember that we sent the request to a Realm.
2663          */
2664         if (realmname) pairmake_packet("Realm", realmname, T_OP_EQ);
2665
2666         /*
2667          *      Strip the name, if told to.
2668          *
2669          *      Doing it here catches the case of proxied tunneled
2670          *      requests.
2671          */
2672         if (realm && (realm->striprealm == true) &&
2673            (strippedname = pairfind(request->proxy->vps, PW_STRIPPED_USER_NAME, 0, TAG_ANY)) != NULL) {
2674                 /*
2675                  *      If there's a Stripped-User-Name attribute in
2676                  *      the request, then use THAT as the User-Name
2677                  *      for the proxied request, instead of the
2678                  *      original name.
2679                  *
2680                  *      This is done by making a copy of the
2681                  *      Stripped-User-Name attribute, turning it into
2682                  *      a User-Name attribute, deleting the
2683                  *      Stripped-User-Name and User-Name attributes
2684                  *      from the vps list, and making the new
2685                  *      User-Name the head of the vps list.
2686                  */
2687                 vp = pairfind(request->proxy->vps, PW_USER_NAME, 0, TAG_ANY);
2688                 if (!vp) {
2689                         vp_cursor_t cursor;
2690                         vp = radius_paircreate(NULL, NULL,
2691                                                PW_USER_NAME, 0);
2692                         rad_assert(vp != NULL); /* handled by above function */
2693                         /* Insert at the START of the list */
2694                         /* FIXME: Can't make assumptions about ordering */
2695                         fr_cursor_init(&cursor, &vp);
2696                         fr_cursor_insert(&cursor, request->proxy->vps);
2697                         request->proxy->vps = vp;
2698                 }
2699                 pairstrcpy(vp, strippedname->vp_strvalue);
2700
2701                 /*
2702                  *      Do NOT delete Stripped-User-Name.
2703                  */
2704         }
2705
2706         /*
2707          *      If there is no PW_CHAP_CHALLENGE attribute but
2708          *      there is a PW_CHAP_PASSWORD we need to add it
2709          *      since we can't use the request authenticator
2710          *      anymore - we changed it.
2711          */
2712         if ((request->packet->code == PW_CODE_ACCESS_REQUEST) &&
2713             pairfind(request->proxy->vps, PW_CHAP_PASSWORD, 0, TAG_ANY) &&
2714             pairfind(request->proxy->vps, PW_CHAP_CHALLENGE, 0, TAG_ANY) == NULL) {
2715                 vp = radius_paircreate(request->proxy, &request->proxy->vps, PW_CHAP_CHALLENGE, 0);
2716                 pairmemcpy(vp, request->packet->vector, sizeof(request->packet->vector));
2717         }
2718
2719         /*
2720          *      The RFC's say we have to do this, but FreeRADIUS
2721          *      doesn't need it.
2722          */
2723         vp = radius_paircreate(request->proxy, &request->proxy->vps, PW_PROXY_STATE, 0);
2724         pairsprintf(vp, "%u", request->packet->id);
2725
2726         /*
2727          *      Should be done BEFORE inserting into proxy hash, as
2728          *      pre-proxy may use this information, or change it.
2729          */
2730         request->proxy->code = request->packet->code;
2731
2732         /*
2733          *      Call the pre-proxy routines.
2734          */
2735         vp = pairfind(request->config_items, PW_PRE_PROXY_TYPE, 0, TAG_ANY);
2736         if (vp) {
2737                 DICT_VALUE const *dval = dict_valbyattr(vp->da->attr, vp->da->vendor, vp->vp_integer);
2738                 /* Must be a validation issue */
2739                 rad_assert(dval);
2740                 RDEBUG2("Found Pre-Proxy-Type %s", dval->name);
2741                 pre_proxy_type = vp->vp_integer;
2742         }
2743
2744         rad_assert(request->home_pool != NULL);
2745
2746         if (request->home_pool->virtual_server) {
2747                 char const *old_server = request->server;
2748
2749                 request->server = request->home_pool->virtual_server;
2750
2751                 RDEBUG2("server %s {", request->server);
2752                 RINDENT();
2753                 rcode = process_pre_proxy(pre_proxy_type, request);
2754                 REXDENT();
2755                 RDEBUG2("}");
2756
2757                 request->server = old_server;
2758         } else {
2759                 rcode = process_pre_proxy(pre_proxy_type, request);
2760         }
2761         switch (rcode) {
2762         case RLM_MODULE_FAIL:
2763         case RLM_MODULE_INVALID:
2764         case RLM_MODULE_NOTFOUND:
2765         case RLM_MODULE_USERLOCK:
2766         default:
2767                 /* FIXME: debug print failed stuff */
2768                 return -1;
2769
2770         case RLM_MODULE_REJECT:
2771         case RLM_MODULE_HANDLED:
2772                 return 0;
2773
2774         /*
2775          *      Only proxy the packet if the pre-proxy code succeeded.
2776          */
2777         case RLM_MODULE_NOOP:
2778         case RLM_MODULE_OK:
2779         case RLM_MODULE_UPDATED:
2780                 break;
2781         }
2782
2783         return 1;
2784 }
2785
2786 static int request_proxy(REQUEST *request, int retransmit)
2787 {
2788         char buffer[128];
2789
2790         VERIFY_REQUEST(request);
2791
2792         rad_assert(request->parent == NULL);
2793         rad_assert(request->home_server != NULL);
2794
2795         if (request->master_state == REQUEST_STOP_PROCESSING) return 0;
2796
2797 #ifdef WITH_COA
2798         if (request->coa) {
2799                 RWDEBUG("Cannot proxy and originate CoA packets at the same time.  Cancelling CoA request");
2800                 request_done(request->coa, FR_ACTION_DONE);
2801         }
2802 #endif
2803
2804         /*
2805          *      The request may need sending to a virtual server.
2806          *      This code is more than a little screwed up.  The rest
2807          *      of the state machine doesn't handle parent / child
2808          *      relationships well.  i.e. if the child request takes
2809          *      too long, the core will mark the *parent* as "stop
2810          *      processing".  And the child will continue without
2811          *      knowing anything...
2812          *
2813          *      So, we have some horrible hacks to get around that.
2814          */
2815         if (request->home_server->server) {
2816                 REQUEST *fake;
2817
2818                 if (request->packet->dst_port == 0) {
2819                         WARN("Cannot proxy an internal request");
2820                         return 0;
2821                 }
2822
2823                 DEBUG("Proxying to virtual server %s",
2824                       request->home_server->server);
2825
2826                 /*
2827                  *      Packets to virtual serrers don't get
2828                  *      retransmissions sent to them.  And the virtual
2829                  *      server is run ONLY if we have no child
2830                  *      threads, or we're running in a child thread.
2831                  */
2832                 rad_assert(retransmit == 0);
2833                 rad_assert(!spawn_flag || !we_are_master());
2834
2835                 fake = request_alloc_fake(request);
2836
2837                 fake->packet->vps = paircopy(fake->packet, request->packet->vps);
2838                 talloc_free(request->proxy);
2839
2840                 fake->server = request->home_server->server;
2841                 fake->handle = request->handle;
2842                 fake->process = NULL; /* should never be run for anything */
2843
2844                 /*
2845                  *      Run the virtual server.
2846                  */
2847                 request_running(fake, FR_ACTION_RUN);
2848
2849                 request->proxy = talloc_steal(request, fake->packet);
2850                 fake->packet = NULL;
2851                 request->proxy_reply = talloc_steal(request, fake->reply);
2852                 fake->reply = NULL;
2853
2854                 talloc_free(fake);
2855
2856                 /*
2857                  *      Just do the work here, rather than trying to
2858                  *      run the "decode proxy reply" stuff...
2859                  */
2860                 process_proxy_reply(request, request->proxy_reply);
2861
2862                 request->handle(request); /* to do more post-proxy stuff */
2863
2864                 return -1;      /* so we call request_finish */
2865         }
2866
2867         /*
2868          *      We're actually sending a proxied packet.  Do that now.
2869          */
2870         if (!request->in_proxy_hash && !insert_into_proxy_hash(request)) {
2871                 ERROR("Failed to insert request into the proxy list");
2872                 return -1;
2873         }
2874
2875         rad_assert(request->proxy->id >= 0);
2876
2877         if (debug_flag) {
2878                 struct timeval *response_window;
2879
2880                 response_window = request_response_window(request);
2881
2882 #ifdef WITH_TLS
2883                 if (request->home_server->tls) {
2884                         RDEBUG2("Proxying request to home server %s port %d (TLS) timeout %d.%06d",
2885                                 inet_ntop(request->proxy->dst_ipaddr.af,
2886                                           &request->proxy->dst_ipaddr.ipaddr,
2887                                           buffer, sizeof(buffer)),
2888                                 request->proxy->dst_port,
2889                                 (int) response_window->tv_sec, (int) response_window->tv_usec);
2890                 } else
2891 #endif
2892                         RDEBUG2("Proxying request to home server %s port %d timeout %d.%06d",
2893                                 inet_ntop(request->proxy->dst_ipaddr.af,
2894                                           &request->proxy->dst_ipaddr.ipaddr,
2895                                           buffer, sizeof(buffer)),
2896                                 request->proxy->dst_port,
2897                                 (int) response_window->tv_sec, (int) response_window->tv_usec);
2898
2899                 DEBUG_PACKET(request, request->proxy, 1);
2900         }
2901
2902         gettimeofday(&request->proxy_retransmit, NULL);
2903         if (!retransmit) {
2904                 request->proxy->timestamp = request->proxy_retransmit;
2905                 request->home_server->last_packet_sent = request->proxy_retransmit.tv_sec;
2906         }
2907
2908         FR_STATS_TYPE_INC(request->home_server->stats.total_requests);
2909         NO_CHILD_THREAD;
2910         request->child_state = REQUEST_PROXIED;
2911         request->proxy_listener->send(request->proxy_listener,
2912                                       request);
2913         return 1;
2914 }
2915
2916 /*
2917  *      Proxy the packet as if it was new.
2918  */
2919 static int request_proxy_anew(REQUEST *request)
2920 {
2921         home_server_t *home;
2922
2923         VERIFY_REQUEST(request);
2924
2925         /*
2926          *      Delete the request from the proxy list.
2927          *
2928          *      The packet list code takes care of ensuring that IDs
2929          *      aren't reused until all 256 IDs have been used.  So
2930          *      there's a 1/256 chance of re-using the same ID when
2931          *      we're sending to the same home server.  Which is
2932          *      acceptable.
2933          */
2934         remove_from_proxy_hash(request);
2935
2936         /*
2937          *      Find a live home server for the request.
2938          */
2939         home = home_server_ldb(NULL, request->home_pool, request);
2940         if (!home) {
2941                 REDEBUG2("Failed to find live home server for request");
2942         post_proxy_fail:
2943                 if (setup_post_proxy_fail(request)) {
2944                         request_queue_or_run(request, proxy_running);
2945                 } else {
2946                         gettimeofday(&request->reply->timestamp, NULL);
2947                         request_cleanup_delay_init(request, NULL);
2948                 }
2949                 return 0;
2950         }
2951         home_server_update_request(home, request);
2952
2953         if (!insert_into_proxy_hash(request)) {
2954                 RPROXY("Failed to insert retransmission into the proxy list");
2955                 goto post_proxy_fail;
2956         }
2957
2958         /*
2959          *      Free the old packet, to force re-encoding
2960          */
2961         talloc_free(request->proxy->data);
2962         request->proxy->data = NULL;
2963         request->proxy->data_len = 0;
2964
2965 #ifdef WITH_ACCOUNTING
2966         /*
2967          *      Update the Acct-Delay-Time attribute.
2968          */
2969         if (request->packet->code == PW_CODE_ACCOUNTING_REQUEST) {
2970                 VALUE_PAIR *vp;
2971
2972                 vp = pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME, 0, TAG_ANY);
2973                 if (!vp) vp = radius_paircreate(request->proxy,
2974                                                 &request->proxy->vps,
2975                                                 PW_ACCT_DELAY_TIME, 0);
2976                 if (vp) {
2977                         struct timeval now;
2978
2979                         gettimeofday(&now, NULL);
2980                         vp->vp_integer += now.tv_sec - request->proxy_retransmit.tv_sec;
2981                 }
2982         }
2983 #endif
2984
2985         if (request_proxy(request, 1) != 1) goto post_proxy_fail;
2986
2987         return 1;
2988 }
2989
2990 STATE_MACHINE_DECL(request_ping)
2991 {
2992         home_server_t *home = request->home_server;
2993         char buffer[128];
2994
2995         VERIFY_REQUEST(request);
2996
2997         TRACE_STATE_MACHINE;
2998         ASSERT_MASTER;
2999
3000         switch (action) {
3001         case FR_ACTION_TIMER:
3002                 ERROR("No response to status check %d for home server %s port %d",
3003                        request->number,
3004                        inet_ntop(request->proxy->dst_ipaddr.af,
3005                                  &request->proxy->dst_ipaddr.ipaddr,
3006                                  buffer, sizeof(buffer)),
3007                        request->proxy->dst_port);
3008                 break;
3009
3010         case FR_ACTION_PROXY_REPLY:
3011                 rad_assert(request->in_proxy_hash);
3012
3013                 request->home_server->num_received_pings++;
3014                 RPROXY("Received response to status check %d (%d in current sequence)",
3015                        request->number, home->num_received_pings);
3016
3017                 /*
3018                  *      Remove the request from any hashes
3019                  */
3020                 fr_event_delete(el, &request->ev);
3021                 remove_from_proxy_hash(request);
3022
3023                 /*
3024                  *      The control socket may have marked the home server as
3025                  *      alive.  OR, it may have suddenly started responding to
3026                  *      requests again.  If so, don't re-do the "make alive"
3027                  *      work.
3028                  */
3029                 if (home->state == HOME_STATE_ALIVE) break;
3030
3031                 /*
3032                  *      It's dead, and we haven't received enough ping
3033                  *      responses to mark it "alive".  Wait a bit.
3034                  *
3035                  *      If it's zombie, we mark it alive immediately.
3036                  */
3037                 if ((home->state == HOME_STATE_IS_DEAD) &&
3038                     (home->num_received_pings < home->num_pings_to_alive)) {
3039                         return;
3040                 }
3041
3042                 /*
3043                  *      Mark it alive and delete any outstanding
3044                  *      pings.
3045                  */
3046                 home->state = HOME_STATE_ALIVE;
3047                 home->response_timeouts = 0;
3048                 exec_trigger(request, home->cs, "home_server.alive", false);
3049                 home->currently_outstanding = 0;
3050                 home->num_sent_pings = 0;
3051                 home->num_received_pings = 0;
3052                 gettimeofday(&home->revive_time, NULL);
3053
3054                 fr_event_delete(el, &home->ev);
3055
3056                 RPROXY("Marking home server %s port %d alive",
3057                        inet_ntop(request->proxy->dst_ipaddr.af,
3058                                  &request->proxy->dst_ipaddr.ipaddr,
3059                                  buffer, sizeof(buffer)),
3060                        request->proxy->dst_port);
3061                 break;
3062
3063         default:
3064                 RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
3065                 break;
3066         }
3067
3068         rad_assert(!request->in_request_hash);
3069         rad_assert(request->ev == NULL);
3070         request_done(request, FR_ACTION_DONE);
3071 }
3072
3073 /*
3074  *      Called from start of zombie period, OR after control socket
3075  *      marks the home server dead.
3076  */
3077 static void ping_home_server(void *ctx)
3078 {
3079         home_server_t *home = talloc_get_type_abort(ctx, home_server_t);
3080         REQUEST *request;
3081         VALUE_PAIR *vp;
3082         struct timeval when, now;
3083
3084         if ((home->state == HOME_STATE_ALIVE) ||
3085 #ifdef WITH_TCP
3086             (home->proto == IPPROTO_TCP) ||
3087 #endif
3088             (home->ev != NULL)) {
3089                 return;
3090         }
3091
3092         gettimeofday(&now, NULL);
3093
3094         /*
3095          *      We've run out of zombie time.  Mark it dead.
3096          */
3097         if (home->state == HOME_STATE_ZOMBIE) {
3098                 when = home->zombie_period_start;
3099                 when.tv_sec += home->zombie_period;
3100
3101                 if (timercmp(&when, &now, <)) {
3102                         DEBUG("PING: Zombie period is over for home server %s",
3103                                 home->name);
3104                         mark_home_server_dead(home, &now);
3105                 }
3106         }
3107
3108         /*
3109          *      We're not supposed to be pinging it.  Just wake up
3110          *      when we're supposed to mark it dead.
3111          */
3112         if (home->ping_check == HOME_PING_CHECK_NONE) {
3113                 if (home->state == HOME_STATE_ZOMBIE) {
3114                         when = home->zombie_period_start;
3115                         when.tv_sec += home->zombie_period;
3116                         INSERT_EVENT(ping_home_server, home);
3117                 }
3118
3119                 /*
3120                  *      Else mark_home_server_dead will set a timer
3121                  *      for revive_interval.
3122                  */
3123                 return;
3124         }
3125
3126
3127         request = request_alloc(NULL);
3128         request->number = request_num_counter++;
3129         NO_CHILD_THREAD;
3130
3131         request->proxy = rad_alloc(request, true);
3132         rad_assert(request->proxy != NULL);
3133
3134         if (home->ping_check == HOME_PING_CHECK_STATUS_SERVER) {
3135                 request->proxy->code = PW_CODE_STATUS_SERVER;
3136
3137                 pairmake(request->proxy, &request->proxy->vps,
3138                          "Message-Authenticator", "0x00", T_OP_SET);
3139
3140         } else if (home->type == HOME_TYPE_AUTH) {
3141                 request->proxy->code = PW_CODE_ACCESS_REQUEST;
3142
3143                 pairmake(request->proxy, &request->proxy->vps,
3144                          "User-Name", home->ping_user_name, T_OP_SET);
3145                 pairmake(request->proxy, &request->proxy->vps,
3146                          "User-Password", home->ping_user_password, T_OP_SET);
3147                 pairmake(request->proxy, &request->proxy->vps,
3148                          "Service-Type", "Authenticate-Only", T_OP_SET);
3149                 pairmake(request->proxy, &request->proxy->vps,
3150                          "Message-Authenticator", "0x00", T_OP_SET);
3151
3152         } else {
3153 #ifdef WITH_ACCOUNTING
3154                 request->proxy->code = PW_CODE_ACCOUNTING_REQUEST;
3155
3156                 pairmake(request->proxy, &request->proxy->vps,
3157                          "User-Name", home->ping_user_name, T_OP_SET);
3158                 pairmake(request->proxy, &request->proxy->vps,
3159                          "Acct-Status-Type", "Stop", T_OP_SET);
3160                 pairmake(request->proxy, &request->proxy->vps,
3161                          "Acct-Session-Id", "00000000", T_OP_SET);
3162                 vp = pairmake(request->proxy, &request->proxy->vps,
3163                               "Event-Timestamp", "0", T_OP_SET);
3164                 vp->vp_date = now.tv_sec;
3165 #else
3166                 rad_assert("Internal sanity check failed");
3167 #endif
3168         }
3169
3170         vp = pairmake(request->proxy, &request->proxy->vps,
3171                       "NAS-Identifier", "", T_OP_SET);
3172         if (vp) {
3173                 pairsprintf(vp, "Status Check %u. Are you alive?",
3174                             home->num_sent_pings);
3175         }
3176
3177         request->proxy->src_ipaddr = home->src_ipaddr;
3178         request->proxy->dst_ipaddr = home->ipaddr;
3179         request->proxy->dst_port = home->port;
3180         request->home_server = home;
3181 #ifdef DEBUG_STATE_MACHINE
3182         if (debug_flag) printf("(%u) ********\tSTATE %s C-%s -> C-%s\t********\n", request->number, __FUNCTION__,
3183                                child_state_names[request->child_state],
3184                                child_state_names[REQUEST_DONE]);
3185         if (debug_flag) printf("(%u) ********\tNEXT-STATE %s -> %s\n", request->number, __FUNCTION__, "request_ping");
3186 #endif
3187 #ifdef HAVE_PTHREAD_H
3188         rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
3189 #endif
3190         request->child_state = REQUEST_DONE;
3191         request->process = request_ping;
3192
3193         rad_assert(request->proxy_listener == NULL);
3194
3195         if (!insert_into_proxy_hash(request)) {
3196                 RPROXY("Failed to insert status check %d into proxy list.  Discarding it.",
3197                        request->number);
3198
3199                 rad_assert(!request->in_request_hash);
3200                 rad_assert(!request->in_proxy_hash);
3201                 rad_assert(request->ev == NULL);
3202                 talloc_free(request);
3203                 return;
3204         }
3205
3206         /*
3207          *      Set up the timer callback.
3208          */
3209         when = now;
3210         when.tv_sec += home->ping_timeout;
3211
3212         DEBUG("PING: Waiting %u seconds for response to ping",
3213               home->ping_timeout);
3214
3215         STATE_MACHINE_TIMER(FR_ACTION_TIMER);
3216         home->num_sent_pings++;
3217
3218         rad_assert(request->proxy_listener != NULL);
3219         request->proxy_listener->send(request->proxy_listener,
3220                                       request);
3221
3222         /*
3223          *      Add +/- 2s of jitter, as suggested in RFC 3539
3224          *      and in the Issues and Fixes draft.
3225          */
3226         home->when = now;
3227         home->when.tv_sec += home->ping_interval;
3228
3229         add_jitter(&home->when);
3230
3231         DEBUG("PING: Next status packet in %u seconds", home->ping_interval);
3232         INSERT_EVENT(ping_home_server, home);
3233 }
3234
3235 static void home_trigger(home_server_t *home, char const *trigger)
3236 {
3237         REQUEST my_request;
3238         RADIUS_PACKET my_packet;
3239
3240         memset(&my_request, 0, sizeof(my_request));
3241         memset(&my_packet, 0, sizeof(my_packet));
3242         my_request.proxy = &my_packet;
3243         my_packet.dst_ipaddr = home->ipaddr;
3244         my_packet.src_ipaddr = home->src_ipaddr;
3245
3246         exec_trigger(&my_request, home->cs, trigger, false);
3247 }
3248
3249 static void mark_home_server_zombie(home_server_t *home, struct timeval *now, struct timeval *response_window)
3250 {
3251         time_t start;
3252         char buffer[128];
3253
3254         ASSERT_MASTER;
3255
3256         rad_assert((home->state == HOME_STATE_ALIVE) ||
3257                    (home->state == HOME_STATE_UNKNOWN));
3258
3259 #ifdef WITH_TCP
3260         if (home->proto == IPPROTO_TCP) {
3261                 WARN("Not marking TCP server %s zombie", home->name);
3262                 return;
3263         }
3264 #endif
3265
3266         /*
3267          *      We've received a real packet recently.  Don't mark the
3268          *      server as zombie until we've received NO packets for a
3269          *      while.  The "1/4" of zombie period was chosen rather
3270          *      arbitrarily.  It's a balance between too short, which
3271          *      gives quick fail-over and fail-back, or too long,
3272          *      where the proxy still sends packets to an unresponsive
3273          *      home server.
3274          */
3275         start = now->tv_sec - ((home->zombie_period + 3) / 4);
3276         if (home->last_packet_recv >= start) {
3277                 DEBUG("Recieved reply from home server %d seconds ago.  Might not be zombie.",
3278                       (int) (now->tv_sec - home->last_packet_recv));
3279                 return;
3280         }
3281
3282         home->state = HOME_STATE_ZOMBIE;
3283         home_trigger(home, "home_server.zombie");
3284
3285         /*
3286          *      Set the home server to "zombie", as of the time
3287          *      calculated above.
3288          */
3289         home->zombie_period_start.tv_sec = start;
3290         home->zombie_period_start.tv_usec = USEC / 2;
3291
3292         fr_event_delete(el, &home->ev);
3293         home->num_sent_pings = 0;
3294         home->num_received_pings = 0;
3295
3296         PROXY( "Marking home server %s port %d as zombie (it has not responded in %d.%06d seconds).",
3297                inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
3298                          buffer, sizeof(buffer)),
3299                home->port, (int) response_window->tv_sec, (int) response_window->tv_usec);
3300
3301         ping_home_server(home);
3302 }
3303
3304
3305 void revive_home_server(void *ctx)
3306 {
3307         home_server_t *home = talloc_get_type_abort(ctx, home_server_t);
3308         char buffer[128];
3309
3310 #ifdef WITH_TCP
3311         rad_assert(home->proto != IPPROTO_TCP);
3312 #endif
3313
3314         home->state = HOME_STATE_ALIVE;
3315         home->response_timeouts = 0;
3316         home_trigger(home, "home_server.alive");
3317         home->currently_outstanding = 0;
3318         gettimeofday(&home->revive_time, NULL);
3319
3320         /*
3321          *      Delete any outstanding events.
3322          */
3323         if (home->ev) fr_event_delete(el, &home->ev);
3324
3325         PROXY( "Marking home server %s port %d alive again... we have no idea if it really is alive or not.",
3326                inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
3327                          buffer, sizeof(buffer)),
3328                home->port);
3329 }
3330
3331 void mark_home_server_dead(home_server_t *home, struct timeval *when)
3332 {
3333         int previous_state = home->state;
3334         char buffer[128];
3335
3336 #ifdef WITH_TCP
3337         if (home->proto == IPPROTO_TCP) {
3338                 WARN("Not marking TCP server dead");
3339                 return;
3340         }
3341 #endif
3342
3343         PROXY( "Marking home server %s port %d as dead.",
3344                inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
3345                          buffer, sizeof(buffer)),
3346                home->port);
3347
3348         home->state = HOME_STATE_IS_DEAD;
3349         home_trigger(home, "home_server.dead");
3350
3351         if (home->ping_check != HOME_PING_CHECK_NONE) {
3352                 /*
3353                  *      If the control socket marks us dead, start
3354                  *      pinging.  Otherwise, we already started
3355                  *      pinging when it was marked "zombie".
3356                  */
3357                 if (previous_state == HOME_STATE_ALIVE) {
3358                         ping_home_server(home);
3359                 } else {
3360                         DEBUG("PING: Already pinging home server %s",
3361                               home->name);
3362                 }
3363
3364         } else {
3365                 /*
3366                  *      Revive it after a fixed period of time.  This
3367                  *      is very, very, bad.
3368                  */
3369                 home->when = *when;
3370                 home->when.tv_sec += home->revive_interval;
3371
3372                 DEBUG("PING: Reviving home server %s in %u seconds",
3373                       home->name, home->revive_interval);
3374                 INSERT_EVENT(revive_home_server, home);
3375         }
3376 }
3377
3378 STATE_MACHINE_DECL(proxy_wait_for_reply)
3379 {
3380         struct timeval now, when;
3381         struct timeval *response_window = NULL;
3382         home_server_t *home = request->home_server;
3383         char buffer[128];
3384
3385         VERIFY_REQUEST(request);
3386
3387         TRACE_STATE_MACHINE;
3388
3389         rad_assert(request->packet->code != PW_CODE_STATUS_SERVER);
3390         rad_assert(request->home_server != NULL);
3391
3392         if (request->master_state == REQUEST_STOP_PROCESSING) {
3393                 request->child_state = REQUEST_DONE;
3394                 return;
3395         }
3396
3397         gettimeofday(&now, NULL);
3398
3399         switch (action) {
3400         case FR_ACTION_DUP:
3401                 /*
3402                  *      We have a reply, ignore the retransmit.
3403                  */
3404                 if (request->proxy_reply) return;
3405
3406                 /*
3407                  *      The request was proxied to a virtual server.
3408                  *      Ignore the retransmit.
3409                  */
3410                 if (request->home_server->server) return;
3411
3412                 if ((home->state == HOME_STATE_IS_DEAD) ||
3413                     !request->proxy_listener ||
3414                     (request->proxy_listener->status != RAD_LISTEN_STATUS_KNOWN)) {
3415                         request_proxy_anew(request);
3416                         return;
3417                 }
3418
3419 #ifdef WITH_TCP
3420                 if (home->proto == IPPROTO_TCP) {
3421                         DEBUG2("Suppressing duplicate proxied request (tcp) to home server %s port %d proto TCP - ID: %d",
3422                                inet_ntop(request->proxy->dst_ipaddr.af,
3423                                          &request->proxy->dst_ipaddr.ipaddr,
3424                                          buffer, sizeof(buffer)),
3425                                request->proxy->dst_port,
3426                                request->proxy->id);
3427                         return;
3428                 }
3429 #endif
3430
3431                 /*
3432                  *      More than one retransmit a second is stupid,
3433                  *      and should be suppressed by the proxy.
3434                  */
3435                 when = request->proxy_retransmit;
3436                 when.tv_sec++;
3437
3438                 if (timercmp(&now, &when, <)) {
3439                         DEBUG2("Suppressing duplicate proxied request (too fast) to home server %s port %d proto TCP - ID: %d",
3440                                inet_ntop(request->proxy->dst_ipaddr.af,
3441                                          &request->proxy->dst_ipaddr.ipaddr,
3442                                          buffer, sizeof(buffer)),
3443                                request->proxy->dst_port,
3444                                request->proxy->id);
3445                         return;
3446                 }
3447
3448 #ifdef WITH_ACCOUNTING
3449                 /*
3450                  *      If we update the Acct-Delay-Time, we need to
3451                  *      get a new ID.
3452                  */
3453                 if ((request->packet->code == PW_CODE_ACCOUNTING_REQUEST) &&
3454                     pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME, 0, TAG_ANY)) {
3455                         request_proxy_anew(request);
3456                         return;
3457                 }
3458 #endif
3459
3460                 RDEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
3461                         inet_ntop(request->proxy->dst_ipaddr.af,
3462                                   &request->proxy->dst_ipaddr.ipaddr,
3463                                   buffer, sizeof(buffer)),
3464                         request->proxy->dst_port,
3465                         request->proxy->id);
3466                 request->num_proxied_requests++;
3467
3468                 rad_assert(request->proxy_listener != NULL);;
3469                 DEBUG_PACKET(request, request->proxy, 1);
3470                 FR_STATS_TYPE_INC(home->stats.total_requests);
3471                 home->last_packet_sent = now.tv_sec;
3472                 request->proxy_retransmit = now;
3473                 request->proxy_listener->send(request->proxy_listener,
3474                                               request);
3475                 break;
3476
3477         case FR_ACTION_TIMER:
3478                 response_window = request_response_window(request);
3479
3480 #ifdef WITH_TCP
3481                 if (!request->proxy_listener ||
3482                     (request->proxy_listener->status != RAD_LISTEN_STATUS_KNOWN)) {
3483                         remove_from_proxy_hash(request);
3484
3485                         when = request->packet->timestamp;
3486                         when.tv_sec += request->root->max_request_time;
3487
3488                         if (timercmp(&when, &now, >)) {
3489                                 RDEBUG("Waiting for client retransmission in order to do a proxy retransmit");
3490                                 STATE_MACHINE_TIMER(FR_ACTION_TIMER);
3491                                 return;
3492                         }
3493                 } else
3494 #endif
3495                 {
3496                         /*
3497                          *      Wake up "response_window" time in the future.
3498                          *      i.e. when MY packet hasn't received a response.
3499                          *
3500                          *      Note that we DO NOT mark the home server as
3501                          *      zombie if it doesn't respond to us.  It may be
3502                          *      responding to other (better looking) packets.
3503                          */
3504                         when = request->proxy->timestamp;
3505                         timeradd(&when, response_window, &when);
3506
3507                         /*
3508                          *      Not at the response window.  Set the timer for
3509                          *      that.
3510                          */
3511                         if (timercmp(&when, &now, >)) {
3512                                 struct timeval diff;
3513                                 timersub(&when, &now, &diff);
3514
3515                                 RDEBUG("Expecting proxy response no later than %d.%06d seconds from now",
3516                                        (int) diff.tv_sec, (int) diff.tv_usec);
3517                                 STATE_MACHINE_TIMER(FR_ACTION_TIMER);
3518                                 return;
3519                         }
3520                 }
3521
3522                 RDEBUG("No proxy response, giving up on request and marking it done");
3523
3524                 /*
3525                  *      If we haven't received any packets for
3526                  *      "response_window", then mark the home server
3527                  *      as zombie.
3528                  *
3529                  *      If the connection is TCP, then another
3530                  *      "watchdog timer" function takes care of pings,
3531                  *      etc.  So we don't need to do it here.
3532                  *
3533                  *      This check should really be part of a home
3534                  *      server state machine.
3535                  */
3536                 if (((home->state == HOME_STATE_ALIVE) ||
3537                      (home->state == HOME_STATE_UNKNOWN))
3538 #ifdef WITH_TCP
3539                     && (home->proto != IPPROTO_TCP)
3540 #endif
3541                         ) {
3542                         home->response_timeouts++;
3543                         if (home->response_timeouts >= home->max_response_timeouts)
3544                                 mark_home_server_zombie(home, &now, response_window);
3545                 }
3546
3547                 FR_STATS_TYPE_INC(home->stats.total_timeouts);
3548                 if (home->type == HOME_TYPE_AUTH) {
3549                         if (request->proxy_listener) FR_STATS_TYPE_INC(request->proxy_listener->stats.total_timeouts);
3550                         FR_STATS_TYPE_INC(proxy_auth_stats.total_timeouts);
3551                 }
3552 #ifdef WITH_ACCT
3553                 else if (home->type == HOME_TYPE_ACCT) {
3554                         if (request->proxy_listener) FR_STATS_TYPE_INC(request->proxy_listener->stats.total_timeouts);
3555                         FR_STATS_TYPE_INC(proxy_acct_stats.total_timeouts);
3556                 }
3557 #endif
3558
3559                 /*
3560                  *      There was no response within the window.  Stop
3561                  *      the request.  If the client retransmitted, it
3562                  *      may have failed over to another home server.
3563                  *      But that one may be dead, too.
3564                  */
3565                 RERROR("Failing proxied request, due to lack of any response from home server %s port %d",
3566                                inet_ntop(request->proxy->dst_ipaddr.af,
3567                                          &request->proxy->dst_ipaddr.ipaddr,
3568                                          buffer, sizeof(buffer)),
3569                                request->proxy->dst_port);
3570
3571                 if (setup_post_proxy_fail(request)) {
3572                         request_queue_or_run(request, proxy_no_reply);
3573                 } else {
3574                         gettimeofday(&request->reply->timestamp, NULL);
3575                         request_cleanup_delay_init(request, NULL);
3576                 }
3577                 break;
3578
3579                 /*
3580                  *      Duplicate proxy replies have been quenched by
3581                  *      now.  This state is only called ONCE, when we
3582                  *      receive a new reply from the home server.
3583                  */
3584         case FR_ACTION_PROXY_REPLY:
3585                 request_queue_or_run(request, proxy_running);
3586                 break;
3587
3588         case FR_ACTION_CONFLICTING:
3589                 request_done(request, action);
3590                 return;
3591
3592         default:
3593                 RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
3594                 break;
3595         }
3596 }
3597 #endif  /* WITH_PROXY */
3598
3599 /***********************************************************************
3600  *
3601  *  CoA code
3602  *
3603  ***********************************************************************/
3604 #ifdef WITH_COA
3605 static int null_handler(UNUSED REQUEST *request)
3606 {
3607         return 0;
3608 }
3609
3610 /*
3611  *      See if we need to originate a CoA request.
3612  */
3613 static void request_coa_originate(REQUEST *request)
3614 {
3615         int rcode, pre_proxy_type = 0;
3616         VALUE_PAIR *vp;
3617         REQUEST *coa;
3618         fr_ipaddr_t ipaddr;
3619         char buffer[256];
3620
3621         VERIFY_REQUEST(request);
3622
3623         rad_assert(request->coa != NULL);
3624         rad_assert(request->proxy == NULL);
3625         rad_assert(!request->in_proxy_hash);
3626         rad_assert(request->proxy_reply == NULL);
3627
3628         /*
3629          *      Check whether we want to originate one, or cancel one.
3630          */
3631         vp = pairfind(request->config_items, PW_SEND_COA_REQUEST, 0, TAG_ANY);
3632         if (!vp) {
3633                 vp = pairfind(request->coa->proxy->vps, PW_SEND_COA_REQUEST, 0, TAG_ANY);
3634         }
3635
3636         if (vp) {
3637                 if (vp->vp_integer == 0) {
3638                 fail:
3639                         TALLOC_FREE(request->coa);
3640                         return;
3641                 }
3642         }
3643
3644         coa = request->coa;
3645
3646         /*
3647          *      src_ipaddr will be set up in proxy_encode.
3648          */
3649         memset(&ipaddr, 0, sizeof(ipaddr));
3650         vp = pairfind(coa->proxy->vps, PW_PACKET_DST_IP_ADDRESS, 0, TAG_ANY);
3651         if (vp) {
3652                 ipaddr.af = AF_INET;
3653                 ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
3654
3655         } else if ((vp = pairfind(coa->proxy->vps, PW_PACKET_DST_IPV6_ADDRESS, 0, TAG_ANY)) != NULL) {
3656                 ipaddr.af = AF_INET6;
3657                 ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
3658
3659         } else if ((vp = pairfind(coa->proxy->vps, PW_HOME_SERVER_POOL, 0, TAG_ANY)) != NULL) {
3660                 coa->home_pool = home_pool_byname(vp->vp_strvalue,
3661                                                   HOME_TYPE_COA);
3662                 if (!coa->home_pool) {
3663                         RWDEBUG2("No such home_server_pool %s",
3664                                vp->vp_strvalue);
3665                         goto fail;
3666                 }
3667
3668                 /*
3669                  *      Prefer the pool to one server
3670                  */
3671         } else if (request->client->coa_pool) {
3672                 coa->home_pool = request->client->coa_pool;
3673
3674         } else if (request->client->coa_server) {
3675                 coa->home_server = request->client->coa_server;
3676
3677         } else {
3678                 /*
3679                  *      If all else fails, send it to the client that
3680                  *      originated this request.
3681                  */
3682                 memcpy(&ipaddr, &request->packet->src_ipaddr, sizeof(ipaddr));
3683         }
3684
3685         /*
3686          *      Use the pool, if it exists.
3687          */
3688         if (coa->home_pool) {
3689                 coa->home_server = home_server_ldb(NULL, coa->home_pool, coa);
3690                 if (!coa->home_server) {
3691                         RWDEBUG("No live home server for home_server_pool %s", coa->home_pool->name);
3692                         goto fail;
3693                 }
3694                 home_server_update_request(coa->home_server, coa);
3695
3696         } else if (!coa->home_server) {
3697                 uint16_t port = PW_COA_UDP_PORT;
3698
3699                 vp = pairfind(coa->proxy->vps, PW_PACKET_DST_PORT, 0, TAG_ANY);
3700                 if (vp) port = vp->vp_integer;
3701
3702                 coa->home_server = home_server_find(&ipaddr, port, IPPROTO_UDP);
3703                 if (!coa->home_server) {
3704                         RWDEBUG2("Unknown destination %s:%d for CoA request.",
3705                                inet_ntop(ipaddr.af, &ipaddr.ipaddr,
3706                                          buffer, sizeof(buffer)), port);
3707                         goto fail;
3708                 }
3709         }
3710
3711         vp = pairfind(coa->proxy->vps, PW_PACKET_TYPE, 0, TAG_ANY);
3712         if (vp) {
3713                 switch (vp->vp_integer) {
3714                 case PW_CODE_COA_REQUEST:
3715                 case PW_CODE_DISCONNECT_REQUEST:
3716                         coa->proxy->code = vp->vp_integer;
3717                         break;
3718
3719                 default:
3720                         DEBUG("Cannot set CoA Packet-Type to code %d",
3721                               vp->vp_integer);
3722                         goto fail;
3723                 }
3724         }
3725
3726         if (!coa->proxy->code) coa->proxy->code = PW_CODE_COA_REQUEST;
3727
3728         /*
3729          *      The rest of the server code assumes that
3730          *      request->packet && request->reply exist.  Copy them
3731          *      from the original request.
3732          */
3733         rad_assert(coa->packet != NULL);
3734         rad_assert(coa->packet->vps == NULL);
3735
3736         coa->packet = rad_copy_packet(coa, request->packet);
3737         coa->reply = rad_copy_packet(coa, request->reply);
3738
3739         coa->config_items = paircopy(coa, request->config_items);
3740         coa->num_coa_requests = 0;
3741         coa->handle = null_handler;
3742         coa->number = request->number; /* it's associated with the same request */
3743
3744         /*
3745          *      Call the pre-proxy routines.
3746          */
3747         vp = pairfind(request->config_items, PW_PRE_PROXY_TYPE, 0, TAG_ANY);
3748         if (vp) {
3749                 DICT_VALUE const *dval = dict_valbyattr(vp->da->attr, vp->da->vendor, vp->vp_integer);
3750                 /* Must be a validation issue */
3751                 rad_assert(dval);
3752                 RDEBUG2("Found Pre-Proxy-Type %s", dval->name);
3753                 pre_proxy_type = vp->vp_integer;
3754         }
3755
3756         if (coa->home_pool && coa->home_pool->virtual_server) {
3757                 char const *old_server = coa->server;
3758
3759                 coa->server = coa->home_pool->virtual_server;
3760                 RDEBUG2("server %s {", coa->server);
3761                 RINDENT();
3762                 rcode = process_pre_proxy(pre_proxy_type, coa);
3763                 REXDENT();
3764                 RDEBUG2("}");
3765                 coa->server = old_server;
3766         } else {
3767                 rcode = process_pre_proxy(pre_proxy_type, coa);
3768         }
3769         switch (rcode) {
3770         default:
3771                 goto fail;
3772
3773         /*
3774          *      Only send the CoA packet if the pre-proxy code succeeded.
3775          */
3776         case RLM_MODULE_NOOP:
3777         case RLM_MODULE_OK:
3778         case RLM_MODULE_UPDATED:
3779                 break;
3780         }
3781
3782         /*
3783          *      Source IP / port is set when the proxy socket
3784          *      is chosen.
3785          */
3786         coa->proxy->dst_ipaddr = coa->home_server->ipaddr;
3787         coa->proxy->dst_port = coa->home_server->port;
3788
3789         if (!insert_into_proxy_hash(coa)) {
3790                 radlog_request(L_PROXY, 0, coa, "Failed to insert CoA request into proxy list");
3791                 goto fail;
3792         }
3793
3794         /*
3795          *      We CANNOT divorce the CoA request from the parent
3796          *      request.  This function is running in a child thread,
3797          *      and we need access to the main event loop in order to
3798          *      to add the timers for the CoA packet.
3799          *
3800          *      Instead, we wait for the timer on the parent request
3801          *      to fire.
3802          */
3803         gettimeofday(&coa->proxy->timestamp, NULL);
3804         coa->packet->timestamp = coa->proxy->timestamp; /* for max_request_time */
3805         coa->delay = 0;         /* need to calculate a new delay */
3806
3807         DEBUG_PACKET(coa, coa->proxy, 1);
3808
3809         coa->process = coa_wait_for_reply;
3810 #ifdef DEBUG_STATE_MACHINE
3811         if (debug_flag) printf("(%u) ********\tSTATE %s C-%s -> C-%s\t********\n", request->number, __FUNCTION__,
3812                                child_state_names[request->child_state],
3813                                child_state_names[REQUEST_RUNNING]);
3814 #endif
3815 #ifdef HAVE_PTHREAD_H
3816         coa->child_pid = NO_SUCH_CHILD_PID;
3817 #endif
3818         coa->child_state = REQUEST_PROXIED;
3819         rad_assert(coa->proxy_reply == NULL);
3820         FR_STATS_TYPE_INC(coa->home_server->stats.total_requests);
3821         coa->home_server->last_packet_sent = coa->proxy->timestamp.tv_sec;
3822         coa->proxy_listener->send(coa->proxy_listener, coa);
3823 }
3824
3825
3826 static void coa_timer(REQUEST *request)
3827 {
3828         uint32_t delay, frac;
3829         struct timeval now, when, mrd;
3830
3831         VERIFY_REQUEST(request);
3832
3833         rad_assert(request->parent == NULL);
3834
3835         if (request->proxy_reply) return request_process_timer(request);
3836
3837         gettimeofday(&now, NULL);
3838
3839         if (request->delay == 0) {
3840                 /*
3841                  *      Implement re-transmit algorithm as per RFC 5080
3842                  *      Section 2.2.1.
3843                  *
3844                  *      We want IRT + RAND*IRT
3845                  *      or 0.9 IRT + rand(0,.2) IRT
3846                  *
3847                  *      2^20 ~ USEC, and we want 2.
3848                  *      rand(0,0.2) USEC ~ (rand(0,2^21) / 10)
3849                  */
3850                 delay = (fr_rand() & ((1 << 22) - 1)) / 10;
3851                 request->delay = delay * request->home_server->coa_irt;
3852                 delay = request->home_server->coa_irt * USEC;
3853                 delay -= delay / 10;
3854                 delay += request->delay;
3855                 request->delay = delay;
3856
3857                 when = request->proxy->timestamp;
3858                 tv_add(&when, delay);
3859
3860                 if (timercmp(&when, &now, >)) {
3861                         STATE_MACHINE_TIMER(FR_ACTION_TIMER);
3862                         return;
3863                 }
3864         }
3865
3866         /*
3867          *      Retransmit CoA request.
3868          */
3869
3870         /*
3871          *      Cap count at MRC, if it is non-zero.
3872          */
3873         if (request->home_server->coa_mrc &&
3874             (request->num_coa_requests >= request->home_server->coa_mrc)) {
3875                 char buffer[128];
3876
3877                 RERROR("Failing request - originate-coa ID %u, due to lack of any response from coa server %s port %d",
3878                        request->proxy->id,
3879                                inet_ntop(request->proxy->dst_ipaddr.af,
3880                                          &request->proxy->dst_ipaddr.ipaddr,
3881                                          buffer, sizeof(buffer)),
3882                                request->proxy->dst_port);
3883
3884                 if (setup_post_proxy_fail(request)) {
3885                         request_queue_or_run(request, coa_no_reply);
3886                 } else {
3887                         request_done(request, FR_ACTION_DONE);
3888                 }
3889                 return;
3890         }
3891
3892         /*
3893          *      RFC 5080 Section 2.2.1
3894          *
3895          *      RT = 2*RTprev + RAND*RTprev
3896          *         = 1.9 * RTprev + rand(0,.2) * RTprev
3897          *         = 1.9 * RTprev + rand(0,1) * (RTprev / 5)
3898          */
3899         delay = fr_rand();
3900         delay ^= (delay >> 16);
3901         delay &= 0xffff;
3902         frac = request->delay / 5;
3903         delay = ((frac >> 16) * delay) + (((frac & 0xffff) * delay) >> 16);
3904
3905         delay += (2 * request->delay) - (request->delay / 10);
3906
3907         /*
3908          *      Cap delay at MRT, if MRT is non-zero.
3909          */
3910         if (request->home_server->coa_mrt &&
3911             (delay > (request->home_server->coa_mrt * USEC))) {
3912                 int mrt_usec = request->home_server->coa_mrt * USEC;
3913
3914                 /*
3915                  *      delay = MRT + RAND * MRT
3916                  *            = 0.9 MRT + rand(0,.2)  * MRT
3917                  */
3918                 delay = fr_rand();
3919                 delay ^= (delay >> 15);
3920                 delay &= 0x1ffff;
3921                 delay = ((mrt_usec >> 16) * delay) + (((mrt_usec & 0xffff) * delay) >> 16);
3922                 delay += mrt_usec - (mrt_usec / 10);
3923         }
3924
3925         request->delay = delay;
3926         when = now;
3927         tv_add(&when, request->delay);
3928         mrd = request->proxy->timestamp;
3929         mrd.tv_sec += request->home_server->coa_mrd;
3930
3931         /*
3932          *      Cap duration at MRD.
3933          */
3934         if (timercmp(&mrd, &when, <)) {
3935                 when = mrd;
3936         }
3937         STATE_MACHINE_TIMER(FR_ACTION_TIMER);
3938
3939         request->num_coa_requests++; /* is NOT reset by code 3 lines above! */
3940
3941         FR_STATS_TYPE_INC(request->home_server->stats.total_requests);
3942
3943         /*
3944          *      Status servers don't count as real packets sent.
3945          */
3946         request->proxy_listener->send(request->proxy_listener,
3947                                       request);
3948 }
3949
3950 STATE_MACHINE_DECL(coa_wait_for_reply)
3951 {
3952         rad_assert(request->parent == NULL);
3953
3954         VERIFY_REQUEST(request);
3955
3956         TRACE_STATE_MACHINE;
3957
3958         switch (action) {
3959         case FR_ACTION_TIMER:
3960                 /*
3961                  *      This is big enough to be in it's own function.
3962                  */
3963                 coa_timer(request);
3964                 break;
3965
3966         case FR_ACTION_PROXY_REPLY:
3967                 rad_assert(request->parent == NULL);
3968                 request_queue_or_run(request, coa_running);
3969                 break;
3970
3971         default:
3972                 RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
3973                 break;
3974         }
3975 }
3976
3977 static void request_coa_separate(REQUEST *request)
3978 {
3979 #ifdef DEBUG_STATE_MACHINE
3980         int action = FR_ACTION_TIMER;
3981 #endif
3982
3983         VERIFY_REQUEST(request);
3984
3985         TRACE_STATE_MACHINE;
3986
3987         rad_assert(request->parent != NULL);
3988         rad_assert(request->parent->coa == request);
3989         rad_assert(request->ev == NULL);
3990         rad_assert(!request->in_request_hash);
3991         rad_assert(request->coa == NULL);
3992
3993         rad_assert(request->proxy_listener != NULL);
3994
3995         (void) talloc_steal(NULL, request);
3996         request->parent->coa = NULL;
3997         request->parent = NULL;
3998
3999         /*
4000          *      Should be coa_wait_for_reply()
4001          */
4002         request->process(request, FR_ACTION_TIMER);
4003 }
4004
4005 STATE_MACHINE_DECL(coa_no_reply)
4006 {
4007         char buffer[128];
4008
4009         VERIFY_REQUEST(request);
4010
4011         TRACE_STATE_MACHINE;
4012
4013         switch (action) {
4014         case FR_ACTION_TIMER:
4015                 request_common(request, action);
4016                 break;
4017
4018         case FR_ACTION_PROXY_REPLY: /* too late! */
4019                 RDEBUG2("Reply from CoA server %s port %d  - ID: %d arrived too late.",
4020                         inet_ntop(request->proxy->src_ipaddr.af,
4021                                   &request->proxy->src_ipaddr.ipaddr,
4022                                   buffer, sizeof(buffer)),
4023                         request->proxy->dst_port, request->proxy->id);
4024                 break;
4025
4026         case FR_ACTION_RUN:
4027                 /*
4028                  *      FIXME: do recv_coa Fail
4029                  */
4030                 (void) process_proxy_reply(request, NULL);
4031                 request_done(request, FR_ACTION_DONE);
4032                 break;
4033
4034         default:
4035                 RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
4036                 break;
4037         }
4038 }
4039
4040 STATE_MACHINE_DECL(coa_running)
4041 {
4042         VERIFY_REQUEST(request);
4043
4044         TRACE_STATE_MACHINE;
4045
4046         switch (action) {
4047         case FR_ACTION_TIMER:
4048                 request_process_timer(request);
4049                 break;
4050
4051         case FR_ACTION_PROXY_REPLY:
4052                 request_common(request, action);
4053                 break;
4054
4055         case FR_ACTION_RUN:
4056                 if (process_proxy_reply(request, request->proxy_reply)) {
4057                         request->handle(request);
4058                         request_finish(request, action);
4059                 } else {
4060                         request_done(request, FR_ACTION_DONE);
4061                 }
4062                 break;
4063
4064         default:
4065                 RDEBUG3("%s: Ignoring action %s", __FUNCTION__, action_codes[action]);
4066                 break;
4067         }
4068 }
4069 #endif  /* WITH_COA */
4070
4071 /***********************************************************************
4072  *
4073  *  End of the State machine.  Start of additional helper code.
4074  *
4075  ***********************************************************************/
4076
4077 /***********************************************************************
4078  *
4079  *      Event handlers.
4080  *
4081  ***********************************************************************/
4082 static void event_socket_handler(UNUSED fr_event_list_t *xel, UNUSED int fd, void *ctx)
4083 {
4084         rad_listen_t *listener = talloc_get_type_abort(ctx, rad_listen_t);
4085
4086         rad_assert(xel == el);
4087
4088         if (
4089 #ifdef WITH_DETAIL
4090             (listener->type != RAD_LISTEN_DETAIL) &&
4091 #endif
4092             (listener->fd < 0)) {
4093                 char buffer[256];
4094
4095                 listener->print(listener, buffer, sizeof(buffer));
4096                 ERROR("FATAL: Asked to read from closed socket: %s",
4097                        buffer);
4098
4099                 rad_panic("Socket was closed on us!");
4100                 fr_exit_now(1);
4101         }
4102
4103         listener->recv(listener);
4104 }
4105
4106 #ifdef WITH_DETAIL
4107 #ifdef WITH_DETAIL_THREAD
4108 #else
4109 /*
4110  *      This function is called periodically to see if this detail
4111  *      file is available for reading.
4112  */
4113 static void event_poll_detail(void *ctx)
4114 {
4115         int delay;
4116         rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
4117         struct timeval when, now;
4118         listen_detail_t *detail = this->data;
4119
4120         rad_assert(this->type == RAD_LISTEN_DETAIL);
4121
4122  redo:
4123         event_socket_handler(el, this->fd, this);
4124
4125         fr_event_now(el, &now);
4126         when = now;
4127
4128         /*
4129          *      Backdoor API to get the delay until the next poll
4130          *      time.
4131          */
4132         delay = this->encode(this, NULL);
4133         if (delay == 0) goto redo;
4134
4135         tv_add(&when, delay);
4136
4137         if (!fr_event_insert(el, event_poll_detail, this,
4138                              &when, &detail->ev)) {
4139                 ERROR("Failed creating handler");
4140                 fr_exit(1);
4141         }
4142 }
4143 #endif  /* WITH_DETAIL_THREAD */
4144 #endif  /* WITH_DETAIL */
4145
4146 static void event_status(struct timeval *wake)
4147 {
4148 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
4149         int argval;
4150 #endif
4151
4152         if (debug_flag == 0) {
4153                 if (just_started) {
4154                         INFO("Ready to process requests");
4155                         just_started = false;
4156                 }
4157                 return;
4158         }
4159
4160         if (!wake) {
4161                 INFO("Ready to process requests");
4162
4163         } else if ((wake->tv_sec != 0) ||
4164                    (wake->tv_usec >= 100000)) {
4165                 DEBUG("Waking up in %d.%01u seconds.",
4166                       (int) wake->tv_sec, (unsigned int) wake->tv_usec / 100000);
4167         }
4168
4169
4170         /*
4171          *      FIXME: Put this somewhere else, where it isn't called
4172          *      all of the time...
4173          */
4174
4175 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
4176         /*
4177          *      If there are no child threads, then there may
4178          *      be child processes.  In that case, wait for
4179          *      their exit status, and throw that exit status
4180          *      away.  This helps get rid of zxombie children.
4181          */
4182         while (waitpid(-1, &argval, WNOHANG) > 0) {
4183                 /* do nothing */
4184         }
4185 #endif
4186
4187 }
4188
4189 #ifdef WITH_TCP
4190 static void listener_free_cb(void *ctx)
4191 {
4192         rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
4193         char buffer[1024];
4194
4195         if (this->count > 0) {
4196                 struct timeval when;
4197                 listen_socket_t *sock = this->data;
4198
4199                 fr_event_now(el, &when);
4200                 when.tv_sec += 3;
4201
4202                 if (!fr_event_insert(el, listener_free_cb, this, &when,
4203                                      &(sock->ev))) {
4204                         rad_panic("Failed to insert event");
4205                 }
4206
4207                 return;
4208         }
4209
4210         /*
4211          *      It's all free, close the socket.
4212          */
4213
4214         this->print(this, buffer, sizeof(buffer));
4215         DEBUG("... cleaning up socket %s", buffer);
4216         listen_free(&this);
4217 }
4218 #endif
4219
4220 #ifdef WITH_PROXY
4221 static int proxy_eol_cb(void *ctx, void *data)
4222 {
4223         struct timeval when;
4224         REQUEST *request = fr_packet2myptr(REQUEST, proxy, data);
4225
4226         if (request->proxy_listener != ctx) return 0;
4227
4228         /*
4229          *      We don't care if it's being processed in a child thread.
4230          */
4231
4232 #ifdef WITH_ACCOUNTING
4233         /*
4234          *      Accounting packets should be deleted immediately.
4235          *      They will never be retransmitted by the client.
4236          */
4237         if (request->proxy->code == PW_CODE_ACCOUNTING_REQUEST) {
4238                 RDEBUG("Stopping request due to failed connection to home server");
4239                 request->master_state = REQUEST_STOP_PROCESSING;
4240         }
4241 #endif
4242
4243         /*
4244          *      Reset the timer to be now, so that the request is
4245          *      quickly updated.  But spread the requests randomly
4246          *      over the next second, so that we don't overload the
4247          *      server.
4248          */
4249         fr_event_now(el, &when);
4250         tv_add(&when, fr_rand() % USEC);
4251         STATE_MACHINE_TIMER(FR_ACTION_TIMER);
4252
4253         /*
4254          *      Don't delete it from the list.
4255          */
4256         return 0;
4257 }
4258 #endif
4259
4260 static int event_new_fd(rad_listen_t *this)
4261 {
4262         char buffer[1024];
4263
4264         ASSERT_MASTER;
4265
4266         if (this->status == RAD_LISTEN_STATUS_KNOWN) return 1;
4267
4268         this->print(this, buffer, sizeof(buffer));
4269
4270         if (this->status == RAD_LISTEN_STATUS_INIT) {
4271                 listen_socket_t *sock = this->data;
4272
4273                 if (just_started) {
4274                         DEBUG("Listening on %s", buffer);
4275
4276 #ifdef WITH_PROXY
4277                 } else if (this->type == RAD_LISTEN_PROXY) {
4278                         home_server_t *home;
4279
4280                         home = sock->home;
4281                         if (!home || !home->limit.max_connections) {
4282                                 INFO(" ... adding new socket %s", buffer);
4283                         } else {
4284                                 INFO(" ... adding new socket %s (%u of %u)", buffer,
4285                                      home->limit.num_connections, home->limit.max_connections);
4286                         }
4287                 
4288 #endif
4289                 } else {
4290                         INFO(" ... adding new socket %s", buffer);
4291                 }
4292
4293                 switch (this->type) {
4294 #ifdef WITH_DETAIL
4295                 /*
4296                  *      Detail files are always known, and aren't
4297                  *      put into the socket event loop.
4298                  */
4299                 case RAD_LISTEN_DETAIL:
4300                         this->status = RAD_LISTEN_STATUS_KNOWN;
4301
4302 #ifndef WITH_DETAIL_THREAD
4303                         /*
4304                          *      Set up the first poll interval.
4305                          */
4306                         event_poll_detail(this);
4307                         return 1;
4308 #else
4309                         break;  /* add the FD to the list */
4310 #endif
4311 #endif  /* WITH_DETAIL */
4312
4313 #ifdef WITH_PROXY
4314                 /*
4315                  *      Add it to the list of sockets we can use.
4316                  *      Server sockets (i.e. auth/acct) are never
4317                  *      added to the packet list.
4318                  */
4319                 case RAD_LISTEN_PROXY:
4320 #ifdef WITH_TCP
4321                         /*
4322                          *      Add timers to outgoing child sockets, if necessary.
4323                          */
4324                         if (sock->proto == IPPROTO_TCP && sock->opened &&
4325                             (sock->home->limit.lifetime || sock->home->limit.idle_timeout)) {
4326                                 struct timeval when;
4327
4328                                 when.tv_sec = sock->opened + 1;
4329                                 when.tv_usec = 0;
4330
4331                                 if (!fr_event_insert(el, tcp_socket_timer, this, &when,
4332                                                      &(sock->ev))) {
4333                                         rad_panic("Failed to insert event");
4334                                 }
4335                         }
4336 #endif
4337                         break;
4338 #endif  /* WITH_PROXY */
4339
4340                         /*
4341                          *      FIXME: put idle timers on command sockets.
4342                          */
4343
4344                 default:
4345 #ifdef WITH_TCP
4346                         /*
4347                          *      Add timers to incoming child sockets, if necessary.
4348                          */
4349                         if (sock->proto == IPPROTO_TCP && sock->opened &&
4350                             (sock->limit.lifetime || sock->limit.idle_timeout)) {
4351                                 struct timeval when;
4352
4353                                 when.tv_sec = sock->opened + 1;
4354                                 when.tv_usec = 0;
4355
4356                                 if (!fr_event_insert(el, tcp_socket_timer, this, &when,
4357                                                      &(sock->ev))) {
4358                                         rad_panic("Failed to insert event");
4359                                 }
4360                         }
4361 #endif
4362                         break;
4363                 } /* switch over listener types */
4364
4365                 /*
4366                  *      All sockets: add the FD to the event handler.
4367                  */
4368                 if (!fr_event_fd_insert(el, 0, this->fd,
4369                                         event_socket_handler, this)) {
4370                         ERROR("Failed adding event handler for socket!");
4371                         fr_exit(1);
4372                 }
4373
4374                 this->status = RAD_LISTEN_STATUS_KNOWN;
4375                 return 1;
4376         } /* end of INIT */
4377
4378 #ifdef WITH_TCP
4379         /*
4380          *      Stop using this socket, if at all possible.
4381          */
4382         if (this->status == RAD_LISTEN_STATUS_EOL) {
4383                 /*
4384                  *      Remove it from the list of live FD's.
4385                  */
4386                 fr_event_fd_delete(el, 0, this->fd);
4387
4388 #ifdef WITH_PROXY
4389                 /*
4390                  *      Proxy sockets get frozen, so that we don't use
4391                  *      them for new requests.  But we do keep them
4392                  *      open to listen for replies to requests we had
4393                  *      previously sent.
4394                  */
4395                 if (this->type == RAD_LISTEN_PROXY) {
4396                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
4397                         if (!fr_packet_list_socket_freeze(proxy_list,
4398                                                           this->fd)) {
4399                                 ERROR("Fatal error freezing socket: %s", fr_strerror());
4400                                 fr_exit(1);
4401                         }
4402
4403                         fr_packet_list_walk(proxy_list, this, proxy_eol_cb);
4404                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
4405                 }
4406 #endif
4407
4408                 /*
4409                  *      Requests are still using the socket.  Wait for
4410                  *      them to finish.
4411                  */
4412                 if (this->count > 0) {
4413                         struct timeval when;
4414                         listen_socket_t *sock = this->data;
4415
4416                         /*
4417                          *      Try again to clean up the socket in 30
4418                          *      seconds.
4419                          */
4420                         gettimeofday(&when, NULL);
4421                         when.tv_sec += 30;
4422
4423                         if (!fr_event_insert(el,
4424                                              (fr_event_callback_t) event_new_fd,
4425                                              this, &when, &sock->ev)) {
4426                                 rad_panic("Failed to insert event");
4427                         }
4428
4429                         return 1;
4430                 }
4431
4432                 /*
4433                  *      No one is using the socket.  We can remove it now.
4434                  */
4435                 this->status = RAD_LISTEN_STATUS_REMOVE_NOW;
4436         } /* socket is at EOL */
4437 #endif
4438
4439         /*
4440          *      Nuke the socket.
4441          */
4442         if (this->status == RAD_LISTEN_STATUS_REMOVE_NOW) {
4443                 int devnull;
4444 #ifdef WITH_TCP
4445                 listen_socket_t *sock = this->data;
4446 #endif
4447                 struct timeval when;
4448
4449                 /*
4450                  *      Re-open the socket, pointing it to /dev/null.
4451                  *      This means that all writes proceed without
4452                  *      blocking, and all reads return "no data".
4453                  *
4454                  *      This leaves the socket active, so any child
4455                  *      threads won't go insane.  But it means that
4456                  *      they cannot send or receive any packets.
4457                  *
4458                  *      This is EXTRA work in the normal case, when
4459                  *      sockets are closed without error.  But it lets
4460                  *      us have one simple processing method for all
4461                  *      sockets.
4462                  */
4463                 devnull = open("/dev/null", O_RDWR);
4464                 if (devnull < 0) {
4465                         ERROR("FATAL failure opening /dev/null: %s",
4466                                fr_syserror(errno));
4467                         fr_exit(1);
4468                 }
4469                 if (dup2(devnull, this->fd) < 0) {
4470                         ERROR("FATAL failure closing socket: %s",
4471                                fr_syserror(errno));
4472                         fr_exit(1);
4473                 }
4474                 close(devnull);
4475
4476 #ifdef WITH_DETAIL
4477                 rad_assert(this->type != RAD_LISTEN_DETAIL);
4478 #endif
4479
4480 #ifdef WITH_TCP
4481 #ifdef WITH_PROXY
4482                 /*
4483                  *      The socket is dead.  Force all proxied packets
4484                  *      to stop using it.  And then remove it from the
4485                  *      list of outgoing sockets.
4486                  */
4487                 if (this->type == RAD_LISTEN_PROXY) {
4488                         home_server_t *home;
4489
4490                         home = sock->home;
4491                         if (!home || !home->limit.max_connections) {
4492                                 INFO(" ... shutting down socket %s", buffer);
4493                         } else {
4494                                 INFO(" ... shutting down socket %s (%u of %u)", buffer,
4495                                      home->limit.num_connections, home->limit.max_connections);
4496                         }
4497
4498                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
4499                         fr_packet_list_walk(proxy_list, this, eol_proxy_listener);
4500
4501                         if (!fr_packet_list_socket_del(proxy_list, this->fd)) {
4502                                 ERROR("Fatal error removing socket %s: %s",
4503                                       buffer, fr_strerror());
4504                                 fr_exit(1);
4505                         }
4506                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
4507                 } else
4508 #endif
4509                 {
4510                         INFO(" ... shutting down socket %s", buffer);
4511
4512                         /*
4513                          *      EOL all requests using this socket.
4514                          */
4515                         fr_packet_list_walk(pl, this, eol_listener);
4516                 }
4517
4518                 /*
4519                  *      No child threads, clean it up now.
4520                  */
4521                 if (!spawn_flag) {
4522                         if (sock->ev) fr_event_delete(el, &sock->ev);
4523                         listen_free(&this);
4524                         return 1;
4525                 }
4526
4527                 /*
4528                  *      Wait until all requests using this socket are done.
4529                  */
4530                 gettimeofday(&when, NULL);
4531                 when.tv_sec += 3;
4532
4533                 if (!fr_event_insert(el, listener_free_cb, this, &when,
4534                                      &(sock->ev))) {
4535                         rad_panic("Failed to insert event");
4536                 }
4537         }
4538 #endif  /* WITH_TCP */
4539
4540         return 1;
4541 }
4542
4543 /***********************************************************************
4544  *
4545  *      Signal handlers.
4546  *
4547  ***********************************************************************/
4548
4549 static void handle_signal_self(int flag)
4550 {
4551         ASSERT_MASTER;
4552
4553         if ((flag & (RADIUS_SIGNAL_SELF_EXIT | RADIUS_SIGNAL_SELF_TERM)) != 0) {
4554                 if ((flag & RADIUS_SIGNAL_SELF_EXIT) != 0) {
4555                         INFO("Signalled to exit");
4556                         fr_event_loop_exit(el, 1);
4557                 } else {
4558                         INFO("Signalled to terminate");
4559                         exec_trigger(NULL, NULL, "server.signal.term", true);
4560                         fr_event_loop_exit(el, 2);
4561                 }
4562
4563                 return;
4564         } /* else exit/term flags weren't set */
4565
4566         /*
4567          *      Tell the even loop to stop processing.
4568          */
4569         if ((flag & RADIUS_SIGNAL_SELF_HUP) != 0) {
4570                 time_t when;
4571                 static time_t last_hup = 0;
4572
4573                 when = time(NULL);
4574                 if ((int) (when - last_hup) < 5) {
4575                         INFO("Ignoring HUP (less than 5s since last one)");
4576                         return;
4577                 }
4578
4579                 INFO("Received HUP signal");
4580
4581                 last_hup = when;
4582
4583                 exec_trigger(NULL, NULL, "server.signal.hup", true);
4584                 fr_event_loop_exit(el, 0x80);
4585         }
4586
4587 #ifdef WITH_DETAIL
4588 #ifndef WITH_DETAIL_THREAD
4589         if ((flag & RADIUS_SIGNAL_SELF_DETAIL) != 0) {
4590                 rad_listen_t *this;
4591
4592                 /*
4593                  *      FIXME: O(N) loops suck.
4594                  */
4595                 for (this = main_config.listen;
4596                      this != NULL;
4597                      this = this->next) {
4598                         if (this->type != RAD_LISTEN_DETAIL) continue;
4599
4600                         /*
4601                          *      This one didn't send the signal, skip
4602                          *      it.
4603                          */
4604                         if (!this->decode(this, NULL)) continue;
4605
4606                         /*
4607                          *      Go service the interrupt.
4608                          */
4609                         event_poll_detail(this);
4610                 }
4611         }
4612 #endif
4613 #endif
4614
4615 #ifdef WITH_TCP
4616 #ifdef WITH_PROXY
4617 #ifdef HAVE_PTHREAD_H
4618         /*
4619          *      There are new listeners in the list.  Run
4620          *      event_new_fd() on them.
4621          */
4622         if ((flag & RADIUS_SIGNAL_SELF_NEW_FD) != 0) {
4623                 rad_listen_t *this, *next;
4624
4625                 FD_MUTEX_LOCK(&fd_mutex);
4626
4627                 /*
4628                  *      FIXME: unlock the mutex before calling
4629                  *      event_new_fd()?
4630                  */
4631                 for (this = new_listeners; this != NULL; this = next) {
4632                         next = this->next;
4633                         this->next = NULL;
4634
4635                         event_new_fd(this);
4636                 }
4637
4638                 new_listeners = NULL;
4639                 FD_MUTEX_UNLOCK(&fd_mutex);
4640         }
4641 #endif  /* HAVE_PTHREAD_H */
4642 #endif  /* WITH_PROXY */
4643 #endif  /* WITH_TCP */
4644 }
4645
4646 #ifndef HAVE_PTHREAD_H
4647 void radius_signal_self(int flag)
4648 {
4649         return handle_signal_self(flag);
4650 }
4651
4652 #else
4653 static int self_pipe[2] = { -1, -1 };
4654
4655 /*
4656  *      Inform ourselves that we received a signal.
4657  */
4658 void radius_signal_self(int flag)
4659 {
4660         ssize_t rcode;
4661         uint8_t buffer[16];
4662
4663         /*
4664          *      The read MUST be non-blocking for this to work.
4665          */
4666         rcode = read(self_pipe[0], buffer, sizeof(buffer));
4667         if (rcode > 0) {
4668                 ssize_t i;
4669
4670                 for (i = 0; i < rcode; i++) {
4671                         buffer[0] |= buffer[i];
4672                 }
4673         } else {
4674                 buffer[0] = 0;
4675         }
4676
4677         buffer[0] |= flag;
4678
4679         if (write(self_pipe[1], buffer, 1) < 0) fr_exit(0);
4680 }
4681
4682
4683 static void event_signal_handler(UNUSED fr_event_list_t *xel,
4684                                  UNUSED int fd, UNUSED void *ctx)
4685 {
4686         ssize_t i, rcode;
4687         uint8_t buffer[32];
4688
4689         rcode = read(self_pipe[0], buffer, sizeof(buffer));
4690         if (rcode <= 0) return;
4691
4692         /*
4693          *      Merge pending signals.
4694          */
4695         for (i = 0; i < rcode; i++) {
4696                 buffer[0] |= buffer[i];
4697         }
4698
4699         handle_signal_self(buffer[0]);
4700 }
4701 #endif  /* HAVE_PTHREAD_H */
4702
4703 /***********************************************************************
4704  *
4705  *      Bootstrapping code.
4706  *
4707  ***********************************************************************/
4708
4709 /*
4710  *      Externally-visibly functions.
4711  */
4712 int radius_event_init(TALLOC_CTX *ctx) {
4713         el = fr_event_list_create(ctx, event_status);
4714         if (!el) return 0;
4715
4716         return 1;
4717 }
4718
4719 int radius_event_start(CONF_SECTION *cs, bool have_children)
4720 {
4721         rad_listen_t *head = NULL;
4722
4723         if (fr_start_time != (time_t)-1) return 0;
4724
4725         time(&fr_start_time);
4726
4727         if (!check_config) {
4728                 /*
4729                  *  radius_event_init() must be called first
4730                  */
4731                 rad_assert(el);
4732
4733                 pl = fr_packet_list_create(0);
4734                 if (!pl) return 0;      /* leak el */
4735         }
4736
4737         request_num_counter = 0;
4738
4739 #ifdef WITH_PROXY
4740         if (main_config.proxy_requests) {
4741                 /*
4742                  *      Create the tree for managing proxied requests and
4743                  *      responses.
4744                  */
4745                 proxy_list = fr_packet_list_create(1);
4746                 if (!proxy_list) return 0;
4747
4748 #ifdef HAVE_PTHREAD_H
4749                 if (pthread_mutex_init(&proxy_mutex, NULL) != 0) {
4750                         ERROR("FATAL: Failed to initialize proxy mutex: %s",
4751                                fr_syserror(errno));
4752                         fr_exit(1);
4753                 }
4754 #endif
4755
4756                 /*
4757                  *      The "init_delay" is set to "response_window".
4758                  *      Reset it to half of "response_window" in order
4759                  *      to give the event loop enough time to service
4760                  *      the event before hitting "response_window".
4761                  */
4762                 main_config.init_delay.tv_usec += (main_config.init_delay.tv_sec & 0x01) * USEC;
4763                 main_config.init_delay.tv_usec >>= 1;
4764                 main_config.init_delay.tv_sec >>= 1;
4765
4766         }
4767 #endif
4768
4769         /*
4770          *      Move all of the thread calls to this file?
4771          *
4772          *      It may be best for the mutexes to be in this file...
4773          */
4774         spawn_flag = have_children;
4775
4776 #ifdef HAVE_PTHREAD_H
4777         NO_SUCH_CHILD_PID = pthread_self(); /* not a child thread */
4778
4779         /*
4780          *      Initialize the threads ONLY if we're spawning, AND
4781          *      we're running normally.
4782          */
4783         if (have_children && !check_config &&
4784             (thread_pool_init(cs, &spawn_flag) < 0)) {
4785                 fr_exit(1);
4786         }
4787 #endif
4788
4789         if (check_config) {
4790                 DEBUG("%s: #### Skipping IP addresses and Ports ####",
4791                        main_config.name);
4792                 if (listen_init(cs, &head, spawn_flag) < 0) {
4793                         fflush(NULL);
4794                         fr_exit(1);
4795                 }
4796                 return 1;
4797         }
4798
4799 #ifdef HAVE_PTHREAD_H
4800         /*
4801          *      Child threads need a pipe to signal us, as do the
4802          *      signal handlers.
4803          */
4804         if (pipe(self_pipe) < 0) {
4805                 ERROR("radiusd: Error opening internal pipe: %s",
4806                        fr_syserror(errno));
4807                 fr_exit(1);
4808         }
4809         if ((fcntl(self_pipe[0], F_SETFL, O_NONBLOCK) < 0) ||
4810             (fcntl(self_pipe[0], F_SETFD, FD_CLOEXEC) < 0)) {
4811                 ERROR("radiusd: Error setting internal flags: %s",
4812                        fr_syserror(errno));
4813                 fr_exit(1);
4814         }
4815         if ((fcntl(self_pipe[1], F_SETFL, O_NONBLOCK) < 0) ||
4816             (fcntl(self_pipe[1], F_SETFD, FD_CLOEXEC) < 0)) {
4817                 ERROR("radiusd: Error setting internal flags: %s",
4818                        fr_syserror(errno));
4819                 fr_exit(1);
4820         }
4821
4822         if (!fr_event_fd_insert(el, 0, self_pipe[0],
4823                                   event_signal_handler, el)) {
4824                 ERROR("Failed creating handler for signals");
4825                 fr_exit(1);
4826         }
4827 #endif
4828
4829        DEBUG("%s: #### Opening IP addresses and Ports ####",
4830                main_config.name);
4831
4832        /*
4833         *       The server temporarily switches to an unprivileged
4834         *       user very early in the bootstrapping process.
4835         *       However, some sockets MAY require privileged access
4836         *       (bind to device, or to port < 1024, or to raw
4837         *       sockets).  Those sockets need to call suid up/down
4838         *       themselves around the functions that need a privileged
4839         *       uid.
4840         */
4841        if (listen_init(cs, &head, spawn_flag) < 0) {
4842                 fr_exit_now(1);
4843         }
4844
4845         main_config.listen = head;
4846
4847         /*
4848          *      At this point, no one has any business *ever* going
4849          *      back to root uid.
4850          */
4851         fr_suid_down_permanent();
4852
4853         return 1;
4854 }
4855
4856
4857 #ifdef WITH_PROXY
4858 static int proxy_delete_cb(UNUSED void *ctx, void *data)
4859 {
4860         REQUEST *request = fr_packet2myptr(REQUEST, proxy, data);
4861
4862         VERIFY_REQUEST(request);
4863
4864         request->master_state = REQUEST_STOP_PROCESSING;
4865
4866 #ifdef HAVE_PTHREAD_H
4867         if (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0) return 0;
4868 #endif
4869
4870         /*
4871          *      If it's queued we can't delete it from the queue.
4872          *
4873          *      Otherwise, it's OK to delete it.  Even RUNNING, because
4874          *      that will get caught by the check above.
4875          */
4876         if (request->child_state == REQUEST_QUEUED) return 0;
4877
4878         request->in_proxy_hash = false;
4879
4880         if (!request->in_request_hash) {
4881                 request_done(request, FR_ACTION_DONE);
4882         }
4883
4884         /*
4885          *      Delete it from the list.
4886          */
4887         return 2;
4888 }
4889 #endif
4890
4891
4892 static int request_delete_cb(UNUSED void *ctx, void *data)
4893 {
4894         REQUEST *request = fr_packet2myptr(REQUEST, packet, data);
4895
4896         VERIFY_REQUEST(request);
4897
4898         request->master_state = REQUEST_STOP_PROCESSING;
4899
4900         /*
4901          *      Not done, or the child thread is still processing it.
4902          */
4903         if (request->child_state < REQUEST_RESPONSE_DELAY) return 0; /* continue */
4904
4905 #ifdef HAVE_PTHREAD_H
4906         if (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0) return 0;
4907 #endif
4908
4909 #ifdef WITH_PROXY
4910         rad_assert(request->in_proxy_hash == false);
4911 #endif
4912
4913         request->in_request_hash = false;
4914         if (request->ev) fr_event_delete(el, &request->ev);
4915
4916         if (main_config.memory_report) {
4917                 RDEBUG2("Cleaning up request packet ID %u with timestamp +%d",
4918                         request->packet->id,
4919                         (unsigned int) (request->timestamp - fr_start_time));
4920         }
4921
4922 #ifdef WITH_COA
4923         if (request->coa) {
4924                 rad_assert(!request->coa->in_proxy_hash);
4925         }
4926 #endif
4927
4928         talloc_free(request);
4929
4930         /*
4931          *      Delete it from the list, and continue;
4932          */
4933         return 2;
4934 }
4935
4936
4937 void radius_event_free(void)
4938 {
4939         ASSERT_MASTER;
4940
4941 #ifdef WITH_PROXY
4942         /*
4943          *      There are requests in the proxy hash that aren't
4944          *      referenced from anywhere else.  Remove them first.
4945          */
4946         if (proxy_list) {
4947                 fr_packet_list_walk(proxy_list, NULL, proxy_delete_cb);
4948         }
4949 #endif
4950
4951         fr_packet_list_walk(pl, NULL, request_delete_cb);
4952
4953         if (spawn_flag) {
4954                 /*
4955                  *      Now that all requests have been marked "please stop",
4956                  *      ensure that all of the threads have exited.
4957                  */
4958 #ifdef HAVE_PTHREAD_H
4959                 thread_pool_stop();
4960 #endif
4961
4962                 /*
4963                  *      Walk the lists again, ensuring that all
4964                  *      requests are done.
4965                  */
4966                 if (main_config.memory_report) {
4967                         int num;
4968
4969 #ifdef WITH_PROXY
4970                         if (proxy_list) {
4971                                 fr_packet_list_walk(proxy_list, NULL, proxy_delete_cb);
4972                                 num = fr_packet_list_num_elements(proxy_list);
4973                                 if (num > 0) {
4974                                         ERROR("Proxy list has %d requests still in it.", num);
4975                                 }
4976                         }
4977 #endif
4978
4979                         fr_packet_list_walk(pl, NULL, request_delete_cb);
4980                         num = fr_packet_list_num_elements(pl);
4981                         if (num > 0) {
4982                                 ERROR("Request list has %d requests still in it.", num);
4983                         }
4984                 }
4985         }
4986
4987         fr_packet_list_free(pl);
4988         pl = NULL;
4989
4990 #ifdef WITH_PROXY
4991         fr_packet_list_free(proxy_list);
4992         proxy_list = NULL;
4993 #endif
4994
4995         TALLOC_FREE(el);
4996
4997         if (debug_condition) talloc_free(debug_condition);
4998 }
4999
5000 int radius_event_process(void)
5001 {
5002         if (!el) return 0;
5003
5004         return fr_event_loop(el);
5005 }