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