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