Make hash table have comparison callback, it's needed.
[freeradius.git] / src / main / listen.c
1 /*
2  * listen.c     Handle socket stuff
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 2005  The FreeRADIUS server project
21  * Copyright 2005  Alan DeKok <aland@ox.org>
22  */
23
24 #include <freeradius-devel/autoconf.h>
25
26 #include <stdlib.h>
27 #include <string.h>
28
29 #ifdef HAVE_NETINET_IN_H
30 #include <netinet/in.h>
31 #endif
32
33 #ifdef HAVE_ARPA_INET_H
34 #include <arpa/inet.h>
35 #endif
36
37 #include <sys/resource.h>
38 #include <unistd.h>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netdb.h>
42
43 #ifdef HAVE_NET_IF_H
44 #include <net/if.h>
45 #endif
46
47 #ifdef HAVE_SYS_STAT_H
48 #include <sys/stat.h>
49 #endif
50
51 #ifdef WITH_UDPFROMTO
52 #include <freeradius-devel/udpfromto.h>
53 #endif
54
55 #include <fcntl.h>
56
57 #include <freeradius-devel/radiusd.h>
58 #include <freeradius-devel/rad_assert.h>
59 #include <freeradius-devel/conffile.h>
60 #include <freeradius-devel/token.h>
61
62 #include <freeradius-devel/radius_snmp.h>
63 #include <freeradius-devel/request_list.h>
64
65 static time_t start_time = 0;
66
67 /*
68  *      FIXME: Delete this crap!
69  */
70 extern time_t time_now;
71
72 /*
73  *      We'll use this below.
74  */
75 typedef int (*rad_listen_parse_t)(const char *, int, const CONF_SECTION *, rad_listen_t *);
76 typedef void (*rad_listen_free_t)(rad_listen_t *);
77
78 typedef struct rad_listen_master_t {
79         rad_listen_parse_t      parse;
80         rad_listen_free_t       free;
81         rad_listen_recv_t       recv;
82         rad_listen_send_t       send;
83         rad_listen_update_t     update;
84         rad_listen_print_t      print;
85 } rad_listen_master_t;
86
87 typedef struct listen_socket_t {
88         /*
89          *      For normal sockets.
90          */
91         lrad_ipaddr_t   ipaddr;
92         int             port;
93         RADCLIENT_LIST  *clients;
94 } listen_socket_t;
95
96 typedef struct listen_detail_t {
97         const char      *detail;
98         VALUE_PAIR      *vps;
99         FILE            *fp;
100         int             state;
101         time_t          timestamp;
102         lrad_ipaddr_t   client_ip;
103         int             max_outstanding;
104         int             *outstanding;
105 } listen_detail_t;
106                                
107
108 /*
109  *      Find a per-socket client.
110  */
111 static RADCLIENT *client_listener_find(const rad_listen_t *listener,
112                                        const lrad_ipaddr_t *ipaddr)
113 {
114         const RADCLIENT_LIST *clients;
115
116         rad_assert(listener != NULL);
117         rad_assert(ipaddr != NULL);
118
119         rad_assert((listener->type == RAD_LISTEN_AUTH) ||
120                    (listener->type == RAD_LISTEN_ACCT));
121
122         clients = ((listen_socket_t *)listener->data)->clients;
123         if (!clients) clients = mainconfig.clients;
124
125         rad_assert(clients != NULL);
126         
127         return client_find(clients, ipaddr);
128 }
129
130 static int listen_bind(rad_listen_t *this);
131
132 /*
133  *      FIXME: have the detail reader use another config "exit when done",
134  *      so that it can be used as a one-off tool to update stuff.
135  */
136
137 /*
138  *      Process and reply to a server-status request.
139  *      Like rad_authenticate and rad_accounting this should
140  *      live in it's own file but it's so small we don't bother.
141  */
142 static int rad_status_server(REQUEST *request)
143 {
144         char            reply_msg[64];
145         time_t          t;
146         VALUE_PAIR      *vp;
147
148         /*
149          *      Reply with an ACK. We might want to add some more
150          *      interesting reply attributes, such as server uptime.
151          */
152         t = request->timestamp - start_time;
153         sprintf(reply_msg, "FreeRADIUS up %d day%s, %02d:%02d",
154                 (int)(t / 86400), (t / 86400) == 1 ? "" : "s",
155                 (int)((t / 3600) % 24), (int)(t / 60) % 60);
156         request->reply->code = PW_AUTHENTICATION_ACK;
157
158         vp = pairmake("Reply-Message", reply_msg, T_OP_SET);
159         pairadd(&request->reply->vps, vp); /* don't need to check if !vp */
160
161         return 0;
162 }
163
164 static int request_num_counter = 0;
165
166 /*
167  *      Check for dups, etc.  Common to Access-Request &&
168  *      Accounting-Request packets.
169  */
170 static int common_checks(rad_listen_t *listener,
171                          RADIUS_PACKET *packet, REQUEST **prequest,
172                          const RADCLIENT *client)
173 {
174         REQUEST *curreq;
175         char buffer[128];
176
177         rad_assert(listener->rl != NULL);
178
179         /*
180          *      If there is no existing request of id, code, etc.,
181          *      then we can return, and let it be processed.
182          */
183         if ((curreq = rl_find(listener->rl, packet)) == NULL) {
184                 /*
185                  *      Count the total number of requests, to see if
186                  *      there are too many.  If so, return with an
187                  *      error.
188                  */
189                 if (mainconfig.max_requests) {
190                         /*
191                          *      FIXME: This is now per-socket,
192                          *      when it should really be global
193                          *      to the server!
194                          */
195                         int request_count = rl_num_requests(listener->rl);
196
197                         /*
198                          *      This is a new request.  Let's see if
199                          *      it makes us go over our configured
200                          *      bounds.
201                          */
202                         if (request_count > mainconfig.max_requests) {
203                                 radlog(L_ERR, "Dropping request (%d is too many): "
204                                        "from client %s port %d - ID: %d", request_count,
205                                        client->shortname,
206                                        packet->src_port, packet->id);
207                                 radlog(L_INFO, "WARNING: Please check the %s file.\n"
208                                        "\tThe value for 'max_requests' is probably set too low.\n", mainconfig.radiusd_conf);
209                                 return 0;
210                         } /* else there were a small number of requests */
211                 } /* else there was no configured limit for requests */
212
213                 /*
214                  *      FIXME: Add checks for system load.  If the
215                  *      system is busy, start dropping requests...
216                  *
217                  *      We can probably keep some statistics
218                  *      ourselves...  if there are more requests
219                  *      coming in than we can handle, start dropping
220                  *      some.
221                  */
222
223         /*
224          *      The current request isn't finished, which
225          *      means that the NAS sent us a new packet, while
226          *      we are still processing the old request.
227          */
228         } else if (!curreq->finished) {
229                 /*
230                  *      If the authentication vectors are identical,
231                  *      then the NAS is re-transmitting it, trying to
232                  *      kick us into responding to the request.
233                  */
234                 if (memcmp(curreq->packet->vector, packet->vector,
235                            sizeof(packet->vector)) == 0) {
236                         RAD_SNMP_INC(rad_snmp.auth.total_dup_requests);
237
238                         /*
239                          *      It's not finished because the request
240                          *      was proxied, but there was no reply
241                          *      from the home server.
242                          *
243                          *      This code will never get hit for
244                          *      accounting packets, as they're always
245                          *      updated, and never re-transmitted.
246                          */
247                         if (curreq->proxy && !curreq->proxy_reply) {
248                                 DEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
249                                        inet_ntop(curreq->proxy->dst_ipaddr.af,
250                                                  &curreq->proxy->dst_ipaddr.ipaddr,
251                                                  buffer, sizeof(buffer)),                                              curreq->proxy->dst_port,
252                                        
253                                        curreq->proxy->id);
254                                 listener->send(curreq->proxy_listener, curreq);
255                                 return 0;
256                         } /* else the packet was not proxied */
257
258                         /*
259                          *      Someone's still working on it, so we
260                          *      ignore the duplicate request.
261                          */
262                         radlog(L_ERR, "Discarding duplicate request from "
263                                "client %s port %d - ID: %d due to unfinished request %d",
264                                client->shortname,
265                                packet->src_port, packet->id,
266                                curreq->number);
267                         return 0;
268                 } /* else the authentication vectors were different */
269
270                 /*
271                  *      The authentication vectors are different, so
272                  *      the NAS has given up on us, as we've taken too
273                  *      long to process the request.  This is a
274                  *      SERIOUS problem!
275                  */
276                 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
277
278                 radlog(L_ERR, "Dropping conflicting packet from "
279                        "client %s port %d - ID: %d due to unfinished request %d",
280                        client->shortname,
281                        packet->src_port, packet->id,
282                        curreq->number);
283                 return 0;
284                 
285                 /*
286                  *      The old request is finished.  We now check the
287                  *      authentication vectors.  If the client has sent us a
288                  *      request with identical code && ID, but different
289                  *      vector, then they MUST have gotten our response, so we
290                  *      can delete the original request, and process the new
291                  *      one.
292                  *
293                  *      If the vectors are the same, then it's a duplicate
294                  *      request, and we can send a duplicate reply.
295                  */
296         } else if (memcmp(curreq->packet->vector, packet->vector,
297                           sizeof(packet->vector)) == 0) {
298                 RAD_SNMP_INC(rad_snmp.auth.total_dup_requests);
299
300                 /*
301                  *      If the packet has been delayed, then silently
302                  *      send a response, and clear the delayed flag.
303                  *
304                  *      Note that this means if the NAS kicks us while
305                  *      we're delaying a reject, then the reject may
306                  *      be sent sooner than otherwise.
307                  *
308                  *      This COULD be construed as a bug.  Maybe what
309                  *      we want to do is to ignore the duplicate
310                  *      packet, and send the reject later.
311                  */
312                 if (curreq->options & RAD_REQUEST_OPTION_DELAYED_REJECT) {
313                         curreq->options &= ~RAD_REQUEST_OPTION_DELAYED_REJECT;
314                         rad_assert(curreq->listener == listener);
315                         listener->send(listener, curreq);
316                         return 0;
317                 }
318
319                 /*
320                  *      Maybe we've saved a reply packet.  If so,
321                  *      re-send it.  Otherwise, just complain.
322                  */
323                 if (curreq->reply->code != 0) {
324                         DEBUG2("Sending duplicate reply "
325                                "to client %s port %d - ID: %d",
326                                client->shortname,
327                                packet->src_port, packet->id);
328                         rad_assert(curreq->listener == listener);
329                         listener->send(listener, curreq);
330                         return 0;
331                 }
332
333                 /*
334                  *      Else we never sent a reply to the NAS,
335                  *      as we decided somehow we didn't like the request.
336                  *
337                  *      This shouldn't happen, in general...
338                  */
339                 DEBUG2("Discarding duplicate request from client %s port %d - ID: %d",
340                        client->shortname, packet->src_port, packet->id);
341                 return 0;
342         } /* else the vectors were different, so we discard the old request. */
343
344         /*
345          *      'packet' has the same source IP, source port, code,
346          *      and Id as 'curreq', but a different authentication
347          *      vector.  We can therefore delete 'curreq', as we were
348          *      only keeping it around to send out duplicate replies,
349          *      if the first reply got lost in the network.
350          */
351         if (curreq) {
352                 RADIUS_PACKET *reply = curreq->reply;
353
354                 rl_yank(listener->rl, curreq);
355                 rad_free(&curreq->packet);
356
357                 if (curreq->reply) {
358                         reply = curreq->reply;
359                         pairfree(&reply->vps);
360                         free(reply->data);
361                         memset(reply, 0, sizeof(*reply));
362                 }
363                 memset(curreq, 0, sizeof(*curreq));
364 #ifndef NDEBUG
365                 curreq->magic = REQUEST_MAGIC;
366 #endif
367                 curreq->timestamp = time(NULL);
368                 curreq->child_pid = NO_SUCH_CHILD_PID;
369                 curreq->options = RAD_REQUEST_OPTION_NONE;
370                 curreq->reply = reply;
371         } else {
372                 /*
373                  *      A unique per-request counter.
374                  */
375                 curreq = request_alloc(); /* never fails */
376
377                 if ((curreq->reply = rad_alloc(0)) == NULL) {
378                         radlog(L_ERR, "No memory");
379                         exit(1);
380                 }
381         }
382         curreq->listener = listener;
383         curreq->packet = packet;
384         curreq->packet->timestamp = curreq->timestamp;
385         curreq->number = request_num_counter++;
386         strNcpy(curreq->secret, client->secret, sizeof(curreq->secret));
387         
388         /*
389          *      Remember the request in the list.
390          */
391         if (!rl_add(listener->rl, curreq)) {
392                 radlog(L_ERR, "Failed to insert request %d in the list of live requests: discarding", curreq->number);
393                 request_free(&curreq);
394                 return 0;
395         }
396         
397         /*
398          *      The request passes many of our sanity checks.
399          *      From here on in, if anything goes wrong, we
400          *      send a reject message, instead of dropping the
401          *      packet.
402          */
403
404         /*
405          *      Build the reply template from the request.
406          */
407
408         curreq->reply->sockfd = curreq->packet->sockfd;
409         curreq->reply->dst_ipaddr = curreq->packet->src_ipaddr;
410         curreq->reply->src_ipaddr = curreq->packet->dst_ipaddr;
411         curreq->reply->dst_port = curreq->packet->src_port;
412         curreq->reply->src_port = curreq->packet->dst_port;
413         curreq->reply->id = curreq->packet->id;
414         curreq->reply->code = 0; /* UNKNOWN code */
415         memcpy(curreq->reply->vector, curreq->packet->vector,
416                sizeof(curreq->reply->vector));
417         curreq->reply->vps = NULL;
418         curreq->reply->data = NULL;
419         curreq->reply->data_len = 0;
420
421         *prequest = curreq;
422         return 1;
423 }
424
425
426 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
427 {
428         size_t len;
429         listen_socket_t *sock = this->data;
430
431         if ((sock->ipaddr.af == AF_INET) &&
432             (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
433                 strcpy(buffer, "*");
434         } else {
435                 ip_ntoh(&sock->ipaddr, buffer, bufsize);
436         }
437
438         len = strlen(buffer);
439
440         return len + snprintf(buffer + len, bufsize - len, " port %d",
441                               sock->port);
442 }
443
444
445 /*
446  *      Parse an authentication or accounting socket.
447  */
448 static int common_socket_parse(const char *filename, int lineno,
449                              const CONF_SECTION *cs, rad_listen_t *this)
450 {
451         int             rcode;
452         int             listen_port;
453         lrad_ipaddr_t   ipaddr;
454         listen_socket_t *sock = this->data;
455         const char      *section_name = NULL;
456         CONF_SECTION    *client_cs;
457
458         /*
459          *      Try IPv4 first
460          */
461         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
462         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
463                               &ipaddr.ipaddr.ip4addr, NULL);
464         if (rcode < 0) return -1;
465         
466         if (rcode == 0) { /* successfully parsed IPv4 */
467                 ipaddr.af = AF_INET;
468                 
469         } else {        /* maybe IPv6? */
470                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
471                                       &ipaddr.ipaddr.ip6addr, NULL);
472                 if (rcode < 0) return -1;
473                 
474                 if (rcode == 1) {
475                         radlog(L_ERR, "%s[%d]: No address specified in listen section",
476                                filename, lineno);
477                         return -1;
478                 }
479                 ipaddr.af = AF_INET6;
480         }
481         
482         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
483                               &listen_port, "0");
484         if (rcode < 0) return -1;
485         
486         sock->ipaddr = ipaddr;
487         sock->port = listen_port;
488
489         /*
490          *      And bind it to the port.
491          */
492         if (listen_bind(this) < 0) {
493                 char buffer[128];
494                 radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s port %d",
495                        filename, cf_section_lineno(cs),
496                        ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
497                        sock->port);
498                 return -1;
499         }
500
501         /*
502          *      If we can bind to interfaces, do so,
503          *      else don't.
504          */
505         if (cf_pair_find(cs, "interface")) {
506 #ifndef SO_BINDTODEVICE
507                 radlog(L_CONS|L_ERR, "%s[%d]: System does not support binding to interfaces, delete this line from the configuration file.",
508                        filename, cf_section_lineno(cs));
509                 return -1;
510 #else
511                 const char *value;
512                 const CONF_PAIR *cp = cf_pair_find(cs, "interface");
513                 struct ifreq ifreq;
514
515                 rad_assert(cp != NULL);
516                 value = cf_pair_value(cp);
517                 rad_assert(value != NULL);
518                 
519                 strcpy(ifreq.ifr_name, value);
520         
521                 if (setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
522                                (char *)&ifreq, sizeof(ifreq)) < 0) {
523                         radlog(L_CONS|L_ERR, "%s[%d]: Failed binding to interface %s: %s",
524                                filename, cf_section_lineno(cs),
525                                value, strerror(errno));
526                         return -1;
527                 } /* else it worked. */
528 #endif
529         }
530
531         /*
532          *      Look for the name of a section that holds a list
533          *      of clients.
534          */
535         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
536                               &section_name, NULL);
537         if (rcode < 0) return -1; /* bad string */
538         if (rcode > 0) return 0; /* non-existent is OK. */
539
540         client_cs = cf_section_find(section_name);
541         if (!client_cs) {
542                 radlog(L_CONS|L_ERR, "%s[%d]: Failed to find client section %s",
543                        filename, cf_section_lineno(cs), section_name);
544                 return -1;
545         }
546
547         sock->clients = clients_parse_section(filename, client_cs);
548         if (!sock->clients) {
549                 return -1;
550         }
551
552         return 0;
553 }
554
555 /*
556  *      Send an authentication response packet
557  */
558 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
559 {
560         rad_assert(request->listener == listener);
561         rad_assert(listener->send == auth_socket_send);
562
563         /*
564          *      Ensure that the reply is sane
565          */
566         if (request->reply->code == 0) {
567                 DEBUG2("There was no response configured: rejecting request %d", request->number);
568                 request->reply->code = PW_AUTHENTICATION_REJECT;
569         }
570
571         /*
572          *      If we're delaying authentication rejects, then
573          *      mark the request as delayed, and do NOT send a
574          *      response right now.
575          *
576          *      However, if it's already marked as delayed, then
577          *      send it now.
578          */
579         if ((request->reply->code == PW_AUTHENTICATION_REJECT) &&
580             ((request->options & RAD_REQUEST_OPTION_DELAYED_REJECT) == 0) &&
581             (mainconfig.reject_delay > 0) &&
582             ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) == 0)) {
583                 DEBUG2("Delaying request %d for %d seconds",
584                        request->number, mainconfig.reject_delay);
585                 request->options |= RAD_REQUEST_OPTION_DELAYED_REJECT;
586                 return 0;
587         }
588
589         return rad_send(request->reply, request->packet, request->secret);
590 }
591
592
593 /*
594  *      Send an accounting response packet (or not)
595  */
596 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
597 {
598         rad_assert(request->listener == listener);
599         rad_assert(listener->send == acct_socket_send);
600
601         /*
602          *      Accounting reject's are silently dropped.
603          *
604          *      We do it here to avoid polluting the rest of the
605          *      code with this knowledge
606          */
607         if (request->reply->code == 0) return 0;
608
609         return rad_send(request->reply, request->packet, request->secret);
610 }
611
612
613 /*
614  *      Send a packet to a home server.
615  *
616  *      FIXME: have different code for proxy auth & acct!
617  */
618 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
619 {
620         listen_socket_t *sock = listener->data;
621
622         rad_assert(request->proxy_listener == listener);
623         rad_assert(listener->send == proxy_socket_send);
624
625         request->proxy->src_ipaddr = sock->ipaddr;
626         request->proxy->src_port = sock->port;
627
628         return rad_send(request->proxy, request->packet, request->proxysecret);
629 }
630
631
632 /*
633  *      Check if an incoming request is "ok"
634  *
635  *      It takes packets, not requests.  It sees if the packet looks
636  *      OK.  If so, it does a number of sanity checks on it.
637   */
638 static int auth_socket_recv(rad_listen_t *listener,
639                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
640 {
641         RADIUS_PACKET   *packet;
642         RAD_REQUEST_FUNP fun = NULL;
643         char            buffer[128];
644         RADCLIENT       *client;
645
646         packet = rad_recv(listener->fd);
647         if (!packet) {
648                 radlog(L_ERR, "%s", librad_errstr);
649                 return 0;
650         }
651
652         RAD_SNMP_TYPE_INC(listener, total_requests); /* FIXME: auth specific */
653
654         if ((client = client_listener_find(listener,
655                                            &packet->src_ipaddr)) == NULL) {
656                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
657                 
658                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
659                        inet_ntop(packet->src_ipaddr.af,
660                                  &packet->src_ipaddr.ipaddr,
661                                  buffer, sizeof(buffer)),
662                        packet->src_port);
663                 rad_free(&packet);
664                 return 0;
665         }
666
667         /*
668          *      Some sanity checks, based on the packet code.
669          */
670         switch(packet->code) {
671         case PW_AUTHENTICATION_REQUEST:
672                 fun = rad_authenticate;
673                 break;
674                 
675         case PW_STATUS_SERVER:
676                 if (!mainconfig.status_server) {
677                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
678                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
679                         rad_free(&packet);
680                         return 0;
681                 }
682                 fun = rad_status_server;
683                 break;
684
685         default:
686                 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
687                 
688                 radlog(L_ERR, "Invalid packet code %d sent to authentication port from client %s port %d "
689                        "- ID %d : IGNORED",
690                        packet->code, client->shortname,
691                        packet->src_port, packet->id);
692                 rad_free(&packet);
693                 return 0;
694                 break;
695         } /* switch over packet types */
696         
697         if (!common_checks(listener, packet, prequest, client)) {
698                 rad_free(&packet);
699                 return 0;
700         }
701
702         *pfun = fun;
703         return 1;
704 }
705
706
707 /*
708  *      Receive packets from an accounting socket
709  */
710 static int acct_socket_recv(rad_listen_t *listener,
711         RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
712 {
713         RADIUS_PACKET   *packet;
714         RAD_REQUEST_FUNP fun = NULL;
715         char            buffer[128];
716         RADCLIENT       *client;
717         
718         packet = rad_recv(listener->fd);
719         if (!packet) {
720                 radlog(L_ERR, "%s", librad_errstr);
721                 return 0;
722         }
723         
724         RAD_SNMP_TYPE_INC(listener, total_requests); /* FIXME: acct-specific */
725
726         if ((client = client_listener_find(listener,
727                                            &packet->src_ipaddr)) == NULL) {
728                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
729                 
730                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
731                        inet_ntop(packet->src_ipaddr.af,
732                                  &packet->src_ipaddr.ipaddr,
733                                  buffer, sizeof(buffer)),
734                        packet->src_port);
735                 rad_free(&packet);
736                 return 0;
737         }
738
739         switch(packet->code) {
740         case PW_ACCOUNTING_REQUEST:
741                 fun = rad_accounting;
742                 break;
743                 
744         default:
745                 /*
746                  *      FIXME: Update MIB for packet types?
747                  */
748                 radlog(L_ERR, "Invalid packet code %d sent to a accounting port "
749                        "from client %s port %d - ID %d : IGNORED",
750                        packet->code, client->shortname,
751                        packet->src_port, packet->id);
752                 rad_free(&packet);
753                 return 0;
754         }
755
756         /*
757          *      FIXME: Accounting duplicates should be handled
758          *      differently than authentication duplicates.
759          */
760         if (!common_checks(listener, packet, prequest, client)) {
761                 rad_free(&packet);
762                 return 0;
763         }
764
765         *pfun = fun;
766         return 1;
767 }
768
769
770 /*
771  *      Recieve packets from a proxy socket.
772  */
773 static int proxy_socket_recv(rad_listen_t *listener,
774                               RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
775 {
776         REALM           *cl;
777         REQUEST         *oldreq;
778         RADIUS_PACKET   *packet;
779         RAD_REQUEST_FUNP fun = NULL;
780         char            buffer[128];
781         
782         packet = rad_recv(listener->fd);
783         if (!packet) {
784                 radlog(L_ERR, "%s", librad_errstr);
785                 return 0;
786         }
787
788         /*
789          *      Unsupported stuff
790          */
791         if (packet->src_ipaddr.af != AF_INET) {
792                 rad_assert("PROXY IPV6 NOT SUPPORTED" == NULL);
793         }
794         
795         /*
796          *      FIXME: Add support for home servers!
797          */
798         if ((cl = realm_findbyaddr(packet->src_ipaddr.ipaddr.ip4addr.s_addr,
799                                    packet->src_port)) == NULL) {
800                 radlog(L_ERR, "Ignoring request from unknown home server %s port %d",
801                        inet_ntop(packet->src_ipaddr.af,
802                                  &packet->src_ipaddr.ipaddr,
803                                  buffer, sizeof(buffer)),
804                                packet->src_port);
805                 rad_free(&packet);
806                 return 0;
807         }
808
809         /*
810          *      FIXME: Client MIB updates?
811          */
812         switch(packet->code) {
813         case PW_AUTHENTICATION_ACK:
814         case PW_ACCESS_CHALLENGE:
815         case PW_AUTHENTICATION_REJECT:
816                 fun = rad_authenticate;
817                 break;
818                 
819         case PW_ACCOUNTING_RESPONSE:
820                 fun = rad_accounting;
821                 break;
822                 
823         default:
824                 /*
825                  *      FIXME: Update MIB for packet types?
826                  */
827                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
828                        "from home server %s port %d - ID %d : IGNORED",
829                        packet->code,
830                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
831                        packet->src_port, packet->id);
832                 rad_free(&packet);
833                 return 0;
834         }
835
836         /*
837          *      Find the original request in the request list
838          */
839         oldreq = rl_find_proxy(packet);
840
841         /*
842          *      If we haven't found the original request which was
843          *      sent, to get this reply.  Complain, and discard this
844          *      request, as there's no way for us to send it to a NAS.
845          */
846         if (!oldreq) {
847                 radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s port %d - ID %d",
848                        inet_ntop(packet->src_ipaddr.af,
849                                  &packet->src_ipaddr.ipaddr,
850                                  buffer, sizeof(buffer)),
851                        packet->src_port, packet->id);
852                 rad_free(&packet);
853                 return 0;
854         }
855
856         /*
857          *      The proxy reply has arrived too late, as the original
858          *      (old) request has timed out, been rejected, and marked
859          *      as finished.  The client has already received a
860          *      response, so there is nothing that can be done. Delete
861          *      the tardy reply from the home server, and return nothing.
862          */
863         if ((oldreq->reply->code != 0) ||
864             (oldreq->finished)) {
865                 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'",
866                        inet_ntop(packet->src_ipaddr.af,
867                                  &packet->src_ipaddr.ipaddr,
868                                  buffer, sizeof(buffer)),
869                        packet->src_port, packet->id,
870                        oldreq->number);
871                 rad_free(&packet);
872                 return 0;
873         }
874
875         /*
876          *      If there is already a reply, maybe this one is a
877          *      duplicate?
878          */
879         if (oldreq->proxy_reply) {
880                 if (memcmp(oldreq->proxy_reply->vector,
881                            packet->vector,
882                            sizeof(oldreq->proxy_reply->vector)) == 0) {
883                         radlog(L_ERR, "Discarding duplicate reply from home server %s port %d  - ID: %d for request %d",
884                                inet_ntop(packet->src_ipaddr.af,
885                                          &packet->src_ipaddr.ipaddr,
886                                          buffer, sizeof(buffer)),
887                                packet->src_port, packet->id,
888                                oldreq->number);
889                 } else {
890                         /*
891                          *      ? The home server gave us a new proxy
892                          *      reply, which doesn't match the old
893                          *      one.  Delete it.
894                          */
895                         DEBUG2("Ignoring conflicting proxy reply");
896                 }
897
898                 /*
899                  *      We've already received a reply, so
900                  *      we discard this one, as we don't want
901                  *      to do duplicate work.
902                  */
903                 rad_free(&packet);
904                 return 0;
905         } /* else there wasn't a proxy reply yet, so we can process it */
906
907         /*
908          *       Refresh the old request, and update it with the proxy
909          *       reply.
910          *
911          *      ? Can we delete the proxy request here?  * Is there
912          *      any more need for it?
913          *
914          *      FIXME: we probably shouldn't be updating the time
915          *      stamp here.
916          */
917         oldreq->timestamp = time_now;
918         oldreq->proxy_reply = packet;
919
920         /*
921          *      FIXME: we should really verify the digest here,
922          *      before marking this packet as a valid response.
923          *
924          *      This is a security problem, I think...
925          */
926
927         /*
928          *      Now that we've verified the packet IS actually from
929          *      that home server, and not forged, we can go mark the
930          *      entries for this home server as active.
931          *
932          *      If we had done this check in the 'find realm by IP address'
933          *      function, then an attacker could force us to use a home
934          *      server which was inactive, by forging reply packets
935          *      which didn't match any request.  We would think that
936          *      the reply meant the home server was active, would
937          *      re-activate the realms, and THEN bounce the packet
938          *      as garbage.
939          */
940         for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
941                 if (oldreq->proxy_reply->src_ipaddr.af != cl->ipaddr.af) continue;
942                 if (cl->ipaddr.af != AF_INET) continue; /* FIXME */
943
944                 if (oldreq->proxy_reply->src_ipaddr.ipaddr.ip4addr.s_addr == cl->ipaddr.ipaddr.ip4addr.s_addr) {
945                         if (oldreq->proxy_reply->src_port == cl->auth_port) {
946                                 cl->active = TRUE;
947                                 cl->last_reply = oldreq->timestamp;
948                         } else if (oldreq->proxy_reply->src_port == cl->acct_port) {
949                                 cl->acct_active = TRUE;
950                                 cl->last_reply = oldreq->timestamp;
951                         }
952                 }
953         }
954
955         rad_assert(fun != NULL);
956         *pfun = fun;
957         *prequest = oldreq;
958
959         return 1;
960 }
961
962 #define STATE_UNOPENED  (0)
963 #define STATE_UNLOCKED  (1)
964 #define STATE_HEADER    (2)
965 #define STATE_READING   (3)
966 #define STATE_DONE      (4)
967 #define STATE_WAITING   (5)
968
969 /*
970  *      If we're limiting outstanding packets, then mark the response
971  *      as being sent.
972  */
973 static int detail_send(rad_listen_t *listener, REQUEST *request)
974 {
975         listen_detail_t *data = listener->data;
976
977         rad_assert(request->listener == listener);
978         rad_assert(listener->send == detail_send);
979
980         if (request->simul_max >= 0) {
981                 rad_assert(data->outstanding != NULL);
982                 rad_assert(request->simul_max < data->max_outstanding);
983
984                 data->outstanding[request->simul_max] = 0;
985         }
986
987         return 0;
988 }
989
990
991 /*
992  *      Open the detail file..
993  *
994  *      FIXME: create it, if it's not already there, so that the main
995  *      server select() will wake us up if there's anything to read.
996  */
997 static int detail_open(rad_listen_t *this)
998 {
999         struct stat st;
1000         char buffer[2048];
1001         listen_detail_t *data = this->data;
1002
1003         rad_assert(data->state == STATE_UNOPENED);
1004         snprintf(buffer, sizeof(buffer), "%s.work", data->detail);
1005         
1006         /*
1007          *      FIXME: Have "one-shot" configuration, where it
1008          *      will read the detail file, and exit once it's
1009          *      done.
1010          *
1011          *      FIXME: Try harder to open the detail file.
1012          *      Maybe sleep for X usecs if it doesn't exist?
1013          */
1014
1015         /*
1016          *      Open detail.work first, so we don't lose
1017          *      accounting packets.  It's probably better to
1018          *      duplicate them than to lose them.
1019          *
1020          *      Note that we're not writing to the file, but
1021          *      we've got to open it for writing in order to
1022          *      establish the lock, to prevent rlm_detail from
1023          *      writing to it.
1024          */
1025         this->fd = open(buffer, O_RDWR);
1026         if (this->fd < 0) {
1027                 /*
1028                  *      Try reading the detail file.  If it
1029                  *      doesn't exist, we can't do anything.
1030                  *
1031                  *      Doing the stat will tell us if the file
1032                  *      exists, even if we don't have permissions
1033                  *      to read it.
1034                  */
1035                 if (stat(data->detail, &st) < 0) {
1036                         return 0;
1037                 }
1038                 
1039                 /*
1040                  *      Open it BEFORE we rename it, just to
1041                  *      be safe...
1042                  */
1043                 this->fd = open(data->detail, O_RDWR);
1044                 if (this->fd < 0) {
1045                         radlog(L_ERR, "Failed to open %s: %s",
1046                                data->detail, strerror(errno));
1047                         return 0;
1048                 }
1049                 
1050                 /*
1051                  *      Rename detail to detail.work
1052                  */
1053                 if (rename(data->detail, buffer) < 0) {
1054                         close(this->fd);
1055                         this->fd = -1;
1056                         return 0;
1057                 }
1058         } /* else detail.work existed, and we opened it */
1059         
1060         rad_assert(data->vps == NULL);
1061         
1062         rad_assert(data->fp == NULL);
1063         data->fp = fdopen(this->fd, "r");
1064         if (!data->fp) {
1065                 radlog(L_ERR, "Failed to re-open %s: %s",
1066                        data->detail, strerror(errno));
1067                 return 0;
1068         }
1069
1070         data->state = STATE_UNLOCKED;
1071
1072         data->client_ip.af = AF_UNSPEC;
1073         data->timestamp = 0;
1074         
1075         return 1;
1076 }
1077
1078 /*
1079  *      This is a bad hack, just so complaints have meaningful text.
1080  */
1081 static const RADCLIENT detail_client = {
1082         {               /* ipaddr */
1083                 AF_INET,
1084                 {{ INADDR_NONE }}
1085         },
1086         32,
1087         "<detail-file>",
1088         "secret",
1089         "UNKNOWN-CLIENT",
1090         "other",
1091         "",
1092         "",
1093         -1
1094 };
1095
1096 static int detail_recv(rad_listen_t *listener,
1097                        RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1098 {
1099         int             free_slot = -1;
1100         char            key[256], value[1024];
1101         VALUE_PAIR      *vp, **tail;
1102         RADIUS_PACKET   *packet;
1103         char            buffer[2048];
1104         listen_detail_t *data = listener->data;
1105
1106         if (data->state == STATE_UNOPENED) {
1107                 rad_assert(listener->fd < 0);
1108                 if (!detail_open(listener)) return 0;
1109         }
1110         rad_assert(listener->fd >= 0);
1111
1112         /*
1113          *      Try to lock fd.  If we can't, return.  If we can,
1114          *      continue.  This means that the server doesn't block
1115          *      while waiting for the lock to open...
1116          */
1117         if (data->state == STATE_UNLOCKED) {
1118                 /*
1119                  *      Note that we do NOT block waiting for the
1120                  *      lock.  We've re-named the file above, so we've
1121                  *      already guaranteed that any *new* detail
1122                  *      writer will not be opening this file.  The
1123                  *      only purpose of the lock is to catch a race
1124                  *      condition where the execution "ping-pongs"
1125                  *      between radiusd & radrelay.
1126                  */
1127                 if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
1128                         return 0;
1129                 }
1130                 /*
1131                  *      Look for the header
1132                  */
1133                 data->state = STATE_HEADER;
1134         }
1135
1136         /*
1137          *      If we keep track of the outstanding requests, do so
1138          *      here.  Note that to minimize potential work, we do
1139          *      so only once the file is opened & locked.
1140          */
1141         if (data->max_outstanding) {
1142                 int i;
1143
1144                 for (i = 0; i < data->max_outstanding; i++) {
1145                         if (!data->outstanding[i]) {
1146                                 free_slot = i;
1147                                 break;
1148                         }
1149                 }
1150
1151                 /*
1152                  *      All of the slots are full, don't read data.
1153                  */
1154                 if (free_slot < 0) return 0;
1155         }
1156
1157         /*
1158          *      Catch an out of memory condition which will most likely
1159          *      never be met.
1160          */
1161         if (data->state == STATE_DONE) goto alloc_packet;
1162
1163         /*
1164          *      If we're in another state, then it means that we read
1165          *      a partial packet, which is bad.
1166          */
1167         rad_assert(data->state == STATE_HEADER);
1168         rad_assert(data->vps == NULL);
1169
1170         /*
1171          *      We read the last packet, and returned it for
1172          *      processing.  We later come back here to shut
1173          *      everything down, and unlink the file.
1174          */
1175         if (feof(data->fp)) {
1176                 rad_assert(data->state == STATE_HEADER);
1177
1178                 /*
1179                  *      Don't unlink the file until we've received
1180                  *      all of the responses.
1181                  */
1182                 if (data->max_outstanding > 0) {
1183                         int i;
1184
1185                         for (i = 0; i < data->max_outstanding; i++) {
1186                                 /*
1187                                  *      FIXME: close the file?
1188                                  */
1189                                 if (data->outstanding[i]) {
1190                                         data->state = STATE_WAITING;
1191                                         return 0;
1192                                 }
1193                         }
1194                 }
1195
1196         cleanup:
1197                 rad_assert(data->vps == NULL);
1198
1199                 snprintf(buffer, sizeof(buffer), "%s.work", data->detail);
1200                 unlink(buffer);
1201                 fclose(data->fp); /* closes listener->fd */
1202                 data->fp = NULL;
1203                 listener->fd = -1;
1204                 data->state = STATE_UNOPENED;
1205
1206                 /*
1207                  *      Try to open "detail" again.  If we're on a
1208                  *      busy RADIUS server, odds are that it will
1209                  *      now exist.
1210                  */
1211                 detail_open(listener);
1212                 return 0;
1213         }
1214
1215         tail = &data->vps;
1216
1217         /*
1218          *      Fill the buffer...
1219          */
1220         while (fgets(buffer, sizeof(buffer), data->fp)) {
1221                 /*
1222                  *      No CR, die.
1223                  */
1224                 if (!strchr(buffer, '\n')) {
1225                         pairfree(&data->vps);
1226                         goto cleanup;
1227                 }
1228
1229                 /*
1230                  *      We've read a header, possibly packet contents,
1231                  *      and are now at the end of the packet.
1232                  */
1233                 if ((data->state == STATE_READING) &&
1234                     (buffer[0] == '\n')) {
1235                         data->state = STATE_DONE;
1236                         break;
1237                 }
1238
1239                 /*
1240                  *      Look for date/time header, and read VP's if
1241                  *      found.  If not, keep reading lines until we
1242                  *      find one.
1243                  */
1244                 if (data->state == STATE_HEADER) {
1245                         int y;
1246                         
1247                         if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
1248                                 data->state = STATE_READING;
1249                         }
1250                         continue;
1251                 }
1252
1253                 /*
1254                  *      We have a full "attribute = value" line.
1255                  *      If it doesn't look reasonable, skip it.
1256                  */
1257                 if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
1258                         continue;
1259                 }
1260
1261                 /*
1262                  *      Skip non-protocol attributes.
1263                  */
1264                 if (!strcasecmp(key, "Request-Authenticator")) continue;
1265
1266                 /*
1267                  *      Set the original client IP address, based on
1268                  *      what's in the detail file.
1269                  *
1270                  *      Hmm... we don't set the server IP address.
1271                  *      or port.  Oh well.
1272                  */
1273                 if (!strcasecmp(key, "Client-IP-Address")) {
1274                         data->client_ip.af = AF_INET;
1275                         ip_hton(value, AF_INET, &data->client_ip);
1276                         continue;
1277                 }
1278
1279                 /*
1280                  *      The original time at which we received the
1281                  *      packet.  We need this to properly calculate
1282                  *      Acct-Delay-Time.
1283                  */
1284                 if (!strcasecmp(key, "Timestamp")) {
1285                         data->timestamp = atoi(value);
1286                         continue;
1287                 }
1288
1289                 /*
1290                  *      Read one VP.
1291                  *
1292                  *      FIXME: do we want to check for non-protocol
1293                  *      attributes like radsqlrelay does?
1294                  */
1295                 vp = NULL;
1296                 if ((userparse(buffer, &vp) > 0) &&
1297                     (vp != NULL)) {
1298                         *tail = vp;
1299                         tail = &(vp->next);
1300                 }               
1301         }
1302
1303         /*
1304          *      We got to EOF,  If we're in STATE_HEADER, it's OK.
1305          *      Otherwise it's a problem.  In any case, nuke the file
1306          *      and start over from scratch,
1307          */
1308         if (feof(data->fp)) {
1309                 goto cleanup;
1310         }
1311
1312         /*
1313          *      FIXME: Do load management.
1314          */
1315
1316         /*
1317          *      If we're not done, then there's a problem.  The checks
1318          *      above for EOF
1319          */
1320         rad_assert(data->state == STATE_DONE);
1321
1322         /*
1323          *      The packet we read was empty, re-set the state to look
1324          *      for a header, and don't return anything.
1325          */
1326         if (!data->vps) {
1327                 data->state = STATE_HEADER;
1328                 return 0;
1329         }
1330
1331         /*
1332          *      Allocate the packet.  If we fail, it's a serious
1333          *      problem.
1334          */
1335  alloc_packet:
1336         packet = rad_alloc(1);
1337         if (!packet) {
1338                 return 0;       /* maybe memory will magically free up... */
1339         }
1340
1341         memset(packet, 0, sizeof(*packet));
1342         packet->sockfd = -1;
1343         packet->src_ipaddr.af = AF_INET;
1344         packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1345         packet->code = PW_ACCOUNTING_REQUEST;
1346         packet->timestamp = time(NULL);
1347
1348         /*
1349          *      Look for Acct-Delay-Time, and update
1350          *      based on Acct-Delay-Time += (time(NULL) - timestamp)
1351          */
1352         vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
1353         if (!vp) {
1354                 vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1355                 rad_assert(vp != NULL);
1356         }
1357         if (data->timestamp != 0) {
1358                 vp->lvalue += time(NULL) - data->timestamp;
1359         }
1360
1361         /*
1362          *      Remember where it came from, so that we don't
1363          *      proxy it to the place it came from...
1364          */
1365         if (data->client_ip.af != AF_UNSPEC) {
1366                 packet->src_ipaddr = data->client_ip;
1367         }
1368
1369         /*
1370          *      We've got to give SOME value for Id & ports, so that
1371          *      the packets can be added to the request queue.
1372          *      However, we don't want to keep track of used/unused
1373          *      id's and ports, as that's a lot of work.  This hack
1374          *      ensures that (if we have real random numbers), that
1375          *      there will be a collision on every (2^(16+16+2+24))/2
1376          *      packets, on average.  That means we can read 2^32 (4G)
1377          *      packets before having a collision, which means it's
1378          *      effectively impossible.  Having 4G packets currently
1379          *      being process is ridiculous.
1380          */
1381         packet->id = lrad_rand() & 0xff;
1382         packet->src_port = lrad_rand() & 0xffff;
1383         packet->dst_port = lrad_rand() & 0xffff;
1384
1385         packet->dst_ipaddr.af = AF_INET;
1386         packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
1387
1388         packet->vps = data->vps;
1389
1390         /*
1391          *      Re-set the state.
1392          */
1393         data->vps = NULL;
1394         data->state = STATE_HEADER;
1395
1396         /*
1397          *      FIXME: many of these checks may not be necessary...
1398          */
1399         if (!common_checks(listener, packet, prequest, &detail_client)) {
1400                 rad_free(&packet);
1401                 return 0;
1402         }
1403
1404         /*
1405          *      Keep track of free slots, as a hack, in an otherwise
1406          *      unused 'int'
1407          */
1408         (*prequest)->simul_max = free_slot;
1409         if (free_slot) data->outstanding[free_slot] = 1;
1410
1411         *pfun = rad_accounting;
1412
1413         if (debug_flag) {
1414                 printf("detail_recv: Read packet from %s\n", data->detail);
1415                 for (vp = packet->vps; vp; vp = vp->next) {
1416                         putchar('\t');
1417                         vp_print(stdout, vp);
1418                         putchar('\n');
1419                 }
1420         }
1421
1422         return 1;
1423 }
1424
1425
1426 /*
1427  *      Free detail-specific stuff.
1428  */
1429 static void detail_free(rad_listen_t *this)
1430 {
1431         listen_detail_t *data = this->data;
1432
1433         free(data->detail);
1434         pairfree(&data->vps);
1435         free(data->outstanding);
1436
1437         if (data->fp != NULL) fclose(data->fp);
1438 }
1439
1440
1441 static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
1442 {
1443         return snprintf(buffer, bufsize, "%s",
1444                         ((listen_detail_t *)(this->data))->detail);
1445 }
1446
1447
1448 static const CONF_PARSER detail_config[] = {
1449         { "detail",   PW_TYPE_STRING_PTR,
1450           offsetof(listen_detail_t, detail), NULL,  NULL },
1451         { "max_outstanding",  PW_TYPE_INTEGER,
1452            offsetof(listen_detail_t, max_outstanding), NULL, "100" },
1453
1454         { NULL, -1, 0, NULL, NULL }             /* end the list */
1455 };
1456
1457
1458 /*
1459  *      Parse a detail section.
1460  */
1461 static int detail_parse(const char *filename, int lineno,
1462                         const CONF_SECTION *cs, rad_listen_t *this)
1463 {
1464         int             rcode;
1465         listen_detail_t *data;
1466
1467         data = this->data;
1468
1469         rcode = cf_section_parse(cs, data, detail_config);
1470         if (rcode < 0) {
1471                 radlog(L_ERR, "%s[%d]: Failed parsing listen section",
1472                        filename, lineno);
1473                 return -1;
1474         }
1475
1476         if (!data->detail) {
1477                 radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
1478                        filename, lineno);
1479                 return -1;
1480         }
1481         
1482         data->vps = NULL;
1483         data->fp = NULL;
1484         data->state = STATE_UNOPENED;
1485
1486         if (data->max_outstanding > 32768) data->max_outstanding = 32768;
1487
1488         if (data->max_outstanding > 0) {
1489                 data->outstanding = rad_malloc(sizeof(int) * data->max_outstanding);
1490         }
1491         
1492         detail_open(this);
1493
1494         return 0;
1495 }
1496
1497
1498 /*
1499  *      See radiusd.c & request_list.c
1500  */
1501 #define SLEEP_FOREVER (65536)
1502 /*
1503  *      A generic "update the request list once a second" function.
1504  */
1505 static int generic_update(rad_listen_t *this, time_t now)
1506 {
1507         if (!this->rl) return SLEEP_FOREVER;
1508
1509         return rl_clean_list(this->rl, now);
1510 }
1511
1512
1513
1514 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1515         { NULL, NULL, NULL, NULL, NULL, NULL},  /* RAD_LISTEN_NONE */
1516
1517         /* authentication */
1518         { common_socket_parse, NULL,
1519           auth_socket_recv, auth_socket_send,
1520           generic_update, socket_print },
1521
1522         /* accounting */
1523         { common_socket_parse, NULL,
1524           acct_socket_recv, acct_socket_send,
1525           generic_update, socket_print},
1526
1527         /* proxying */
1528         { NULL, NULL,
1529           proxy_socket_recv, proxy_socket_send,
1530           generic_update, socket_print }, /* FIXME: update func is wrong! */
1531
1532         /* detail */
1533         { detail_parse, detail_free,
1534           detail_recv, detail_send,
1535           generic_update, detail_print }
1536 };
1537
1538
1539 /*
1540  *      Binds a listener to a socket.
1541  */
1542 static int listen_bind(rad_listen_t *this)
1543 {
1544         rad_listen_t    **last;
1545         listen_socket_t *sock = this->data;
1546
1547         /*
1548          *      If the port is zero, then it means the appropriate
1549          *      thing from /etc/services.
1550          */
1551         if (sock->port == 0) {
1552                 struct servent  *svp;
1553
1554                 switch (this->type) {
1555                 case RAD_LISTEN_AUTH:
1556                         svp = getservbyname ("radius", "udp");
1557                         if (svp != NULL) {
1558                                 sock->port = ntohs(svp->s_port);
1559                         } else {
1560                                 sock->port = PW_AUTH_UDP_PORT;
1561                         }
1562                         break;
1563
1564                 case RAD_LISTEN_ACCT:
1565                         svp = getservbyname ("radacct", "udp");
1566                         if (svp != NULL) {
1567                                 sock->port = ntohs(svp->s_port);
1568                         } else {
1569                                 sock->port = PW_ACCT_UDP_PORT;
1570                         }
1571                         break;
1572
1573                 default:
1574                         radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
1575                         return -1;
1576                 }
1577         }
1578
1579         /*
1580          *      Find it in the old list, AFTER updating the port.  If
1581          *      it's there, use that, rather than creating a new
1582          *      socket.  This allows HUP's to re-use the old sockets,
1583          *      which means that packets waiting in the socket queue
1584          *      don't get lost.
1585          */
1586         for (last = &mainconfig.listen;
1587              *last != NULL;
1588              last = &((*last)->next)) {
1589                 if ((this->type == (*last)->type) &&
1590                     (sock->port == ((listen_socket_t *)((*last)->data))->port) &&
1591                     (sock->ipaddr.af == ((listen_socket_t *)((*last)->data))->ipaddr.af)) {
1592                         int equal;
1593
1594                         if (sock->ipaddr.af == AF_INET) {
1595                                 equal = (sock->ipaddr.ipaddr.ip4addr.s_addr == ((listen_socket_t *)((*last)->data))->ipaddr.ipaddr.ip4addr.s_addr);
1596                         } else if (sock->ipaddr.af == AF_INET6) {
1597                                 equal = IN6_ARE_ADDR_EQUAL(&(sock->ipaddr.ipaddr.ip6addr), &(((listen_socket_t *)((*last)->data))->ipaddr.ipaddr.ip6addr));
1598                         } else {
1599                                 equal = 0;
1600                         }
1601                         
1602                         if (equal) {
1603                                 this->rl = (*last)->rl;
1604                                 this->fd = (*last)->fd;
1605                                 (*last)->fd = -1;
1606                                 (*last)->rl = NULL;
1607                                 return 0;
1608                         }
1609                 }
1610         }
1611
1612         this->fd = lrad_socket(&sock->ipaddr, sock->port);
1613         if (this->fd < 0) {
1614                 radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
1615                        librad_errstr);
1616                 return -1;
1617         }
1618
1619         return 0;
1620 }
1621
1622
1623 /*
1624  *      Allocate & initialize a new listener.
1625  */
1626 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1627 {
1628         rad_listen_t *this;
1629
1630         this = rad_malloc(sizeof(*this));
1631         memset(this, 0, sizeof(*this));
1632
1633         this->type = type;
1634         this->recv = master_listen[this->type].recv;
1635         this->send = master_listen[this->type].send;
1636         this->update = master_listen[this->type].update;
1637         this->print = master_listen[this->type].print;
1638
1639         switch (type) {
1640         case RAD_LISTEN_AUTH:
1641         case RAD_LISTEN_ACCT:
1642         case RAD_LISTEN_PROXY:
1643                 this->data = rad_malloc(sizeof(listen_socket_t));
1644                 memset(this->data, 0, sizeof(listen_socket_t));
1645                 break;
1646
1647         case RAD_LISTEN_DETAIL:
1648                 this->data = rad_malloc(sizeof(listen_detail_t));
1649                 memset(this->data, 0, sizeof(listen_detail_t));
1650                 
1651         default:
1652                 break;
1653         }
1654
1655         return this;
1656 }
1657
1658
1659 /*
1660  *      Externally visible function for creating a new proxy LISTENER.
1661  *
1662  *      For now, don't take ipaddr or port.
1663  *
1664  *      Not thread-safe, but all calls to it are protected by the
1665  *      proxy mutex in request_list.c
1666  */
1667 rad_listen_t *proxy_new_listener()
1668 {
1669         int last_proxy_port, port;
1670         rad_listen_t *this, *tmp, **last;
1671         listen_socket_t *sock, *old;
1672
1673         this = listen_alloc(RAD_LISTEN_PROXY);
1674
1675         /*
1676          *      Find an existing proxy socket to copy.
1677          *
1678          *      FIXME: Make it per-realm, or per-home server!
1679          */
1680         last_proxy_port = 0;
1681         old = NULL;
1682         last = &mainconfig.listen;
1683         for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1684                 if (tmp->type == RAD_LISTEN_PROXY) {
1685                         sock = tmp->data;
1686                         if (sock->port > last_proxy_port) {
1687                                 last_proxy_port = sock->port + 1;
1688                         }
1689                         if (!old) old = sock;
1690                 }
1691
1692                 last = &(tmp->next);
1693         }
1694
1695         if (!old) return NULL;  /* This is a serious error. */
1696
1697         /*
1698          *      FIXME: find a new IP address to listen on?
1699          */
1700         sock = this->data;
1701         memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1702
1703         /*
1704          *      Keep going until we find an unused port.
1705          */
1706         for (port = last_proxy_port; port < 64000; port++) {
1707                 sock->port = port;
1708                 if (listen_bind(this) == 0) {
1709                         /*
1710                          *      Add the new listener to the list of
1711                          *      listeners.
1712                          */
1713                         *last = this;
1714                         return this;
1715                 }
1716         }
1717
1718         return NULL;
1719 }
1720
1721
1722 static const LRAD_NAME_NUMBER listen_compare[] = {
1723         { "auth",       RAD_LISTEN_AUTH },
1724         { "acct",       RAD_LISTEN_ACCT },
1725         { "detail",     RAD_LISTEN_DETAIL },
1726         { NULL, 0 },
1727 };
1728
1729
1730 /*
1731  *      Generate a list of listeners.  Takes an input list of
1732  *      listeners, too, so we don't close sockets with waiting packets.
1733  */
1734 int listen_init(const char *filename, rad_listen_t **head)
1735 {
1736         int             rcode;
1737         CONF_SECTION    *cs;
1738         rad_listen_t    **last;
1739         rad_listen_t    *this;
1740         lrad_ipaddr_t   server_ipaddr;
1741         int             auth_port = 0;
1742
1743         /*
1744          *      We shouldn't be called with a pre-existing list.
1745          */
1746         rad_assert(head && (*head == NULL));
1747         
1748         if (start_time != 0) start_time = time(NULL);
1749
1750         last = head;
1751         server_ipaddr.af = AF_UNSPEC;
1752
1753         /*
1754          *      If the port is specified on the command-line,
1755          *      it over-rides the configuration file.
1756          */
1757         if (mainconfig.port >= 0) {
1758                 auth_port = mainconfig.port;
1759         } else {
1760                 rcode = cf_item_parse(mainconfig.config, "port",
1761                                       PW_TYPE_INTEGER, &auth_port,
1762                                       Stringify(PW_AUTH_UDP_PORT));
1763                 if (rcode < 0) return -1; /* error parsing it */
1764
1765                 if (rcode == 0)
1766                         radlog(L_INFO, "WARNING: The directive 'port' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1767         }
1768
1769         /*
1770          *      If the IP address was configured on the command-line,
1771          *      use that as the "bind_address"
1772          */
1773         if (mainconfig.myip.af != AF_UNSPEC) {
1774                 memcpy(&server_ipaddr, &mainconfig.myip,
1775                        sizeof(server_ipaddr));
1776                 goto bind_it;
1777         }
1778
1779         /*
1780          *      Else look for bind_address and/or listen sections.
1781          */
1782         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1783         rcode = cf_item_parse(mainconfig.config, "bind_address",
1784                               PW_TYPE_IPADDR,
1785                               &server_ipaddr.ipaddr.ip4addr, NULL);
1786         if (rcode < 0) return -1; /* error parsing it */
1787         
1788         if (rcode == 0) { /* successfully parsed IPv4 */
1789                 listen_socket_t *sock;
1790                 server_ipaddr.af = AF_INET;
1791
1792                 radlog(L_INFO, "WARNING: The directive 'bind_adress' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1793
1794         bind_it:
1795                 this = listen_alloc(RAD_LISTEN_AUTH);
1796                 sock = this->data;
1797
1798                 sock->ipaddr = server_ipaddr;
1799                 sock->port = auth_port;
1800                 
1801                 if (listen_bind(this) < 0) {
1802                         listen_free(&this);
1803                         listen_free(head);
1804                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1805                         return -1;
1806                 }
1807                 auth_port = sock->port; /* may have been updated in listen_bind */
1808                 *last = this;
1809                 last = &(this->next);
1810                 
1811                 /*
1812                  *      Open Accounting Socket.
1813                  *
1814                  *      If we haven't already gotten acct_port from
1815                  *      /etc/services, then make it auth_port + 1.
1816                  */
1817                 this = listen_alloc(RAD_LISTEN_ACCT);
1818                 sock = this->data;
1819                 
1820                 /*
1821                  *      Create the accounting socket.
1822                  *
1823                  *      The accounting port is always the
1824                  *      authentication port + 1
1825                  */
1826                 sock->ipaddr = server_ipaddr;
1827                 sock->port = auth_port + 1;
1828                 
1829                 if (listen_bind(this) < 0) {
1830                         listen_free(&this);
1831                         listen_free(head);
1832                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1833                         return -1;
1834                 }
1835
1836                 *last = this;
1837                 last = &(this->next);
1838
1839         } else if (mainconfig.port > 0) { /* no bind address, but a port */
1840                 radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1841                        mainconfig.port);
1842                 return -1;
1843         }
1844
1845         /*
1846          *      They specified an IP on the command-line, ignore
1847          *      all listen sections.
1848          */
1849         if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
1850
1851         /*
1852          *      Walk through the "listen" sections, if they exist.
1853          */
1854         for (cs = cf_subsection_find_next(mainconfig.config, NULL, "listen");
1855              cs != NULL;
1856              cs = cf_subsection_find_next(mainconfig.config, cs, "listen")) {
1857                 int             type;
1858                 char            *listen_type, *identity;
1859                 int             lineno = cf_section_lineno(cs);
1860
1861                 listen_type = identity = NULL;
1862                 
1863                 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1864                                       &listen_type, "");
1865                 if (rcode < 0) return -1;
1866                 if (rcode == 1) {
1867                         listen_free(head);
1868                         free(listen_type);
1869                         radlog(L_ERR, "%s[%d]: No type specified in listen section",
1870                                filename, lineno);
1871                         return -1;
1872                 }
1873
1874                 /*
1875                  *      See if there's an identity.
1876                  */
1877                 rcode = cf_item_parse(cs, "identity", PW_TYPE_STRING_PTR,
1878                                       &identity, NULL);
1879                 if (rcode < 0) {
1880                         listen_free(head);
1881                         free(identity);
1882                         return -1;
1883                 }
1884
1885                 type = lrad_str2int(listen_compare, listen_type,
1886                                     RAD_LISTEN_NONE);
1887                 free(listen_type);
1888                 if (type == RAD_LISTEN_NONE) {
1889                         listen_free(head);
1890                         radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
1891                                filename, lineno);
1892                         return -1;
1893                 }
1894
1895                 /*
1896                  *      Set up cross-type data.
1897                  */
1898                 this = listen_alloc(type);
1899                 this->identity = identity;
1900                 this->fd = -1;
1901                 
1902                 /*
1903                  *      Call per-type parser.
1904                  */
1905                 if (master_listen[type].parse(filename, lineno,
1906                                               cs, this) < 0) {
1907                         listen_free(&this);
1908                         listen_free(head);
1909                         return -1;
1910                 }
1911
1912                 *last = this;
1913                 last = &(this->next);   
1914         }
1915
1916         /*
1917          *      If we're proxying requests, open the proxy FD.
1918          *      Otherwise, don't do anything.
1919          */
1920  do_proxy:
1921         if (mainconfig.proxy_requests == TRUE) {
1922                 int             port = -1;
1923                 listen_socket_t *sock = NULL;
1924
1925                 /*
1926                  *      No sockets to receive packets, therefore
1927                  *      proxying is pointless.
1928                  */
1929                 if (!*head) return -1;
1930
1931                 /*
1932                  *      If we previously had proxy sockets, copy them
1933                  *      to the new config.
1934                  */
1935                 if (mainconfig.listen != NULL) {
1936                         rad_listen_t *old, *next, **tail;
1937
1938                         tail = &mainconfig.listen;
1939                         for (old = mainconfig.listen;
1940                              old != NULL;
1941                              old = next) {
1942                                 next = old->next;
1943
1944                                 if (old->type != RAD_LISTEN_PROXY) {
1945                                         tail = &((*tail)->next);
1946                                         continue;
1947                                 }
1948
1949                                 *last = old;
1950                                 *tail = next;
1951                                 old->next = NULL;
1952                                 last = &(old->next);
1953                         }
1954
1955                         goto done;
1956                 }
1957
1958                 /*
1959                  *      Find the first authentication port,
1960                  *      and use it
1961                  */
1962                 for (this = *head; this != NULL; this = this->next) {
1963                         if (this->type == RAD_LISTEN_AUTH) {
1964                                 sock = this->data;
1965                                 if (server_ipaddr.af == AF_UNSPEC) {
1966                                         server_ipaddr = sock->ipaddr;
1967                                 }
1968                                 port = sock->port + 2; /* skip acct port */
1969                                 break;
1970                         }
1971                 }
1972                 rad_assert(port > 0); /* must have found at least one entry! */
1973
1974                 /*
1975                  *      Address is still unspecified, use IPv4.
1976                  */
1977                 if (server_ipaddr.af == AF_UNSPEC) {
1978                         server_ipaddr.af = AF_INET;
1979                         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
1980                 }
1981
1982                 this = listen_alloc(RAD_LISTEN_PROXY);
1983                 sock = this->data;
1984
1985                 /*
1986                  *      Create the first proxy socket.
1987                  */
1988                 sock->ipaddr = server_ipaddr;
1989
1990                 /*
1991                  *      Try to find a proxy port (value doesn't matter)
1992                  */
1993                 for (sock->port = port;
1994                      sock->port < 64000;
1995                      sock->port++) {
1996                         if (listen_bind(this) == 0) {
1997                                 *last = this;
1998                                 last = &(this->next); /* just in case */
1999                                 break;
2000                         }
2001                 }
2002
2003                 if (sock->port >= 64000) {
2004                         listen_free(head);
2005                         listen_free(&this);
2006                         radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
2007                         return -1;
2008                 }
2009         }
2010
2011         /*
2012          *      Sanity check the configuration.
2013          */
2014         rcode = 0;
2015         for (this = *head; this != NULL; this = this->next) {
2016                 if ((this->type != RAD_LISTEN_PROXY) &&
2017                     !this->rl) {
2018                         /*
2019                          *      FIXME: Pass type to rl_init, so that
2020                          *      it knows how to deal with accounting
2021                          *      packets.  i.e. it caches them, but
2022                          *      doesn't bother trying to re-transmit.
2023                          */
2024                         this->rl = rl_init();
2025                         if (!this->rl) {
2026                                 rad_assert(0 == 1); /* FIXME: */
2027                         }
2028                 }
2029
2030                 if (((this->type == RAD_LISTEN_ACCT) &&
2031                      (rcode == RAD_LISTEN_DETAIL)) ||
2032                     ((this->type == RAD_LISTEN_DETAIL) &&
2033                      (rcode == RAD_LISTEN_ACCT))) {
2034                         rad_assert(0 == 1); /* FIXME: configuration error */
2035                 }
2036
2037                 if (rcode != 0) continue;
2038
2039                 if ((this->type == RAD_LISTEN_ACCT) ||
2040                     (this->type == RAD_LISTEN_DETAIL)) {
2041                         rcode = this->type;
2042                 }
2043         }
2044
2045  done:
2046         return 0;
2047 }
2048
2049 /*
2050  *      Free a linked list of listeners;
2051  */
2052 void listen_free(rad_listen_t **head)
2053 {
2054         rad_listen_t *this;
2055
2056         if (!head || !*head) return;
2057
2058         this = *head;
2059         while (this) {
2060                 rad_listen_t *next = this->next;
2061                 
2062                 free(this->identity);
2063
2064                 rl_deinit(this->rl);
2065
2066                 /*
2067                  *      Other code may have eaten the FD.
2068                  */
2069                 if (this->fd >= 0) close(this->fd);
2070
2071                 if (master_listen[this->type].free) {
2072                         master_listen[this->type].free(this);
2073                 }
2074                 free(this->data);
2075                 free(this);
2076                 
2077                 this = next;
2078         }
2079
2080         *head = NULL;
2081 }