Compile-time option WITH_ACCOUNTING
[freeradius.git] / src / main / event.c
1 /*
2  * event.c      Server event handling
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2007  The FreeRADIUS server project
21  * Copyright 2007  Alan DeKok <aland@deployingradius.com>
22  */
23
24 #include <freeradius-devel/ident.h>
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 #include <freeradius-devel/event.h>
30 #include <freeradius-devel/detail.h>
31 #include <freeradius-devel/radius_snmp.h>
32
33 #include <freeradius-devel/rad_assert.h>
34
35 #include <signal.h>
36 #include <fcntl.h>
37
38 #ifdef HAVE_SYS_WAIT_H
39 #       include <sys/wait.h>
40 #endif
41
42 #define USEC (1000000)
43
44 extern pid_t radius_pid;
45 extern int dont_fork;
46 extern int check_config;
47 extern void force_log_reopen(void);
48
49 /*
50  *      Ridiculous amounts of local state.
51  */
52 static fr_event_list_t  *el = NULL;
53 static fr_packet_list_t *pl = NULL;
54 static int                      request_num_counter = 0;
55 static struct timeval           now;
56 static time_t                   start_time;
57 static int                      have_children;
58 static int                      has_detail_listener = FALSE;
59 static int                      just_started = FALSE;
60
61 #ifndef __MINGW32__
62 static int self_pipe[2];
63 #endif
64
65 #ifdef HAVE_PTHREAD_H
66 #ifdef WITH_PROXY
67 static pthread_mutex_t  proxy_mutex;
68 #endif
69
70 #define PTHREAD_MUTEX_LOCK if (have_children) pthread_mutex_lock
71 #define PTHREAD_MUTEX_UNLOCK if (have_children) pthread_mutex_unlock
72 #else
73 /*
74  *      This is easier than ifdef's throughout the code.
75  */
76 #define PTHREAD_MUTEX_LOCK(_x)
77 #define PTHREAD_MUTEX_UNLOCK(_x)
78 #define thread_pool_addrequest radius_handle_request
79 #endif
80
81 #define INSERT_EVENT(_function, _ctx) if (!fr_event_insert(el, _function, _ctx, &((_ctx)->when), &((_ctx)->ev))) { _rad_panic(__FILE__, __LINE__, "Failed to insert event"); }
82
83 #ifdef WITH_PROXY
84 static fr_packet_list_t *proxy_list = NULL;
85
86 /*
87  *      We keep the proxy FD's here.  The RADIUS Id's are marked
88  *      "allocated" per Id, via a bit per proxy FD.
89  */
90 static int              proxy_fds[32];
91 static rad_listen_t     *proxy_listeners[32];
92 #else
93 #define remove_from_proxy_hash(foo)
94 #endif
95
96 static void request_post_handler(REQUEST *request);
97 static void wait_a_bit(void *ctx);
98 static void event_socket_handler(fr_event_list_t *xel, UNUSED int fd, void *ctx);
99
100 static void NEVER_RETURNS _rad_panic(const char *file, unsigned int line,
101                                     const char *msg)
102 {
103         radlog(L_ERR, "[%s:%d] %s", file, line, msg);
104         _exit(1);
105 }
106
107 #define rad_panic(x) _rad_panic(__FILE__, __LINE__, x)
108
109
110 static void tv_add(struct timeval *tv, int usec_delay)
111 {
112         if (usec_delay > USEC) {
113                 tv->tv_sec += usec_delay / USEC;
114                 usec_delay %= USEC;
115         }
116         tv->tv_usec += usec_delay;
117
118         if (tv->tv_usec > USEC) {
119                 tv->tv_usec -= USEC;
120                 tv->tv_sec++;
121         }
122 }
123
124 #ifdef WITH_SNMP
125 static void snmp_inc_counters(REQUEST *request)
126 {
127         if (!request->root->do_snmp) return;
128
129         if (request->master_state == REQUEST_COUNTED) return;
130
131         if ((request->listener->type != RAD_LISTEN_AUTH) &&
132             (request->listener->type != RAD_LISTEN_ACCT)) return;
133
134         /*
135          *      Update the SNMP statistics.
136          *
137          *      Note that we do NOT do this in a child thread.
138          *      Instead, we update the stats when a request is
139          *      deleted, because only the main server thread calls
140          *      this function, which makes it thread-safe.
141          */
142         switch (request->reply->code) {
143         case PW_AUTHENTICATION_ACK:
144                 rad_snmp.auth.total_responses++;
145                 rad_snmp.auth.total_access_accepts++;
146                 if (request->client && request->client->auth) {
147                         request->client->auth->accepts++;
148                 }
149                 break;
150
151         case PW_AUTHENTICATION_REJECT:
152                 rad_snmp.auth.total_responses++;
153                 rad_snmp.auth.total_access_rejects++;
154                 if (request->client && request->client->auth) {
155                         request->client->auth->rejects++;
156                 }
157                 break;
158
159         case PW_ACCESS_CHALLENGE:
160                 rad_snmp.auth.total_responses++;
161                 rad_snmp.auth.total_access_challenges++;
162                 if (request->client && request->client->auth) {
163                         request->client->auth->challenges++;
164                 }
165                 break;
166
167 #ifdef WITH_ACCOUNTING
168         case PW_ACCOUNTING_RESPONSE:
169                 rad_snmp.acct.total_responses++;
170                 if (request->client && request->client->acct) {
171                         request->client->acct->responses++;
172                 }
173                 break;
174 #endif
175
176                 /*
177                  *      No response, it must have been a bad
178                  *      authenticator.
179                  */
180         case 0:
181                 if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
182                         rad_snmp.auth.total_bad_authenticators++;
183                         if (request->client && request->client->auth) {
184                                 request->client->auth->bad_authenticators++;
185                         }
186                 }
187                 break;
188
189         default:
190                 break;
191         }
192
193         request->master_state = REQUEST_COUNTED;
194 }
195 #else
196 #define snmp_inc_counters(_x)
197 #endif
198
199
200 static void remove_from_request_hash(REQUEST *request)
201 {
202         if (!request->in_request_hash) return;
203
204         fr_packet_list_yank(pl, request->packet);
205         request->in_request_hash = FALSE;
206
207         snmp_inc_counters(request);
208 }
209
210
211 #ifdef WITH_PROXY
212 static REQUEST *lookup_in_proxy_hash(RADIUS_PACKET *reply)
213 {
214         RADIUS_PACKET **proxy_p;
215         REQUEST *request;
216
217         PTHREAD_MUTEX_LOCK(&proxy_mutex);
218         proxy_p = fr_packet_list_find_byreply(proxy_list, reply);
219
220         if (!proxy_p) {
221                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
222                 return NULL;
223         }
224
225         request = fr_packet2myptr(REQUEST, proxy, proxy_p);
226
227         if (!request) {
228                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
229                 return NULL;
230         }
231
232         request->num_proxied_responses++;
233
234         /*
235          *      Catch the most common case of everything working
236          *      correctly.
237          */
238         if (request->num_proxied_requests == request->num_proxied_responses) {
239                 fr_packet_list_yank(proxy_list, request->proxy);
240                 fr_packet_list_id_free(proxy_list, request->proxy);
241                 request->in_proxy_hash = FALSE;
242         }
243
244         /*
245          *      On the FIRST reply, decrement the count of outstanding
246          *      requests.  Note that this is NOT the count of sent
247          *      packets, but whether or not the home server has
248          *      responded at all.
249          */
250         if (!request->proxy_reply &&
251             request->home_server->currently_outstanding) {
252                 request->home_server->currently_outstanding--;
253         }
254
255         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
256
257         return request;
258 }
259
260
261 static void remove_from_proxy_hash(REQUEST *request)
262 {
263         if (!request->in_proxy_hash) return;
264
265         PTHREAD_MUTEX_LOCK(&proxy_mutex);
266         fr_packet_list_yank(proxy_list, request->proxy);
267         fr_packet_list_id_free(proxy_list, request->proxy);
268
269         /*
270          *      The home server hasn't replied, but we've given up on
271          *      this request.  Don't count this request against the
272          *      home server.
273          */
274         if (!request->proxy_reply &&
275             request->home_server->currently_outstanding) {
276                 request->home_server->currently_outstanding--;
277         }
278
279         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
280
281         request->in_proxy_hash = FALSE;
282 }
283
284
285 static int insert_into_proxy_hash(REQUEST *request)
286 {
287         int i, proxy;
288         char buf[128];
289
290         rad_assert(request->proxy != NULL);
291         rad_assert(proxy_list != NULL);
292
293         request->proxy->sockfd = -1;
294
295         PTHREAD_MUTEX_LOCK(&proxy_mutex);
296
297         request->home_server->currently_outstanding++;
298         request->home_server->total_requests_sent++;
299
300         /*
301          *      On overflow, back up to ~0.
302          */
303         if (!request->home_server->total_requests_sent) {
304                 request->home_server->total_requests_sent--;
305         }
306
307         if (!fr_packet_list_id_alloc(proxy_list, request->proxy)) {
308                 int found;
309                 rad_listen_t *proxy_listener;
310
311                 /*
312                  *      Allocate a new proxy fd.  This function adds
313                  *      it to the tail of the list of listeners.  With
314                  *      some care, this can be thread-safe.
315                  */
316                 proxy_listener = proxy_new_listener();
317                 if (!proxy_listener) {
318                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
319                         DEBUG2("ERROR: Failed to create a new socket for proxying requests.");
320                         return 0;
321                 }
322
323                 /*
324                  *      Cache it locally.
325                  */
326                 found = -1;
327                 proxy = proxy_listener->fd;
328                 for (i = 0; i < 32; i++) {
329                         /*
330                          *      Found a free entry.  Save the socket,
331                          *      and remember where we saved it.
332                          */
333                         if (proxy_fds[(proxy + i) & 0x1f] == -1) {
334                                 found = (proxy + i) & 0x1f;
335                                 proxy_fds[found] = proxy;
336                                 proxy_listeners[found] = proxy_listener;
337                                 break;
338                         }
339                 }
340                 rad_assert(found >= 0);
341
342                 if (!fr_packet_list_socket_add(proxy_list, proxy_listener->fd)) {
343                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
344                         DEBUG2("ERROR: Failed to create a new socket for proxying requests.");
345                         return 0;
346
347                 }
348
349                 if (!fr_packet_list_id_alloc(proxy_list, request->proxy)) {
350                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
351                         DEBUG2("ERROR: Failed to create a new socket for proxying requests.");
352                         return 0;
353                 }
354
355                 /*
356                  *      Signal the main thread to add the new FD to the list
357                  *      of listening FD's.
358                  */
359                 radius_signal_self(RADIUS_SIGNAL_SELF_NEW_FD);
360         }
361         rad_assert(request->proxy->sockfd >= 0);
362
363         /*
364          *      FIXME: Hack until we get rid of rad_listen_t, and put
365          *      the information into the packet_list.
366          */
367         proxy = -1;
368         for (i = 0; i < 32; i++) {
369                 if (proxy_fds[i] == request->proxy->sockfd) {
370                         proxy = i;
371                         break;
372                 }
373         }
374
375         if (proxy < 0) {
376                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
377                 DEBUG2("ERROR: All sockets are full.");
378                 return 0;
379         }
380
381         rad_assert(proxy_fds[proxy] != -1);
382         rad_assert(proxy_listeners[proxy] != NULL);
383         request->proxy_listener = proxy_listeners[proxy];
384
385         if (!fr_packet_list_insert(proxy_list, &request->proxy)) {
386                 fr_packet_list_id_free(proxy_list, request->proxy);
387                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
388                 DEBUG2("ERROR: Failed to insert entry into proxy list");
389                 return 0;
390         }
391
392         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
393
394         DEBUG3(" proxy: allocating destination %s port %d - Id %d",
395                inet_ntop(request->proxy->dst_ipaddr.af,
396                          &request->proxy->dst_ipaddr.ipaddr, buf, sizeof(buf)),
397                request->proxy->dst_port,
398                request->proxy->id);
399
400         request->in_proxy_hash = TRUE;
401
402         return 1;
403 }
404
405
406 /*
407  *      Called as BOTH an event, and in-line from other functions.
408  */
409 static void wait_for_proxy_id_to_expire(void *ctx)
410 {
411         REQUEST *request = ctx;
412         home_server *home = request->home_server;
413
414         rad_assert(request->magic == REQUEST_MAGIC);
415         rad_assert(request->proxy != NULL);
416
417         if (!fr_event_now(el, &now)) gettimeofday(&now, NULL);
418         request->when = request->proxy_when;
419         request->when.tv_sec += home->response_window;
420
421         if ((request->num_proxied_requests == request->num_proxied_responses) ||
422             timercmp(&now, &request->when, >)) {
423                 if (request->packet) {
424                         DEBUG2("Cleaning up request %d ID %d with timestamp +%d",
425                                request->number, request->packet->id,
426                                (unsigned int) (request->timestamp - start_time));
427                 } else {
428                         DEBUG2("Cleaning up request %d with timestamp +%d",
429                                request->number,
430                                (unsigned int) (request->timestamp - start_time));
431                 }
432                 fr_event_delete(el, &request->ev);
433                 remove_from_proxy_hash(request);
434                 remove_from_request_hash(request);
435                 request_free(&request);
436                 return;
437         }
438
439         INSERT_EVENT(wait_for_proxy_id_to_expire, request);
440 }
441 #endif
442
443 /*
444  *      If we don't have pthreads, we MAY be proxying.
445  *      If we don't have either, then this function isn't necessary.
446  */
447 #if defined(HAVE_PTHREAD_H) || defined(WITH_PROXY)
448 static void wait_for_child_to_die(void *ctx)
449 {
450         REQUEST *request = ctx;
451
452         rad_assert(request->magic == REQUEST_MAGIC);
453
454         if ((request->child_state == REQUEST_QUEUED) |
455             (request->child_state == REQUEST_RUNNING)) {
456                 request->delay += (request->delay >> 1);
457                 tv_add(&request->when, request->delay);
458
459                 DEBUG2("Child is still stuck for request %d", request->number);
460
461                 INSERT_EVENT(wait_for_child_to_die, request);
462                 return;
463         }
464
465         DEBUG2("Child is finally responsive for request %d", request->number);
466         remove_from_request_hash(request);
467
468 #ifdef WITH_PROXY
469         if (request->proxy) {
470                 wait_for_proxy_id_to_expire(request);
471                 return;
472         }
473 #endif
474
475         request_free(&request);
476 }
477 #endif
478
479 static void cleanup_delay(void *ctx)
480 {
481         REQUEST *request = ctx;
482
483         rad_assert(request->magic == REQUEST_MAGIC);
484         rad_assert((request->child_state == REQUEST_CLEANUP_DELAY) ||
485                    (request->child_state == REQUEST_DONE));
486
487         remove_from_request_hash(request);
488
489 #ifdef WITH_PROXY
490         if (request->proxy && request->in_proxy_hash) {
491                 wait_for_proxy_id_to_expire(request);
492                 return;
493         }
494 #endif
495
496         DEBUG2("Cleaning up request %d ID %d with timestamp +%d",
497                request->number, request->packet->id,
498                (unsigned int) (request->timestamp - start_time));
499
500         fr_event_delete(el, &request->ev);
501         request_free(&request);
502 }
503
504
505 static void reject_delay(void *ctx)
506 {
507         REQUEST *request = ctx;
508
509         rad_assert(request->magic == REQUEST_MAGIC);
510         rad_assert(request->child_state == REQUEST_REJECT_DELAY);
511
512         DEBUG2("Sending delayed reject for request %d", request->number);
513
514         request->listener->send(request->listener, request);
515
516         request->when.tv_sec += request->root->cleanup_delay;
517         request->child_state = REQUEST_CLEANUP_DELAY;
518
519         INSERT_EVENT(cleanup_delay, request);
520 }
521
522
523 #ifdef WITH_PROXY
524 static void revive_home_server(void *ctx)
525 {
526         home_server *home = ctx;
527         char buffer[128];
528
529         home->state = HOME_STATE_ALIVE;
530         radlog(L_INFO, "PROXY: Marking home server %s port %d alive again... we have no idea if it really is alive or not.",
531                inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
532                          buffer, sizeof(buffer)),
533                home->port);
534         home->currently_outstanding = 0;
535 }
536
537
538 static void no_response_to_ping(void *ctx)
539 {
540         REQUEST *request = ctx;
541         home_server *home = request->home_server;
542         char buffer[128];
543
544         home->num_received_pings = 0;
545
546         DEBUG2("No response to status check %d from home server %s port %d",
547                request->number,
548                inet_ntop(request->proxy->dst_ipaddr.af,
549                          &request->proxy->dst_ipaddr.ipaddr,
550                          buffer, sizeof(buffer)),
551                request->proxy->dst_port);
552
553         wait_for_proxy_id_to_expire(request);
554 }
555
556
557 static void received_response_to_ping(REQUEST *request)
558 {
559         home_server *home = request->home_server;
560         char buffer[128];
561
562         home->num_received_pings++;
563
564         DEBUG2("Received response to status check %d (%d in current sequence)",
565                request->number, home->num_received_pings);
566
567         if (home->num_received_pings < home->num_pings_to_alive) {
568                 wait_for_proxy_id_to_expire(request);
569                 return;
570         }
571
572         radlog(L_INFO, "PROXY: Marking home server %s port %d alive",
573                inet_ntop(request->proxy->dst_ipaddr.af,
574                          &request->proxy->dst_ipaddr.ipaddr,
575                          buffer, sizeof(buffer)),
576                request->proxy->dst_port);
577
578         if (!fr_event_delete(el, &home->ev)) {
579                 DEBUG2("Hmm... no event for home server, WTF?");
580         }
581
582         if (!fr_event_delete(el, &request->ev)) {
583                 DEBUG2("Hmm... no event for request, WTF?");
584         }
585
586         wait_for_proxy_id_to_expire(request);
587
588         home->state = HOME_STATE_ALIVE;
589         home->currently_outstanding = 0;
590 }
591
592
593 static void ping_home_server(void *ctx)
594 {
595         uint32_t jitter;
596         home_server *home = ctx;
597         REQUEST *request;
598         VALUE_PAIR *vp;
599
600         if (home->state == HOME_STATE_ALIVE) {
601                 radlog(L_INFO, "Suspicious proxy state... continuing");
602                 return;
603         }
604
605         request = request_alloc();
606         request->number = request_num_counter++;
607
608         request->proxy = rad_alloc(1);
609         rad_assert(request->proxy != NULL);
610
611         fr_event_now(el, &request->when);
612         home->when = request->when;
613
614         if (home->ping_check == HOME_PING_CHECK_STATUS_SERVER) {
615                 request->proxy->code = PW_STATUS_SERVER;
616
617                 radius_pairmake(request, &request->proxy->vps,
618                                 "Message-Authenticator", "0x00", T_OP_SET);
619
620         } else if (home->type == HOME_TYPE_AUTH) {
621                 request->proxy->code = PW_AUTHENTICATION_REQUEST;
622
623                 radius_pairmake(request, &request->proxy->vps,
624                                 "User-Name", home->ping_user_name, T_OP_SET);
625                 radius_pairmake(request, &request->proxy->vps,
626                                 "User-Password", home->ping_user_password, T_OP_SET);
627                 radius_pairmake(request, &request->proxy->vps,
628                                 "Service-Type", "Authenticate-Only", T_OP_SET);
629                 radius_pairmake(request, &request->proxy->vps,
630                                 "Message-Authenticator", "0x00", T_OP_SET);
631
632         } else {
633 #ifdef WITH_ACCOUNTING
634                 request->proxy->code = PW_ACCOUNTING_REQUEST;
635                 
636                 radius_pairmake(request, &request->proxy->vps,
637                                 "User-Name", home->ping_user_name, T_OP_SET);
638                 radius_pairmake(request, &request->proxy->vps,
639                                 "Acct-Status-Type", "Stop", T_OP_SET);
640                 radius_pairmake(request, &request->proxy->vps,
641                                 "Acct-Session-Id", "00000000", T_OP_SET);
642                 vp = radius_pairmake(request, &request->proxy->vps,
643                                      "Event-Timestamp", "0", T_OP_SET);
644                 vp->vp_date = now.tv_sec;
645 #else
646                 rad_assert("Internal sanity check failed");
647 #endif
648         }
649
650         radius_pairmake(request, &request->proxy->vps,
651                         "NAS-Identifier", "Status Check. Are you alive?",
652                         T_OP_SET);
653
654         request->proxy->dst_ipaddr = home->ipaddr;
655         request->proxy->dst_port = home->port;
656         request->home_server = home;
657
658         rad_assert(request->proxy_listener == NULL);
659
660         if (!insert_into_proxy_hash(request)) {
661                 DEBUG2("ERROR: Failed inserting status check %d into proxy hash.  Discarding it.",
662                        request->number);
663                 request_free(&request);
664                 return;
665         }
666         rad_assert(request->proxy_listener != NULL);
667         request->proxy_listener->send(request->proxy_listener,
668                                       request);
669
670         request->next_callback = NULL;
671         request->child_state = REQUEST_PROXIED;
672         request->when.tv_sec += home->ping_timeout;;
673
674         INSERT_EVENT(no_response_to_ping, request);
675
676         /*
677          *      Add +/- 2s of jitter, as suggested in RFC 3539
678          *      and in the Issues and Fixes draft.
679          */
680         home->when.tv_sec += home->ping_interval - 2;
681
682         jitter = fr_rand();
683         jitter ^= (jitter >> 10);
684         jitter &= ((1 << 23) - 1); /* 22 bits of 1 */
685
686         tv_add(&home->when, jitter);
687
688
689         INSERT_EVENT(ping_home_server, home);
690 }
691
692
693 static void check_for_zombie_home_server(REQUEST *request)
694 {
695         home_server *home;
696         struct timeval when;
697         char buffer[128];
698
699         home = request->home_server;
700
701         if (home->state != HOME_STATE_ZOMBIE) return;
702
703         when = home->zombie_period_start;
704         when.tv_sec += home->zombie_period;
705
706         fr_event_now(el, &now);
707         if (timercmp(&now, &when, <)) {
708                 return;
709         }
710
711         /*
712          *      It's been a zombie for too long, mark it as
713          *      dead.
714          */
715         radlog(L_INFO, "PROXY: Marking home server %s port %d as dead.",
716                inet_ntop(request->proxy->dst_ipaddr.af,
717                          &request->proxy->dst_ipaddr.ipaddr,
718                          buffer, sizeof(buffer)),
719                request->proxy->dst_port);
720         home->state = HOME_STATE_IS_DEAD;
721         home->num_received_pings = 0;
722         home->when = request->when;
723
724         if (home->ping_check != HOME_PING_CHECK_NONE) {
725                 rad_assert((home->ping_check == HOME_PING_CHECK_STATUS_SERVER) ||
726                            (home->ping_user_name != NULL));
727                 home->when.tv_sec += home->ping_interval;
728
729                 INSERT_EVENT(ping_home_server, home);
730         } else {
731                 home->when.tv_sec += home->revive_interval;
732
733                 INSERT_EVENT(revive_home_server, home);
734         }
735 }
736
737 static int proxy_to_virtual_server(REQUEST *request);
738
739 static int virtual_server_handler(UNUSED REQUEST *request)
740 {
741         proxy_to_virtual_server(request);
742         return 0;
743 }
744
745 static void proxy_fallback_handler(REQUEST *request)
746 {
747         /*
748          *      A proper time is required for wait_a_bit.
749          */
750         request->delay = USEC / 10;
751         gettimeofday(&now, NULL);
752         request->next_when = now;
753         tv_add(&request->next_when, request->delay);
754         request->next_callback = wait_a_bit;
755
756         /*
757          *      Re-queue the request.
758          */
759         request->child_state = REQUEST_QUEUED;
760         
761         rad_assert(request->proxy != NULL);
762         if (!thread_pool_addrequest(request, virtual_server_handler)) {
763                 request->child_state = REQUEST_DONE;
764         }
765
766 #ifdef HAVE_PTHREAD_H
767         /*
768          *      MAY free the request if we're over max_request_time,
769          *      AND we're not in threaded mode!
770          *
771          *      Note that we call this ONLY if we're threaded, as
772          *      if we're NOT threaded, request_post_handler() calls
773          *      wait_a_bit(), which means that "request" may not
774          *      exist any more...
775          */
776         if (have_children) wait_a_bit(request);
777 #endif
778 }
779
780
781 static int setup_post_proxy_fail(REQUEST *request)
782 {
783         DICT_VALUE *dval = NULL;
784         VALUE_PAIR *vp;
785
786         if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
787                 dval = dict_valbyname(PW_POST_PROXY_TYPE, "Fail-Authentication");
788
789         } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
790                 dval = dict_valbyname(PW_POST_PROXY_TYPE, "Fail-Accounting");
791
792         } else {
793                 return 0;
794         }
795
796         if (!dval) dval = dict_valbyname(PW_POST_PROXY_TYPE, "Fail");
797
798         if (!dval) {
799                 pairdelete(&request->config_items, PW_POST_PROXY_TYPE);
800                 return 0;
801         }
802
803         vp = pairfind(request->config_items, PW_POST_PROXY_TYPE);
804         if (!vp) vp = radius_paircreate(request, &request->config_items,
805                                         PW_POST_PROXY_TYPE, PW_TYPE_INTEGER);
806         vp->vp_integer = dval->value;
807
808         rad_assert(request->proxy_reply == NULL);
809
810         return 1;
811 }
812
813
814 static int null_handler(UNUSED REQUEST *request)
815 {
816         return 0;
817 }
818
819 static void post_proxy_fail_handler(REQUEST *request)
820 {
821         /*
822          *      A proper time is required for wait_a_bit.
823          */
824         request->delay = USEC / 10;
825         gettimeofday(&now, NULL);
826
827         /*
828          *      Not set up to run Post-Proxy-Type = Fail.
829          *
830          *      Mark the request as still running, and figure out what
831          *      to do next.
832          */
833         if (!setup_post_proxy_fail(request)) {
834                 request->child_state = REQUEST_RUNNING;
835                 request_post_handler(request);
836
837         } else {
838                 /*
839                  *      Re-queue the request.
840                  */
841                 request->child_state = REQUEST_QUEUED;
842
843                 /*
844                  *      There is a post-proxy-type of fail.  We run
845                  *      the request through the pre/post proxy
846                  *      handlers, just like it was a real proxied
847                  *      request.  However, we set the per-request
848                  *      handler to NULL, as we don't want to do
849                  *      anything else.
850                  *
851                  *      Note that when we're not threaded, this will
852                  *      process the request even if it's greater than
853                  *      max_request_time.  That's not fatal.
854                  */
855                 request->priority = 0;
856                 rad_assert(request->proxy != NULL);
857                 thread_pool_addrequest(request, null_handler);
858         }
859
860         /*
861          *      MAY free the request if we're over max_request_time,
862          *      AND we're not in threaded mode!
863          *
864          *      Note that we call this ONLY if we're threaded, as
865          *      if we're NOT threaded, request_post_handler() calls
866          *      wait_a_bit(), which means that "request" may not
867          *      exist any more...
868          */
869         if (have_children) wait_a_bit(request);
870 }
871
872
873 /* maybe check this against wait_for_proxy_id_to_expire? */
874 static void no_response_to_proxied_request(void *ctx)
875 {
876         REQUEST *request = ctx;
877         home_server *home;
878         char buffer[128];
879
880         rad_assert(request->magic == REQUEST_MAGIC);
881         rad_assert(request->child_state == REQUEST_PROXIED);
882
883         /*
884          *      If we've failed over to an internal home server,
885          *      replace the callback with the correct one.  This
886          *      is due to locking issues with child threads...
887          */
888         if (request->home_server->server) {
889                 wait_a_bit(request);
890                 return;
891         }
892
893         radlog(L_ERR, "Rejecting request %d due to lack of any response from home server %s port %d",
894                request->number,
895                inet_ntop(request->proxy->dst_ipaddr.af,
896                          &request->proxy->dst_ipaddr.ipaddr,
897                          buffer, sizeof(buffer)),
898                request->proxy->dst_port);
899
900         check_for_zombie_home_server(request);
901
902         home = request->home_server;
903
904         post_proxy_fail_handler(request);
905
906         /*
907          *      Don't touch request due to race conditions
908          */
909         if (home->state == HOME_STATE_IS_DEAD) {
910                 rad_assert(home->ev != NULL); /* or it will never wake up */
911                 return;
912         }
913
914         /*
915          *      Enable the zombie period when we notice that the home
916          *      server hasn't responded.  We also back-date the start
917          *      of the zombie period to when the proxied request was
918          *      sent.
919          */
920         if (home->state == HOME_STATE_ALIVE) {
921                 radlog(L_ERR, "PROXY: Marking home server %s port %d as zombie (it looks like it is dead).",
922                        inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
923                                  buffer, sizeof(buffer)),
924                        home->port);
925                 home->state = HOME_STATE_ZOMBIE;
926                 home->zombie_period_start = now;
927                 home->zombie_period_start.tv_sec -= home->response_window;
928                 return;
929         }
930 }
931 #endif
932
933 static void wait_a_bit(void *ctx)
934 {
935         struct timeval when;
936         REQUEST *request = ctx;
937         fr_event_callback_t callback = NULL;
938
939         rad_assert(request->magic == REQUEST_MAGIC);
940
941         switch (request->child_state) {
942         case REQUEST_QUEUED:
943         case REQUEST_RUNNING:
944                 when = request->received;
945                 when.tv_sec += request->root->max_request_time;
946
947                 /*
948                  *      Normally called from the event loop with the
949                  *      proper event loop time.  Otherwise, called from
950                  *      post proxy fail handler, which sets "now", and
951                  *      this call won't re-set it, because we're not
952                  *      in the event loop.
953                  */
954                 fr_event_now(el, &now);
955
956                 /*
957                  *      Request still has more time.  Continue
958                  *      waiting.
959                  */
960                 if (timercmp(&now, &when, <) ||
961                     ((request->listener->type == RAD_LISTEN_DETAIL) &&
962                      (request->child_state == REQUEST_QUEUED))) {
963                         if (request->delay < (USEC / 10)) {
964                                 request->delay = USEC / 10;
965                         }
966                         request->delay += request->delay >> 1;
967
968 #ifdef WITH_DETAIL
969                         /*
970                          *      Cap wait at some sane value for detail
971                          *      files.
972                          */
973                         if ((request->listener->type == RAD_LISTEN_DETAIL) &&
974                             (request->delay > (request->root->max_request_time * USEC))) {
975                                 request->delay = request->root->max_request_time * USEC;
976                         }
977 #endif
978
979                         request->when = now;
980                         tv_add(&request->when, request->delay);
981                         callback = wait_a_bit;
982                         break;
983                 }
984
985 #if defined(HAVE_PTHREAD_H) || defined(WITH_PROXY)
986                 /*
987                  *      A child thread MAY still be running on the
988                  *      request.  Ask the thread to stop working on
989                  *      the request.
990                  */
991                 if (have_children) {
992                         /* FIXME: kill unresponsive children? */
993
994                         /*
995                          *      Print this error message ONLY if
996                          *      there's a child currently processing
997                          *      the request.  As we don't have thread
998                          *      locks here, there may be race
999                          *      conditions on this check.  But it's
1000                          *      just an error message, so that's OK.
1001                          */
1002                         if (request->child_pid != NO_SUCH_CHILD_PID) {
1003                                 radlog(L_ERR, "WARNING: Unresponsive child (id %lu) for request %d, in module %s component %s",
1004                                (unsigned long)request->child_pid, request->number,
1005                                        request->module ? request->module : "<server core>",
1006                                        request->component ? request->component : "<server core>");
1007                         }
1008
1009                         request->master_state = REQUEST_STOP_PROCESSING;
1010                         
1011                         request->delay = USEC / 4;
1012                         tv_add(&request->when, request->delay);
1013                         callback = wait_for_child_to_die;
1014                         break;
1015                 }
1016 #endif
1017
1018                 /*
1019                  *      Else there are no child threads.  We probably
1020                  *      should have just marked the request as 'done'
1021                  *      elsewhere, like in the post-proxy-fail
1022                  *      handler.  But doing that would involve
1023                  *      checking for max_request_time in multiple
1024                  *      places, so this may be simplest.
1025                  */
1026                 request->child_state = REQUEST_DONE;
1027                 /* FALL-THROUGH */
1028
1029                 /*
1030                  *      Mark the request as no longer running,
1031                  *      and clean it up.
1032                  */
1033         case REQUEST_DONE:
1034 #ifdef HAVE_PTHREAD_H
1035                 request->child_pid = NO_SUCH_CHILD_PID;
1036 #endif
1037                 snmp_inc_counters(request);
1038                 cleanup_delay(request);
1039                 return;
1040
1041         case REQUEST_REJECT_DELAY:
1042         case REQUEST_CLEANUP_DELAY:
1043 #ifdef HAVE_PTHREAD_H
1044                 request->child_pid = NO_SUCH_CHILD_PID;
1045 #endif
1046                 snmp_inc_counters(request);
1047
1048         case REQUEST_PROXIED:
1049                 rad_assert(request->next_callback != NULL);
1050                 rad_assert(request->next_callback != wait_a_bit);
1051
1052                 request->when = request->next_when;
1053                 callback = request->next_callback;
1054                 request->next_callback = NULL;
1055                 break;
1056
1057         default:
1058                 rad_panic("Internal sanity check failure");
1059                 return;
1060         }
1061
1062         /*
1063          *      Something major went wrong.  Discard the request, and
1064          *      keep running.
1065          *
1066          *      FIXME: No idea why this happens or how to fix it...
1067          *      It seems to happen *only* when requests are proxied,
1068          *      and where the home server doesn't respond.  So it looks
1069          *      like a race condition above, but it happens in debug
1070          *      mode, with no threads...
1071          */
1072         if (!callback) {
1073                 DEBUG("WARNING: Internal sanity check failed in event handler for request %d: Discarding the request!", request->number);
1074                 fr_event_delete(el, &request->ev);
1075                 remove_from_proxy_hash(request);
1076                 remove_from_request_hash(request);
1077                 request_free(&request);
1078                 return;
1079         }
1080
1081         INSERT_EVENT(callback, request);
1082 }
1083
1084
1085 #ifdef WITH_PROXY
1086 static int process_proxy_reply(REQUEST *request)
1087 {
1088         int rcode;
1089         int post_proxy_type = 0;
1090         VALUE_PAIR *vp;
1091         
1092         /*
1093          *      Delete any reply we had accumulated until now.
1094          */
1095         pairfree(&request->reply->vps);
1096         
1097         /*
1098          *      Run the packet through the post-proxy stage,
1099          *      BEFORE playing games with the attributes.
1100          */
1101         vp = pairfind(request->config_items, PW_POST_PROXY_TYPE);
1102         if (vp) {
1103                 DEBUG2("  Found Post-Proxy-Type %s", vp->vp_strvalue);
1104                 post_proxy_type = vp->vp_integer;
1105         }
1106         
1107         rad_assert(request->home_pool != NULL);
1108         
1109         if (request->home_pool->virtual_server) {
1110                 const char *old_server = request->server;
1111                 
1112                 request->server = request->home_pool->virtual_server;
1113                 DEBUG2(" server %s {", request->server);
1114                 rcode = module_post_proxy(post_proxy_type, request);
1115                 DEBUG2(" }");
1116                 request->server = old_server;
1117         } else {
1118                 rcode = module_post_proxy(post_proxy_type, request);
1119         }
1120         
1121         /*
1122          *      There may NOT be a proxy reply, as we may be
1123          *      running Post-Proxy-Type = Fail.
1124          */
1125         if (request->proxy_reply) {
1126                 /*
1127                  *      Delete the Proxy-State Attributes from
1128                  *      the reply.  These include Proxy-State
1129                  *      attributes from us and remote server.
1130                  */
1131                 pairdelete(&request->proxy_reply->vps, PW_PROXY_STATE);
1132                 
1133                 /*
1134                  *      Add the attributes left in the proxy
1135                  *      reply to the reply list.
1136                  */
1137                 pairadd(&request->reply->vps, request->proxy_reply->vps);
1138                 request->proxy_reply->vps = NULL;
1139                 
1140                 /*
1141                  *      Free proxy request pairs.
1142                  */
1143                 pairfree(&request->proxy->vps);
1144         }
1145         
1146         switch (rcode) {
1147         default:  /* Don't do anything */
1148                 break;
1149         case RLM_MODULE_FAIL:
1150                 /* FIXME: debug print stuff */
1151                 request->child_state = REQUEST_DONE;
1152                 return 0;
1153                 
1154         case RLM_MODULE_HANDLED:
1155                 /* FIXME: debug print stuff */
1156                 request->child_state = REQUEST_DONE;
1157                 return 0;
1158         }
1159
1160         return 1;
1161 }
1162 #endif
1163
1164 static int request_pre_handler(REQUEST *request)
1165 {
1166         int rcode;
1167
1168         rad_assert(request->magic == REQUEST_MAGIC);
1169         rad_assert(request->packet != NULL);
1170
1171         request->child_state = REQUEST_RUNNING;
1172
1173         /*
1174          *      Don't decode the packet if it's an internal "fake"
1175          *      request.  Instead, just return so that the caller can
1176          *      process it.
1177          */
1178         if (request->packet->dst_port == 0) {
1179                 request->username = pairfind(request->packet->vps,
1180                                              PW_USER_NAME);
1181                 request->password = pairfind(request->packet->vps,
1182                                              PW_USER_PASSWORD);
1183                 return 1;
1184         }
1185
1186 #ifdef WITH_PROXY
1187         /*
1188          *      Put the decoded packet into it's proper place.
1189          */
1190         if (request->proxy_reply != NULL) {
1191                 rcode = request->proxy_listener->decode(request->proxy_listener,
1192                                                         request);
1193         } else
1194 #endif
1195         if (request->packet->vps == NULL) {
1196                 rcode = request->listener->decode(request->listener, request);
1197
1198         } else {
1199                 rcode = 0;
1200         }
1201
1202         if (rcode < 0) {
1203                 radlog(L_ERR, "%s Dropping packet without response.", librad_errstr);
1204                 request->child_state = REQUEST_DONE;
1205                 return 0;
1206         }
1207
1208 #ifdef WITH_PROXY
1209         if (!request->proxy)
1210 #endif
1211           {
1212                   request->username = pairfind(request->packet->vps,
1213                                              PW_USER_NAME);
1214
1215 #ifdef WITH_PROXY
1216         } else {
1217                 return process_proxy_reply(request);
1218 #endif
1219         }
1220
1221         return 1;
1222 }
1223
1224
1225 #ifdef WITH_PROXY
1226 /*
1227  *      Do state handling when we proxy a request.
1228  */
1229 static int proxy_request(REQUEST *request)
1230 {
1231         struct timeval when;
1232         char buffer[128];
1233
1234         if (request->home_server->server) {
1235                 DEBUG("ERROR: Cannot perform real proxying to a virtual server.");
1236                 return 0;
1237         }
1238
1239         if (!insert_into_proxy_hash(request)) {
1240                 DEBUG("ERROR: Failed inserting request into proxy hash.");
1241                 return 0;
1242         }
1243
1244         request->proxy_listener->encode(request->proxy_listener, request);
1245
1246         when = request->received;
1247         when.tv_sec += request->root->max_request_time;
1248
1249         gettimeofday(&request->proxy_when, NULL);
1250
1251         request->next_when = request->proxy_when;
1252         request->next_when.tv_sec += request->home_server->response_window;
1253
1254         rad_assert(request->home_server->response_window > 0);
1255
1256         if (timercmp(&when, &request->next_when, <)) {
1257                 request->next_when = when;
1258         }
1259         request->next_callback = no_response_to_proxied_request;
1260
1261         DEBUG2("Proxying request %d to home server %s port %d",
1262                request->number,
1263                inet_ntop(request->proxy->dst_ipaddr.af,
1264                          &request->proxy->dst_ipaddr.ipaddr,
1265                          buffer, sizeof(buffer)),
1266                request->proxy->dst_port);
1267
1268         /*
1269          *      Note that we set proxied BEFORE sending the packet.
1270          *
1271          *      Once we send it, the request is tainted, as
1272          *      another thread may have picked it up.  Don't
1273          *      touch it!
1274          */
1275         request->num_proxied_requests = 1;
1276         request->num_proxied_responses = 0;
1277 #ifdef HAVE_PTHREAD_H
1278         request->child_pid = NO_SUCH_CHILD_PID;
1279 #endif
1280         request->child_state = REQUEST_PROXIED;
1281         request->proxy_listener->send(request->proxy_listener,
1282                                       request);
1283         return 1;
1284 }
1285
1286
1287 /*
1288  *      "Proxy" the request by sending it to a new virtual server.
1289  */
1290 static int proxy_to_virtual_server(REQUEST *request)
1291 {
1292         REQUEST *fake;
1293         RAD_REQUEST_FUNP fun;
1294
1295         if (!request->home_server || !request->home_server->server) return 0;
1296
1297         if (request->parent) {
1298                 DEBUG2("WARNING: Cancelling proxy request to virtual server %s as this request was itself proxied.", request->home_server->server);
1299                 return 0;
1300         }
1301
1302         fake = request_alloc_fake(request);
1303         if (!fake) {
1304                 DEBUG2("WARNING: Out of memory");
1305                 return 0;
1306         }
1307
1308         fake->packet->vps = paircopy(request->proxy->vps);
1309         fake->server = request->home_server->server;
1310
1311         if (request->proxy->code == PW_AUTHENTICATION_REQUEST) {
1312                 fun = rad_authenticate;
1313
1314 #ifdef WITH_ACCOUNTING
1315         } else if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
1316                 fun = rad_accounting;
1317 #endif
1318
1319         } else {
1320                 DEBUG2("Unknown packet type %d", request->proxy->code);
1321                 return 0;
1322         }
1323
1324         DEBUG2(">>> Sending proxied request internally to virtual server.");
1325         radius_handle_request(fake, fun);
1326         DEBUG2("<<< Received proxied response from internal virtual server.");
1327
1328         request->proxy_reply = fake->reply;
1329         fake->reply = NULL;
1330
1331         request_free(&fake);
1332
1333         process_proxy_reply(request);
1334         fun(request);
1335
1336         return 2;               /* success, but NOT '1' !*/
1337 }
1338
1339
1340 /*
1341  *      Return 1 if we did proxy it, or the proxy attempt failed
1342  *      completely.  Either way, the caller doesn't touch the request
1343  *      any more if we return 1.
1344  */
1345 static int successfully_proxied_request(REQUEST *request)
1346 {
1347         int rcode;
1348         int pre_proxy_type = 0;
1349         VALUE_PAIR *realmpair;
1350         VALUE_PAIR *strippedname;
1351         VALUE_PAIR *vp;
1352         char *realmname;
1353         home_server *home;
1354         REALM *realm = NULL;
1355         home_pool_t *pool;
1356
1357         /*
1358          *      If it was already proxied, do nothing.
1359          *
1360          *      FIXME: This should really be a serious error.
1361          */
1362         if (request->in_proxy_hash) {
1363                 return 0;
1364         }
1365
1366         realmpair = pairfind(request->config_items, PW_PROXY_TO_REALM);
1367         if (!realmpair || (realmpair->length == 0)) {
1368                 return 0;
1369         }
1370
1371         realmname = (char *) realmpair->vp_strvalue;
1372
1373         realm = realm_find2(realmname);
1374         if (!realm) {
1375                 DEBUG2("ERROR: Cannot proxy to unknown realm %s", realmname);
1376                 return 0;
1377         }
1378
1379         /*
1380          *      Figure out which pool to use.
1381          */
1382         if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
1383                 pool = realm->auth_pool;
1384
1385 #ifdef WITH_ACCOUNTING
1386         } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
1387                 pool = realm->acct_pool;
1388 #endif
1389
1390         } else {
1391                 rad_panic("Internal sanity check failed");
1392         }
1393
1394         if (!pool) {
1395                 DEBUG2(" WARNING: Cancelling proxy to Realm %s, as the realm is local.",
1396                        realmname);
1397                 return 0;
1398         }
1399
1400         home = home_server_ldb(realmname, pool, request);
1401         if (!home) {
1402                 DEBUG2("ERROR: Failed to find live home server for realm %s",
1403                        realmname);
1404                 return -1;
1405         }
1406         request->home_pool = pool;
1407
1408         /*
1409          *      Remember that we sent the request to a Realm.
1410          */
1411         pairadd(&request->packet->vps,
1412                 pairmake("Realm", realmname, T_OP_EQ));
1413
1414 #ifdef WITH_DETAIL
1415         /*
1416          *      We read the packet from a detail file, AND it came from
1417          *      the server we're about to send it to.  Don't do that.
1418          */
1419         if ((request->packet->code == PW_ACCOUNTING_REQUEST) &&
1420             (request->listener->type == RAD_LISTEN_DETAIL) &&
1421             (home->ipaddr.af == AF_INET) &&
1422             (request->packet->src_ipaddr.af == AF_INET) &&
1423             (home->ipaddr.ipaddr.ip4addr.s_addr == request->packet->src_ipaddr.ipaddr.ip4addr.s_addr)) {
1424                 DEBUG2("    rlm_realm: Packet came from realm %s, proxy cancelled", realmname);
1425                 return 0;
1426         }
1427 #endif
1428
1429         /*
1430          *      Allocate the proxy packet, only if it wasn't already
1431          *      allocated by a module.  This check is mainly to support
1432          *      the proxying of EAP-TTLS and EAP-PEAP tunneled requests.
1433          *
1434          *      In those cases, the EAP module creates a "fake"
1435          *      request, and recursively passes it through the
1436          *      authentication stage of the server.  The module then
1437          *      checks if the request was supposed to be proxied, and
1438          *      if so, creates a proxy packet from the TUNNELED request,
1439          *      and not from the EAP request outside of the tunnel.
1440          *
1441          *      The proxy then works like normal, except that the response
1442          *      packet is "eaten" by the EAP module, and encapsulated into
1443          *      an EAP packet.
1444          */
1445         if (!request->proxy) {
1446                 if ((request->proxy = rad_alloc(TRUE)) == NULL) {
1447                         radlog(L_ERR|L_CONS, "no memory");
1448                         exit(1);
1449                 }
1450
1451                 /*
1452                  *      Copy the request, then look up name and
1453                  *      plain-text password in the copy.
1454                  *
1455                  *      Note that the User-Name attribute is the
1456                  *      *original* as sent over by the client.  The
1457                  *      Stripped-User-Name attribute is the one hacked
1458                  *      through the 'hints' file.
1459                  */
1460                 request->proxy->vps =  paircopy(request->packet->vps);
1461         }
1462
1463         /*
1464          *      Strip the name, if told to.
1465          *
1466          *      Doing it here catches the case of proxied tunneled
1467          *      requests.
1468          */
1469         if (realm->striprealm == TRUE &&
1470            (strippedname = pairfind(request->proxy->vps, PW_STRIPPED_USER_NAME)) != NULL) {
1471                 /*
1472                  *      If there's a Stripped-User-Name attribute in
1473                  *      the request, then use THAT as the User-Name
1474                  *      for the proxied request, instead of the
1475                  *      original name.
1476                  *
1477                  *      This is done by making a copy of the
1478                  *      Stripped-User-Name attribute, turning it into
1479                  *      a User-Name attribute, deleting the
1480                  *      Stripped-User-Name and User-Name attributes
1481                  *      from the vps list, and making the new
1482                  *      User-Name the head of the vps list.
1483                  */
1484                 vp = pairfind(request->proxy->vps, PW_USER_NAME);
1485                 if (!vp) {
1486                         vp = radius_paircreate(request, NULL,
1487                                                PW_USER_NAME, PW_TYPE_STRING);
1488                         rad_assert(vp != NULL); /* handled by above function */
1489                         /* Insert at the START of the list */
1490                         vp->next = request->proxy->vps;
1491                         request->proxy->vps = vp;
1492                 }
1493                 memcpy(vp->vp_strvalue, strippedname->vp_strvalue,
1494                        sizeof(vp->vp_strvalue));
1495                 vp->length = strippedname->length;
1496
1497                 /*
1498                  *      Do NOT delete Stripped-User-Name.
1499                  */
1500         }
1501
1502         /*
1503          *      If there is no PW_CHAP_CHALLENGE attribute but
1504          *      there is a PW_CHAP_PASSWORD we need to add it
1505          *      since we can't use the request authenticator
1506          *      anymore - we changed it.
1507          */
1508         if (pairfind(request->proxy->vps, PW_CHAP_PASSWORD) &&
1509             pairfind(request->proxy->vps, PW_CHAP_CHALLENGE) == NULL) {
1510                 vp = radius_paircreate(request, &request->proxy->vps,
1511                                        PW_CHAP_CHALLENGE, PW_TYPE_OCTETS);
1512                 vp->length = AUTH_VECTOR_LEN;
1513                 memcpy(vp->vp_strvalue, request->packet->vector, AUTH_VECTOR_LEN);
1514         }
1515
1516         /*
1517          *      The RFC's say we have to do this, but FreeRADIUS
1518          *      doesn't need it.
1519          */
1520         vp = radius_paircreate(request, &request->proxy->vps,
1521                                PW_PROXY_STATE, PW_TYPE_OCTETS);
1522         snprintf(vp->vp_strvalue, sizeof(vp->vp_strvalue), "%d",
1523                  request->packet->id);
1524         vp->length = strlen(vp->vp_strvalue);
1525
1526         /*
1527          *      Should be done BEFORE inserting into proxy hash, as
1528          *      pre-proxy may use this information, or change it.
1529          */
1530         request->proxy->code = request->packet->code;
1531         request->proxy->dst_ipaddr = home->ipaddr;
1532         request->proxy->dst_port = home->port;
1533         request->home_server = home;
1534
1535         /*
1536          *      Call the pre-proxy routines.
1537          */
1538         vp = pairfind(request->config_items, PW_PRE_PROXY_TYPE);
1539         if (vp) {
1540                 DEBUG2("  Found Pre-Proxy-Type %s", vp->vp_strvalue);
1541                 pre_proxy_type = vp->vp_integer;
1542         }
1543
1544         rad_assert(request->home_pool != NULL);
1545
1546         if (request->home_pool->virtual_server) {
1547                 const char *old_server = request->server;
1548                 
1549                 request->server = request->home_pool->virtual_server;
1550                 DEBUG2(" server %s {", request->server);
1551                 rcode = module_pre_proxy(pre_proxy_type, request);
1552                 DEBUG2(" }");
1553                         request->server = old_server;
1554         } else {
1555                 rcode = module_pre_proxy(pre_proxy_type, request);
1556         }
1557         switch (rcode) {
1558         case RLM_MODULE_FAIL:
1559         case RLM_MODULE_INVALID:
1560         case RLM_MODULE_NOTFOUND:
1561         case RLM_MODULE_USERLOCK:
1562         default:
1563                 /* FIXME: debug print failed stuff */
1564                 return -1;
1565
1566         case RLM_MODULE_REJECT:
1567         case RLM_MODULE_HANDLED:
1568                 return 0;
1569
1570         /*
1571          *      Only proxy the packet if the pre-proxy code succeeded.
1572          */
1573         case RLM_MODULE_NOOP:
1574         case RLM_MODULE_OK:
1575         case RLM_MODULE_UPDATED:
1576                 break;
1577         }
1578
1579         /*
1580          *      If it's a fake request, don't send the proxy
1581          *      packet.  The outer tunnel session will take
1582          *      care of doing that.
1583          */
1584         if (request->packet->dst_port == 0) {
1585                 request->home_server = NULL;
1586                 return 1;
1587         }
1588
1589         if (request->home_server->server) {
1590                 return proxy_to_virtual_server(request);
1591         }
1592
1593         if (!proxy_request(request)) {
1594                 DEBUG("ERROR: Failed to proxy request %d", request->number);
1595                 return -1;
1596         }
1597         
1598         return 1;
1599 }
1600 #endif
1601
1602
1603 static void request_post_handler(REQUEST *request)
1604 {
1605         int child_state = -1;
1606         struct timeval when;
1607         VALUE_PAIR *vp;
1608
1609         if ((request->master_state == REQUEST_STOP_PROCESSING) ||
1610             (request->parent &&
1611              (request->parent->master_state == REQUEST_STOP_PROCESSING))) {
1612                 DEBUG2("Request %d was cancelled.", request->number);
1613 #ifdef HAVE_PTHREAD_H
1614                 request->child_pid = NO_SUCH_CHILD_PID;
1615 #endif
1616                 request->child_state = REQUEST_DONE;
1617                 return;
1618         }
1619
1620         if (request->child_state != REQUEST_RUNNING) {
1621                 rad_panic("Internal sanity check failed");
1622         }
1623
1624         if ((request->reply->code == 0) &&
1625             ((vp = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL) &&
1626             (vp->vp_integer == PW_AUTHTYPE_REJECT)) {
1627                 request->reply->code = PW_AUTHENTICATION_REJECT;
1628         }
1629
1630 #ifdef WITH_PROXY
1631         if (request->root->proxy_requests &&
1632             !request->in_proxy_hash &&
1633             (request->reply->code == 0) &&
1634             (request->packet->dst_port != 0) &&
1635             (request->packet->code != PW_STATUS_SERVER)) {
1636                 int rcode = successfully_proxied_request(request);
1637
1638                 if (rcode == 1) return;
1639
1640                 /*
1641                  *      Failed proxying it (dead home servers, etc.)
1642                  *      Run it through Post-Proxy-Type = Fail, and
1643                  *      respond to the request.
1644                  *
1645                  *      Note that we're in a child thread here, so we
1646                  *      do NOT re-schedule the request.  Instead, we
1647                  *      do what we would have done, which is run the
1648                  *      pre-handler, a NULL request handler, and then
1649                  *      the post handler.
1650                  */
1651                 if ((rcode < 0) && setup_post_proxy_fail(request)) {
1652                         request_pre_handler(request);
1653                 }
1654
1655                 /*
1656                  *      Else we weren't supposed to proxy it,
1657                  *      OR we proxied it internally to a virutal server.
1658                  */
1659         }
1660 #endif
1661
1662         /*
1663          *      Fake requests don't get encoded or signed.  The caller
1664          *      also requires the reply VP's, so we don't free them
1665          *      here!
1666          */
1667         if (request->packet->dst_port == 0) {
1668                 /* FIXME: DEBUG going to the next request */
1669 #ifdef HAVE_PTHREAD_H
1670                 request->child_pid = NO_SUCH_CHILD_PID;
1671 #endif
1672                 request->child_state = REQUEST_DONE;
1673                 return;
1674         }
1675
1676 #ifdef WITH_PROXY
1677         /*
1678          *      Copy Proxy-State from the request to the reply.
1679          */
1680         vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
1681         if (vp) pairadd(&request->reply->vps, vp);
1682 #endif
1683
1684         /*
1685          *      Access-Requests get delayed or cached.
1686          */
1687         switch (request->packet->code) {
1688         case PW_AUTHENTICATION_REQUEST:
1689                 gettimeofday(&request->next_when, NULL);
1690
1691                 if (request->reply->code == 0) {
1692                         /*
1693                          *      Check if the lack of response is intentional.
1694                          */
1695                         vp = pairfind(request->config_items,
1696                                       PW_RESPONSE_PACKET_TYPE);
1697                         if (!vp) {
1698                                 DEBUG2("There was no response configured: rejecting request %d",
1699                                        request->number);
1700                                 request->reply->code = PW_AUTHENTICATION_REJECT;
1701                         } else if (vp->vp_integer == 256) {
1702                                 DEBUG2("Not responding to request %d",
1703                                        request->number);
1704
1705                         } else {
1706                                 request->reply->code = vp->vp_integer;
1707
1708                         }
1709                 }
1710
1711                 /*
1712                  *      Run rejected packets through
1713                  *
1714                  *      Post-Auth-Type = Reject
1715                  */
1716                 if (request->reply->code == PW_AUTHENTICATION_REJECT) {
1717                         pairdelete(&request->config_items, PW_POST_AUTH_TYPE);
1718                         vp = radius_pairmake(request, &request->config_items,
1719                                              "Post-Auth-Type", "Reject",
1720                                              T_OP_SET);
1721                         if (vp) rad_postauth(request);
1722
1723                         /*
1724                          *      If configured, delay Access-Reject packets.
1725                          *
1726                          *      If request->root->reject_delay = 0, we discover
1727                          *      that we have to send the packet now.
1728                          */
1729                         when = request->received;
1730                         when.tv_sec += request->root->reject_delay;
1731
1732                         if (timercmp(&when, &request->next_when, >)) {
1733                                 DEBUG2("Delaying reject of request %d for %d seconds",
1734                                        request->number,
1735                                        request->root->reject_delay);
1736                                 request->next_when = when;
1737                                 request->next_callback = reject_delay;
1738 #ifdef HAVE_PTHREAD_H
1739                                 request->child_pid = NO_SUCH_CHILD_PID;
1740 #endif
1741                                 request->child_state = REQUEST_REJECT_DELAY;
1742                                 return;
1743                         }
1744                 }
1745
1746                 request->next_when.tv_sec += request->root->cleanup_delay;
1747                 request->next_callback = cleanup_delay;
1748                 child_state = REQUEST_CLEANUP_DELAY;
1749                 break;
1750
1751         case PW_ACCOUNTING_REQUEST:
1752                 request->next_callback = NULL; /* just to be safe */
1753                 child_state = REQUEST_DONE;
1754                 break;
1755
1756                 /*
1757                  *      FIXME: Status-Server should probably not be
1758                  *      handled here...
1759                  */
1760         case PW_STATUS_SERVER:
1761                 request->next_callback = NULL;
1762                 child_state = REQUEST_DONE;
1763                 break;
1764
1765         default:
1766                 if ((request->packet->code > 1024) &&
1767                     (request->packet->code < (1024 + 254 + 1))) {
1768                         request->next_callback = NULL;
1769                         child_state = REQUEST_DONE;
1770                         break;
1771                 }
1772
1773                 radlog(L_ERR, "Unknown packet type %d", request->packet->code);
1774                 rad_panic("Unknown packet type");
1775                 break;
1776         }
1777
1778         /*
1779          *      Suppress "no reply" packets here, unless we're reading
1780          *      from the "detail" file.  In that case, we've got to
1781          *      tell the detail file handler that the request is dead,
1782          *      and it should re-send it.
1783          *      If configured, encode, sign, and send.
1784          */
1785         if ((request->reply->code != 0) ||
1786             (request->listener->type == RAD_LISTEN_DETAIL)) {
1787                 request->listener->send(request->listener, request);
1788         }
1789
1790         /*
1791          *      Clean up.  These are no longer needed.
1792          */
1793         pairfree(&request->config_items);
1794
1795         pairfree(&request->packet->vps);
1796         request->username = NULL;
1797         request->password = NULL;
1798
1799         pairfree(&request->reply->vps);
1800
1801 #ifdef WITH_PROXY
1802         if (request->proxy) {
1803                 pairfree(&request->proxy->vps);
1804
1805                 if (request->proxy_reply) {
1806                         pairfree(&request->proxy_reply->vps);
1807                 }
1808
1809                 /*
1810                  *      We're not tracking responses from the home
1811                  *      server, we can therefore free this memory in
1812                  *      the child thread.
1813                  */
1814                 if (!request->in_proxy_hash) {
1815                         rad_free(&request->proxy);
1816                         rad_free(&request->proxy_reply);
1817                         request->home_server = NULL;
1818                 }
1819         }
1820 #endif
1821
1822         DEBUG2("Finished request %d.", request->number);
1823
1824         request->child_state = child_state;
1825
1826         /*
1827          *      Single threaded mode: update timers now.
1828          */
1829         if (!have_children) wait_a_bit(request);
1830 }
1831
1832
1833 static void received_retransmit(REQUEST *request, const RADCLIENT *client)
1834 {
1835 #ifdef WITH_PROXY
1836         char buffer[128];
1837 #endif
1838
1839         RAD_SNMP_TYPE_INC(request->listener, total_dup_requests);
1840         RAD_SNMP_CLIENT_INC(request->listener, client, dup_requests);
1841
1842         switch (request->child_state) {
1843         case REQUEST_QUEUED:
1844         case REQUEST_RUNNING:
1845 #ifdef WITH_PROXY
1846         discard:
1847 #endif
1848                 radlog(L_ERR, "Discarding duplicate request from "
1849                        "client %s port %d - ID: %d due to unfinished request %d",
1850                        client->shortname,
1851                        request->packet->src_port,request->packet->id,
1852                        request->number);
1853                 break;
1854
1855 #ifdef WITH_PROXY
1856         case REQUEST_PROXIED:
1857                 /*
1858                  *      We're not supposed to have duplicate
1859                  *      accounting packets.  The other states handle
1860                  *      duplicates fine (discard, or send duplicate
1861                  *      reply).  But we do NOT want to retransmit an
1862                  *      accounting request here, because that would
1863                  *      involve updating the Acct-Delay-Time, and
1864                  *      therefore changing the packet Id, etc.
1865                  *
1866                  *      Instead, we just discard the packet.  We may
1867                  *      eventually respond, or the client will send a
1868                  *      new accounting packet.
1869                  */
1870                 if (request->packet->code == PW_ACCOUNTING_REQUEST) {
1871                         goto discard;
1872                 }
1873
1874                 check_for_zombie_home_server(request);
1875
1876                 /*
1877                  *      If we've just discovered that the home server is
1878                  *      dead, send the packet to another one.
1879                  */
1880                 if ((request->packet->dst_port != 0) &&
1881                     (request->home_server->state == HOME_STATE_IS_DEAD)) {
1882                         home_server *home;
1883
1884                         remove_from_proxy_hash(request);
1885
1886                         home = home_server_ldb(NULL, request->home_pool, request);
1887                         if (!home) {
1888                                 DEBUG2("Failed to find live home server for request %d", request->number);
1889                         no_home_servers:
1890                                 /*
1891                                  *      Do post-request processing,
1892                                  *      and any insertion of necessary
1893                                  *      events.
1894                                  */
1895                                 post_proxy_fail_handler(request);
1896                                 return;
1897                         }
1898
1899                         request->proxy->code = request->packet->code;
1900                         request->proxy->dst_ipaddr = home->ipaddr;
1901                         request->proxy->dst_port = home->port;
1902                         request->home_server = home;
1903
1904                         /*
1905                          *      Free the old packet, to force re-encoding
1906                          */
1907                         free(request->proxy->data);
1908                         request->proxy->data = NULL;
1909                         request->proxy->data_len = 0;
1910
1911                         /*
1912                          *      This request failed over to a virtual
1913                          *      server.  Push it back onto the queue
1914                          *      to be processed.
1915                          */
1916                         if (request->home_server->server) {
1917                                 proxy_fallback_handler(request);
1918                                 return;
1919                         }
1920
1921                         /*
1922                          *      Try to proxy the request.
1923                          */
1924                         if (!proxy_request(request)) {
1925                                 DEBUG("ERROR: Failed to re-proxy request %d", request->number);
1926                                 goto no_home_servers;
1927                         }
1928
1929                         /*
1930                          *      This code executes in the main server
1931                          *      thread, so there's no need for locking.
1932                          */
1933                         rad_assert(request->next_callback != NULL);
1934                         INSERT_EVENT(request->next_callback, request);
1935                         request->next_callback = NULL;
1936                         return;
1937                 } /* else the home server is still alive */
1938
1939                 DEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
1940                        inet_ntop(request->proxy->dst_ipaddr.af,
1941                                  &request->proxy->dst_ipaddr.ipaddr,
1942                                  buffer, sizeof(buffer)),
1943                        request->proxy->dst_port,
1944                        request->proxy->id);
1945                 request->num_proxied_requests++;
1946                 request->proxy_listener->send(request->proxy_listener,
1947                                               request);
1948                 break;
1949 #endif
1950
1951         case REQUEST_REJECT_DELAY:
1952                 DEBUG2("Waiting to send Access-Reject "
1953                        "to client %s port %d - ID: %d",
1954                        client->shortname,
1955                        request->packet->src_port, request->packet->id);
1956                 break;
1957
1958         case REQUEST_CLEANUP_DELAY:
1959         case REQUEST_DONE:
1960                 DEBUG2("Sending duplicate reply "
1961                        "to client %s port %d - ID: %d",
1962                        client->shortname,
1963                        request->packet->src_port, request->packet->id);
1964                 request->listener->send(request->listener, request);
1965                 break;
1966         }
1967 }
1968
1969
1970 static void received_conflicting_request(REQUEST *request,
1971                                          const RADCLIENT *client)
1972 {
1973         radlog(L_ERR, "Received conflicting packet from "
1974                "client %s port %d - ID: %d due to unfinished request %d.  Giving up on old request.",
1975                client->shortname,
1976                request->packet->src_port, request->packet->id,
1977                request->number);
1978
1979         /*
1980          *      Nuke it from the request hash, so we can receive new
1981          *      packets.
1982          */
1983         remove_from_request_hash(request);
1984
1985         switch (request->child_state) {
1986                 /*
1987                  *      It's queued or running.  Tell it to stop, and
1988                  *      wait for it to do so.
1989                  */
1990         case REQUEST_QUEUED:
1991         case REQUEST_RUNNING:
1992                 request->master_state = REQUEST_STOP_PROCESSING;
1993                 request->delay += request->delay >> 1;
1994
1995                 tv_add(&request->when, request->delay);
1996
1997                 INSERT_EVENT(wait_for_child_to_die, request);
1998                 return;
1999
2000                 /*
2001                  *      It's in some other state, and therefore also
2002                  *      in the event queue.  At some point, the
2003                  *      child will notice, and we can then delete it.
2004                  */
2005         default:
2006                 rad_assert(request->ev != NULL);
2007                 break;
2008         }
2009 }
2010
2011
2012 static int can_handle_new_request(RADIUS_PACKET *packet,
2013                                   RADCLIENT *client,
2014                                   struct main_config_t *root)
2015 {
2016         /*
2017          *      Count the total number of requests, to see if
2018          *      there are too many.  If so, return with an
2019          *      error.
2020          */
2021         if (root->max_requests) {
2022                 int request_count = fr_packet_list_num_elements(pl);
2023
2024                 /*
2025                  *      This is a new request.  Let's see if
2026                  *      it makes us go over our configured
2027                  *      bounds.
2028                  */
2029                 if (request_count > root->max_requests) {
2030                         radlog(L_ERR, "Dropping request (%d is too many): "
2031                                "from client %s port %d - ID: %d", request_count,
2032                                client->shortname,
2033                                packet->src_port, packet->id);
2034                         radlog(L_INFO, "WARNING: Please check the configuration file.\n"
2035                                "\tThe value for 'max_requests' is probably set too low.\n");
2036                         return 0;
2037                 } /* else there were a small number of requests */
2038         } /* else there was no configured limit for requests */
2039
2040         /*
2041          *      FIXME: Add per-client checks.  If one client is sending
2042          *      too many packets, start discarding them.
2043          *
2044          *      We increment the counters here, and decrement them
2045          *      when the response is sent... somewhere in this file.
2046          */
2047
2048         /*
2049          *      FUTURE: Add checks for system load.  If the system is
2050          *      busy, start dropping requests...
2051          *
2052          *      We can probably keep some statistics ourselves...  if
2053          *      there are more requests coming in than we can handle,
2054          *      start dropping some.
2055          */
2056
2057         return 1;
2058 }
2059
2060
2061 int received_request(rad_listen_t *listener,
2062                      RADIUS_PACKET *packet, REQUEST **prequest,
2063                      RADCLIENT *client)
2064 {
2065         RADIUS_PACKET **packet_p;
2066         REQUEST *request = NULL;
2067         struct main_config_t *root = &mainconfig;
2068
2069         packet_p = fr_packet_list_find(pl, packet);
2070         if (packet_p) {
2071                 request = fr_packet2myptr(REQUEST, packet, packet_p);
2072                 rad_assert(request->in_request_hash);
2073
2074                 if ((request->packet->data_len == packet->data_len) &&
2075                     (memcmp(request->packet->vector, packet->vector,
2076                             sizeof(packet->vector)) == 0)) {
2077                         received_retransmit(request, client);
2078                         return 0;
2079                 }
2080
2081                 /*
2082                  *      The new request is different from the old one,
2083                  *      but maybe the old is finished.  If so, delete
2084                  *      the old one.
2085                  */
2086                 switch (request->child_state) {
2087                         struct timeval when;
2088
2089                 default:
2090                         gettimeofday(&when, NULL);
2091                         when.tv_sec -= 1;
2092
2093                         /*
2094                          *      If the cached request was received
2095                          *      within the last second, then we
2096                          *      discard the NEW request instead of the
2097                          *      old one.  This will happen ONLY when
2098                          *      the client is severely broken, and is
2099                          *      sending conflicting packets very
2100                          *      quickly.
2101                          */
2102                         if (timercmp(&when, &request->received, <)) {
2103                                 radlog(L_ERR, "Discarding conflicting packet from "
2104                                        "client %s port %d - ID: %d due to recent request %d.",
2105                                        client->shortname,
2106                                        packet->src_port, packet->id,
2107                                        request->number);
2108                                 return 0;
2109                         }
2110
2111                         received_conflicting_request(request, client);
2112                         request = NULL;
2113                         break;
2114
2115                 case REQUEST_REJECT_DELAY:
2116                 case REQUEST_CLEANUP_DELAY:
2117                         request->child_state = REQUEST_DONE;
2118                 case REQUEST_DONE:
2119                         cleanup_delay(request);
2120                         request = NULL;
2121                         break;
2122                 }
2123         }
2124
2125         /*
2126          *      We may want to quench the new request.
2127          */
2128         if ((listener->type != RAD_LISTEN_DETAIL) &&
2129             !can_handle_new_request(packet, client, root)) {
2130                 return 0;
2131         }
2132
2133         /*
2134          *      Create and initialize the new request.
2135          */
2136         request = request_alloc(); /* never fails */
2137
2138         if ((request->reply = rad_alloc(0)) == NULL) {
2139                 radlog(L_ERR, "No memory");
2140                 exit(1);
2141         }
2142
2143         request->listener = listener;
2144         request->client = client;
2145         request->packet = packet;
2146         request->packet->timestamp = request->timestamp;
2147         request->number = request_num_counter++;
2148         request->priority = listener->type;
2149
2150         /*
2151          *      Set virtual server identity
2152          */
2153         if (client->server) {
2154                 request->server = client->server;
2155         } else if (listener->server) {
2156                 request->server = listener->server;
2157         } else {
2158                 request->server = NULL;
2159         }
2160
2161         /*
2162          *      Remember the request in the list.
2163          */
2164         if (!fr_packet_list_insert(pl, &request->packet)) {
2165                 radlog(L_ERR, "Failed to insert request %d in the list of live requests: discarding", request->number);
2166                 request_free(&request);
2167                 return 0;
2168         }
2169
2170         request->in_request_hash = TRUE;
2171         request->root = root;
2172         root->refcount++;
2173
2174         /*
2175          *      The request passes many of our sanity checks.
2176          *      From here on in, if anything goes wrong, we
2177          *      send a reject message, instead of dropping the
2178          *      packet.
2179          */
2180
2181         /*
2182          *      Build the reply template from the request.
2183          */
2184
2185         request->reply->sockfd = request->packet->sockfd;
2186         request->reply->dst_ipaddr = request->packet->src_ipaddr;
2187         request->reply->src_ipaddr = request->packet->dst_ipaddr;
2188         request->reply->dst_port = request->packet->src_port;
2189         request->reply->src_port = request->packet->dst_port;
2190         request->reply->id = request->packet->id;
2191         request->reply->code = 0; /* UNKNOWN code */
2192         memcpy(request->reply->vector, request->packet->vector,
2193                sizeof(request->reply->vector));
2194         request->reply->vps = NULL;
2195         request->reply->data = NULL;
2196         request->reply->data_len = 0;
2197
2198         request->master_state = REQUEST_ACTIVE;
2199         request->child_state = REQUEST_QUEUED;
2200         request->next_callback = NULL;
2201
2202         gettimeofday(&request->received, NULL);
2203         request->timestamp = request->received.tv_sec;
2204         request->when = request->received;
2205
2206         request->delay = USEC;
2207
2208         tv_add(&request->when, request->delay);
2209
2210         INSERT_EVENT(wait_a_bit, request);
2211
2212         *prequest = request;
2213         return 1;
2214 }
2215
2216
2217 #ifdef WITH_PROXY
2218 REQUEST *received_proxy_response(RADIUS_PACKET *packet)
2219 {
2220         char            buffer[128];
2221         home_server     *home;
2222         REQUEST         *request;
2223
2224         if (!home_server_find(&packet->src_ipaddr, packet->src_port)) {
2225                 radlog(L_ERR, "Ignoring request from unknown home server %s port %d",
2226                        inet_ntop(packet->src_ipaddr.af,
2227                                  &packet->src_ipaddr.ipaddr,
2228                                  buffer, sizeof(buffer)),
2229                                packet->src_port);
2230                 rad_free(&packet);
2231                 return NULL;
2232         }
2233
2234         /*
2235          *      Also removes from the proxy hash if responses == requests
2236          */
2237         request = lookup_in_proxy_hash(packet);
2238
2239         if (!request) {
2240                 radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s port %d - ID %d",
2241                        inet_ntop(packet->src_ipaddr.af,
2242                                  &packet->src_ipaddr.ipaddr,
2243                                  buffer, sizeof(buffer)),
2244                        packet->src_port, packet->id);
2245                 rad_free(&packet);
2246                 return NULL;
2247         }
2248
2249         home = request->home_server;
2250
2251         gettimeofday(&now, NULL);
2252         home->state = HOME_STATE_ALIVE;
2253
2254         if (request->reply && request->reply->code != 0) {
2255                 DEBUG2("We already replied to this request.  Discarding response from home server.");
2256                 rad_free(&packet);
2257                 return NULL;
2258         }
2259
2260         /*
2261          *      We had previously received a reply, so we don't need
2262          *      to do anything here.
2263          */
2264         if (request->proxy_reply) {
2265                 if (memcmp(request->proxy_reply->vector,
2266                            packet->vector,
2267                            sizeof(request->proxy_reply->vector)) == 0) {
2268                         DEBUG2("Discarding duplicate reply from home server %s port %d  - ID: %d for request %d",
2269                                inet_ntop(packet->src_ipaddr.af,
2270                                          &packet->src_ipaddr.ipaddr,
2271                                          buffer, sizeof(buffer)),
2272                                packet->src_port, packet->id,
2273                                request->number);
2274                 } else {
2275                         /*
2276                          *      ? The home server gave us a new proxy
2277                          *      reply, which doesn't match the old
2278                          *      one.  Delete it.
2279                          */
2280                         DEBUG2("Ignoring conflicting proxy reply");
2281                 }
2282
2283                 /* assert that there's an event queued for request? */
2284                 rad_free(&packet);
2285                 return NULL;
2286         }
2287
2288         switch (request->child_state) {
2289         case REQUEST_QUEUED:
2290         case REQUEST_RUNNING:
2291                 rad_panic("Internal sanity check failed for child state");
2292                 break;
2293
2294         case REQUEST_REJECT_DELAY:
2295         case REQUEST_CLEANUP_DELAY:
2296         case REQUEST_DONE:
2297                 radlog(L_ERR, "Reply from home server %s port %d  - ID: %d arrived too late for request %d. Try increasing 'retry_delay' or 'max_request_time'",
2298                        inet_ntop(packet->src_ipaddr.af,
2299                                  &packet->src_ipaddr.ipaddr,
2300                                  buffer, sizeof(buffer)),
2301                        packet->src_port, packet->id,
2302                        request->number);
2303                 /* assert that there's an event queued for request? */
2304                 rad_free(&packet);
2305                 return NULL;
2306
2307         case REQUEST_PROXIED:
2308                 break;
2309         }
2310
2311         request->proxy_reply = packet;
2312
2313 #if 0
2314         /*
2315          *      Perform RTT calculations, as per RFC 2988 (for TCP).
2316          *      Note that we do so only if we sent one request, and
2317          *      received one response.  If we sent two requests, we
2318          *      have no idea if the response is for the first, or for
2319          *      the second request/
2320          */
2321         if (request->num_proxied_requests == 1) {
2322                 int rtt;
2323                 home_server *home = request->home_server;
2324
2325                 rtt = now.tv_sec - request->proxy_when.tv_sec;
2326                 rtt *= USEC;
2327                 rtt += now.tv_usec;
2328                 rtt -= request->proxy_when.tv_usec;
2329
2330                 if (!home->has_rtt) {
2331                         home->has_rtt = TRUE;
2332
2333                         home->srtt = rtt;
2334                         home->rttvar = rtt / 2;
2335
2336                 } else {
2337                         home->rttvar -= home->rttvar >> 2;
2338                         home->rttvar += (home->srtt - rtt);
2339                         home->srtt -= home->srtt >> 3;
2340                         home->srtt += rtt >> 3;
2341                 }
2342
2343                 home->rto = home->srtt;
2344                 if (home->rttvar > (USEC / 4)) {
2345                         home->rto += home->rttvar * 4;
2346                 } else {
2347                         home->rto += USEC;
2348                 }
2349         }
2350 #endif
2351
2352         /*
2353          *      There's no incoming request, so it's a proxied packet
2354          *      we originated.
2355          */
2356         if (!request->packet) {
2357                 received_response_to_ping(request);
2358                 return NULL;
2359         }
2360
2361         request->child_state = REQUEST_QUEUED;
2362         request->when = now;
2363         request->delay = USEC;
2364         request->priority = RAD_LISTEN_PROXY;
2365         tv_add(&request->when, request->delay);
2366
2367         /*
2368          *      Wait a bit will take care of max_request_time
2369          */
2370         INSERT_EVENT(wait_a_bit, request);
2371
2372         return request;
2373 }
2374 #endif
2375
2376 #ifdef WITH_DETAIL
2377 static void event_detail_timer(void *ctx)
2378 {
2379         rad_listen_t *listener = ctx;
2380         RAD_REQUEST_FUNP fun;
2381         REQUEST *request;
2382
2383         if (listener->recv(listener, &fun, &request)) {
2384                 if (!thread_pool_addrequest(request, fun)) {
2385                         request->child_state = REQUEST_DONE;
2386                 }
2387         }
2388 }
2389 #endif
2390
2391 static void handle_signal_self(int flag)
2392 {
2393         if ((flag & (RADIUS_SIGNAL_SELF_EXIT | RADIUS_SIGNAL_SELF_TERM)) != 0) {
2394                 if ((flag & RADIUS_SIGNAL_SELF_EXIT) != 0) {
2395                         fr_event_loop_exit(el, 1);
2396                 } else {
2397                         fr_event_loop_exit(el, 2);
2398                 }
2399
2400                 return;
2401         } /* else exit/term flags weren't set */
2402
2403         /*
2404          *      Tell the even loop to stop processing.
2405          */
2406         if ((flag & RADIUS_SIGNAL_SELF_HUP) != 0) {
2407                 time_t when;
2408                 static time_t last_hup = 0;
2409
2410                 DEBUG("Received HUP signal.");
2411
2412                 when = time(NULL);
2413                 if ((int) (when - last_hup) < 5) {
2414                         radlog(L_INFO, "Ignoring HUP (less than 5s since last one)");
2415                         return;
2416                 }
2417                 last_hup = when;
2418
2419                 fr_event_loop_exit(el, 0x80);
2420         }
2421
2422 #ifdef WITH_DETAIL
2423         if ((flag & RADIUS_SIGNAL_SELF_DETAIL) != 0) {
2424                 rad_listen_t *this;
2425                 
2426                 for (this = mainconfig.listen;
2427                      this != NULL;
2428                      this = this->next) {
2429                         int delay;
2430                         struct timeval when;
2431
2432                         if (this->type != RAD_LISTEN_DETAIL) continue;
2433                         
2434                         delay = detail_delay(this);
2435                         if (!delay) continue;
2436
2437                         fr_event_now(el, &now);
2438                         when = now;
2439                         tv_add(&when, delay);
2440
2441                         if (delay > 100000) {
2442                                 DEBUG2("Delaying next detail event for %d.%01u seconds.",
2443                                        delay / USEC, (delay % USEC) / 100000);
2444                         }
2445
2446                         if (!fr_event_insert(el, event_detail_timer, this,
2447                                              &when, NULL)) {
2448                                 radlog(L_ERR, "Failed remembering timer");
2449                                 exit(1);
2450                         }
2451                 }
2452         }
2453 #endif
2454
2455         if ((flag & RADIUS_SIGNAL_SELF_NEW_FD) != 0) {
2456                 rad_listen_t *this;
2457                 
2458                 for (this = mainconfig.listen;
2459                      this != NULL;
2460                      this = this->next) {
2461                         if (this->type != RAD_LISTEN_PROXY) continue;
2462                         
2463                         if (!fr_event_fd_insert(el, 0, this->fd,
2464                                                 event_socket_handler, this)) {
2465                                 radlog(L_ERR, "Failed remembering handle for proxy socket!");
2466                                 exit(1);
2467                         }
2468                 }
2469         }
2470 }
2471
2472 #ifdef __MINGW32__
2473 void radius_signal_self(int flag)
2474 {
2475         handle_signal_self(flag);
2476 }
2477 #else
2478 /*
2479  *      Inform ourselves that we received a signal.
2480  */
2481 void radius_signal_self(int flag)
2482 {
2483         ssize_t rcode;
2484         uint8_t buffer[16];
2485
2486         /*
2487          *      The read MUST be non-blocking for this to work.
2488          */
2489         rcode = read(self_pipe[0], buffer, sizeof(buffer));
2490         if (rcode > 0) {
2491                 ssize_t i;
2492
2493                 for (i = 0; i < rcode; i++) {
2494                         buffer[0] |= buffer[i];
2495                 }
2496         } else {
2497                 buffer[0] = 0;
2498         }
2499
2500         buffer[0] |= flag;
2501
2502         write(self_pipe[1], buffer, 1);
2503 }
2504
2505
2506 static void event_signal_handler(UNUSED fr_event_list_t *xel,
2507                                  UNUSED int fd, UNUSED void *ctx)
2508 {
2509         ssize_t i, rcode;
2510         uint8_t buffer[32];
2511
2512         rcode = read(self_pipe[0], buffer, sizeof(buffer));
2513         if (rcode <= 0) return;
2514
2515         /*
2516          *      Merge pending signals.
2517          */
2518         for (i = 0; i < rcode; i++) {
2519                 buffer[0] |= buffer[i];
2520         }
2521
2522         handle_signal_self(buffer[0]);
2523 }
2524 #endif
2525
2526
2527 static void event_socket_handler(fr_event_list_t *xel, UNUSED int fd,
2528                                  void *ctx)
2529 {
2530         rad_listen_t *listener = ctx;
2531         RAD_REQUEST_FUNP fun;
2532         REQUEST *request;
2533
2534         rad_assert(xel == el);
2535
2536         xel = xel;
2537
2538         if (listener->fd < 0) rad_panic("Socket was closed on us!");
2539         
2540         if (!listener->recv(listener, &fun, &request)) return;
2541
2542         if (!thread_pool_addrequest(request, fun)) {
2543                 request->child_state = REQUEST_DONE;
2544         }
2545 }
2546
2547
2548 /*
2549  *      This function is called periodically to see if any FD's are
2550  *      available for reading.
2551  */
2552 static void event_poll_fds(UNUSED void *ctx)
2553 {
2554         int rcode;
2555         RAD_REQUEST_FUNP fun;
2556         REQUEST *request;
2557         rad_listen_t *this;
2558         struct timeval when;
2559
2560         fr_event_now(el, &now);
2561         when = now;
2562         when.tv_sec += 1;
2563
2564         for (this = mainconfig.listen; this != NULL; this = this->next) {
2565                 if (this->fd >= 0) continue;
2566
2567                 /*
2568                  *      Try to read something.
2569                  *
2570                  *      FIXME: This does poll AND receive.
2571                  */
2572                 rcode = this->recv(this, &fun, &request);
2573                 if (!rcode) continue;
2574                 
2575                 rad_assert(fun != NULL);
2576                 rad_assert(request != NULL);
2577                         
2578                 if (!thread_pool_addrequest(request, fun)) {
2579                         request->child_state = REQUEST_DONE;
2580                 }
2581
2582                 /*
2583                  *      We have an FD.  Start watching it.
2584                  */
2585                 if (this->fd >= 0) {
2586 #ifdef WITH_DETAIL
2587                         /*
2588                          *      ... unless it's a detail file.  In
2589                          *      that case, we rely on the signal to
2590                          *      self to know when to continue
2591                          *      processing the detail file.
2592                          */
2593                         if (this->type == RAD_LISTEN_DETAIL) continue;
2594 #endif
2595
2596                         /*
2597                          *      FIXME: this should be SNMP handler,
2598                          *      and we should do SOMETHING when the
2599                          *      fd is closed!
2600                          */
2601                         if (!fr_event_fd_insert(el, 0, this->fd,
2602                                                 event_socket_handler, this)) {
2603                                 char buffer[256];
2604                                 
2605                                 this->print(this, buffer, sizeof(buffer));
2606                                 rad_panic("Failed creating handler for snmp");
2607                         }
2608                 }
2609         }
2610
2611         /*
2612          *      Reset the poll.
2613          */
2614         if (!fr_event_insert(el, event_poll_fds, NULL,
2615                              &when, NULL)) {
2616                 radlog(L_ERR, "Failed creating handler");
2617                 exit(1);
2618         }
2619 }
2620
2621
2622 static void event_status(struct timeval *wake)
2623 {
2624 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
2625         int argval;
2626 #endif
2627
2628         if (debug_flag == 0) {
2629                 if (just_started) {
2630                         radlog(L_INFO, "Ready to process requests.");
2631                         just_started = FALSE;
2632                 }
2633                 return;
2634         }
2635
2636         if (!wake) {
2637                 DEBUG("Ready to process requests.");
2638
2639         } else if ((wake->tv_sec != 0) ||
2640                    (wake->tv_usec >= 100000)) {
2641                 DEBUG("Waking up in %d.%01u seconds.",
2642                       (int) wake->tv_sec, (unsigned int) wake->tv_usec / 100000);
2643         }
2644
2645
2646         /*
2647          *      FIXME: Put this somewhere else, where it isn't called
2648          *      all of the time...
2649          */
2650
2651 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
2652         /*
2653          *      If there are no child threads, then there may
2654          *      be child processes.  In that case, wait for
2655          *      their exit status, and throw that exit status
2656          *      away.  This helps get rid of zxombie children.
2657          */
2658         while (waitpid(-1, &argval, WNOHANG) > 0) {
2659                 /* do nothing */
2660         }
2661 #endif
2662
2663 }
2664
2665
2666 /*
2667  *      Externally-visibly functions.
2668  */
2669 int radius_event_init(CONF_SECTION *cs, int spawn_flag)
2670 {
2671         int has_snmp_listener = FALSE;
2672         rad_listen_t *this, *head = NULL;
2673
2674         if (el) return 0;
2675
2676         time(&start_time);
2677
2678         el = fr_event_list_create(event_status);
2679         if (!el) return 0;
2680
2681         pl = fr_packet_list_create(0);
2682         if (!el) return 0;
2683
2684         request_num_counter = 0;
2685
2686         /*
2687          *      Move all of the thread calls to this file?
2688          *
2689          *      It may be best for the mutexes to be in this file...
2690          */
2691         have_children = spawn_flag;
2692
2693 #ifdef WITH_PROXY
2694         if (mainconfig.proxy_requests) {
2695                 /*
2696                  *      Create the tree for managing proxied requests and
2697                  *      responses.
2698                  */
2699                 proxy_list = fr_packet_list_create(1);
2700                 if (!proxy_list) return 0;
2701
2702 #ifdef HAVE_PTHREAD_H
2703                 if (pthread_mutex_init(&proxy_mutex, NULL) != 0) {
2704                         radlog(L_ERR, "FATAL: Failed to initialize proxy mutex: %s",
2705                                strerror(errno));
2706                         exit(1);
2707                 }
2708 #endif
2709         }
2710 #endif
2711
2712         /*
2713          *      Just before we spawn the child threads, force the log
2714          *      subsystem to re-open the log file for every write.
2715          */
2716         if (spawn_flag) force_log_reopen();
2717
2718 #ifdef HAVE_PTHREAD_H
2719         if (thread_pool_init(cs, spawn_flag) < 0) {
2720                 exit(1);
2721         }
2722 #endif
2723
2724         if (check_config) {
2725                 DEBUG2("%s: #### Skipping IP addresses and Ports ####",
2726                        mainconfig.name);
2727                 return 1;
2728         }
2729
2730 #ifndef __MINGW32__
2731         /*
2732          *      Child threads need a pipe to signal us, as do the
2733          *      signal handlers.
2734          */
2735         if (pipe(self_pipe) < 0) {
2736                 radlog(L_ERR, "radiusd: Error opening internal pipe: %s",
2737                        strerror(errno));
2738                 exit(1);
2739         }
2740         if (fcntl(self_pipe[0], F_SETFL, O_NONBLOCK | FD_CLOEXEC) < 0) {
2741                 radlog(L_ERR, "radiusd: Error setting internal flags: %s",
2742                        strerror(errno));
2743                 exit(1);
2744         }
2745         if (fcntl(self_pipe[1], F_SETFL, O_NONBLOCK | FD_CLOEXEC) < 0) {
2746                 radlog(L_ERR, "radiusd: Error setting internal flags: %s",
2747                        strerror(errno));
2748                 exit(1);
2749         }
2750
2751         if (!fr_event_fd_insert(el, 0, self_pipe[0],
2752                                   event_signal_handler, el)) {
2753                 radlog(L_ERR, "Failed creating handler for signals");
2754                 exit(1);
2755         }
2756 #endif
2757
2758 #ifdef WITH_PROXY
2759         /*
2760          *      Mark the proxy Fd's as unused.
2761          */
2762         {
2763                 int i;
2764
2765                 for (i = 0; i < 32; i++) proxy_fds[i] = -1;
2766         }
2767 #endif
2768
2769         DEBUG2("%s: #### Opening IP addresses and Ports ####",
2770                mainconfig.name);
2771
2772         if (listen_init(cs, &head) < 0) {
2773                 _exit(1);
2774         }
2775         
2776         /*
2777          *      Add all of the sockets to the event loop.
2778          */
2779         for (this = head;
2780              this != NULL;
2781              this = this->next) {
2782                 char buffer[256];
2783
2784                 this->print(this, buffer, sizeof(buffer));
2785
2786                 switch (this->type) {
2787 #ifdef WITH_DETAIL
2788                 case RAD_LISTEN_DETAIL:
2789                         DEBUG("Listening on %s", buffer);
2790                         has_detail_listener = TRUE;
2791                         break;
2792 #endif
2793
2794 #ifdef WITH_SNMP
2795                 case RAD_LISTEN_SNMP:
2796                         DEBUG("Listening on SNMP %s", buffer);
2797                         has_snmp_listener = TRUE;
2798                         break;
2799 #endif
2800
2801 #ifdef WITH_PROXY
2802                 case RAD_LISTEN_PROXY:
2803                         rad_assert(proxy_fds[this->fd & 0x1f] == -1);
2804                         rad_assert(proxy_listeners[this->fd & 0x1f] == NULL);
2805                         
2806                         proxy_fds[this->fd & 0x1f] = this->fd;
2807                         proxy_listeners[this->fd & 0x1f] = this;
2808                         if (!fr_packet_list_socket_add(proxy_list,
2809                                                          this->fd)) {
2810                                 rad_assert(0 == 1);
2811                         }
2812                         /* FALL-THROUGH */
2813 #endif
2814
2815                 default:
2816                         DEBUG("Listening on %s", buffer);
2817                         break;
2818                 }
2819
2820                 /*
2821                  *      The file descriptor isn't ready.  Poll for
2822                  *      when it will become ready.  This is for SNMP
2823                  *      and detail file fd's.
2824                  */
2825                 if (this->fd < 0) {
2826                         continue;
2827                 }
2828
2829                 /*
2830                  *      The socket is open.  It MUST be a socket,
2831                  *      as we don't pre-open the detail files (yet).
2832                  *
2833                  *      FIXME: if we DO open the detail files automatically,
2834                  *      then much of this code becomes simpler.
2835                  */
2836                 if (!fr_event_fd_insert(el, 0, this->fd,
2837                                           event_socket_handler, this)) {
2838                         this->print(this, buffer, sizeof(buffer));
2839                         radlog(L_ERR, "Failed creating handler for socket %s",
2840                                buffer);
2841                         exit(1);
2842                 }
2843         }
2844
2845         if (has_detail_listener || has_snmp_listener) {
2846                 struct timeval when;
2847                 
2848                 gettimeofday(&when, NULL);
2849                 when.tv_sec += 1;
2850                 
2851                 if (!fr_event_insert(el, event_poll_fds, NULL,
2852                                      &when, NULL)) {
2853                         radlog(L_ERR, "Failed creating handler");
2854                         exit(1);
2855                 }
2856         }
2857
2858         mainconfig.listen = head;
2859
2860         return 1;
2861 }
2862
2863
2864 static int request_hash_cb(UNUSED void *ctx, void *data)
2865 {
2866         REQUEST *request = fr_packet2myptr(REQUEST, packet, data);
2867
2868 #ifdef WITH_PROXY
2869         rad_assert(request->in_proxy_hash == FALSE);
2870 #endif
2871
2872         fr_event_delete(el, &request->ev);
2873         remove_from_request_hash(request);
2874         request_free(&request);
2875
2876         return 0;
2877 }
2878
2879
2880 #ifdef WITH_PROXY
2881 static int proxy_hash_cb(UNUSED void *ctx, void *data)
2882 {
2883         REQUEST *request = fr_packet2myptr(REQUEST, proxy, data);
2884
2885         fr_packet_list_yank(proxy_list, request->proxy);
2886         request->in_proxy_hash = FALSE;
2887
2888         if (!request->in_request_hash) {
2889                 fr_event_delete(el, &request->ev);
2890                 request_free(&request);
2891         }
2892
2893         return 0;
2894 }
2895 #endif
2896
2897 void radius_event_free(void)
2898 {
2899         /*
2900          *      FIXME: Stop all threads, or at least check that
2901          *      they're all waiting on the semaphore, and the queues
2902          *      are empty.
2903          */
2904
2905 #ifdef WITH_PROXY
2906         /*
2907          *      There are requests in the proxy hash that aren't
2908          *      referenced from anywhere else.  Remove them first.
2909          */
2910         if (proxy_list) {
2911                 PTHREAD_MUTEX_LOCK(&proxy_mutex);
2912                 fr_packet_list_walk(proxy_list, NULL, proxy_hash_cb);
2913                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
2914                 fr_packet_list_free(proxy_list);
2915                 proxy_list = NULL;
2916         }
2917 #endif
2918
2919         fr_packet_list_walk(pl, NULL, request_hash_cb);
2920
2921         fr_packet_list_free(pl);
2922         pl = NULL;
2923
2924         fr_event_list_free(el);
2925 }
2926
2927 int radius_event_process(void)
2928 {
2929         if (!el) return 0;
2930
2931         just_started = TRUE;
2932
2933         return fr_event_loop(el);
2934 }
2935
2936 void radius_handle_request(REQUEST *request, RAD_REQUEST_FUNP fun)
2937 {
2938         if (request_pre_handler(request)) {
2939                 rad_assert(fun != NULL);
2940                 rad_assert(request != NULL);
2941                 
2942                 if (request->server) DEBUG("server %s {",
2943                                              request->server); 
2944                 fun(request);
2945
2946                 if (request->server) DEBUG("} # server %s",
2947                                              request->server);
2948
2949                 request_post_handler(request);
2950         }
2951
2952         DEBUG2("Going to the next request");
2953         return;
2954 }