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