Massive change to the server core to remove horrid code in
[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/autoconf.h>
28
29 #include <stdlib.h>
30 #include <string.h>
31
32 #ifdef HAVE_NETINET_IN_H
33 #include <netinet/in.h>
34 #endif
35
36 #ifdef HAVE_ARPA_INET_H
37 #include <arpa/inet.h>
38 #endif
39
40 #include <sys/resource.h>
41 #include <unistd.h>
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <netdb.h>
45
46 #ifdef HAVE_NET_IF_H
47 #include <net/if.h>
48 #endif
49
50 #ifdef HAVE_SYS_STAT_H
51 #include <sys/stat.h>
52 #endif
53
54 #ifdef WITH_UDPFROMTO
55 #include <freeradius-devel/udpfromto.h>
56 #endif
57
58 #include <fcntl.h>
59
60 #include <freeradius-devel/radiusd.h>
61 #include <freeradius-devel/rad_assert.h>
62
63 #include <freeradius-devel/radius_snmp.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_print_t      print;
84         rad_listen_encode_t     encode;
85         rad_listen_decode_t     decode;
86 } rad_listen_master_t;
87
88 typedef struct listen_socket_t {
89         /*
90          *      For normal sockets.
91          */
92         lrad_ipaddr_t   ipaddr;
93         int             port;
94         RADCLIENT_LIST  *clients;
95 } listen_socket_t;
96
97 typedef struct listen_detail_t {
98         const char      *detail;
99         VALUE_PAIR      *vps;
100         FILE            *fp;
101         int             state;
102         time_t          timestamp;
103         lrad_ipaddr_t   client_ip;
104         int             max_outstanding;
105         int             *outstanding;
106 } listen_detail_t;
107                                
108
109 /*
110  *      Find a per-socket client.
111  */
112 static RADCLIENT *client_listener_find(const rad_listen_t *listener,
113                                        const lrad_ipaddr_t *ipaddr)
114 {
115         const RADCLIENT_LIST *clients;
116
117         rad_assert(listener != NULL);
118         rad_assert(ipaddr != NULL);
119
120         rad_assert((listener->type == RAD_LISTEN_AUTH) ||
121                    (listener->type == RAD_LISTEN_ACCT));
122
123         clients = ((listen_socket_t *)listener->data)->clients;
124         if (!clients) clients = mainconfig.clients;
125
126         rad_assert(clients != NULL);
127         
128         return client_find(clients, ipaddr);
129 }
130
131 static int listen_bind(rad_listen_t *this);
132
133 /*
134  *      FIXME: have the detail reader use another config "exit when done",
135  *      so that it can be used as a one-off tool to update stuff.
136  */
137
138 /*
139  *      Process and reply to a server-status request.
140  *      Like rad_authenticate and rad_accounting this should
141  *      live in it's own file but it's so small we don't bother.
142  */
143 static int rad_status_server(REQUEST *request)
144 {
145         switch (request->listener->type) {
146         case RAD_LISTEN_AUTH:
147                 request->reply->code = PW_AUTHENTICATION_ACK;
148
149                 /*
150                  *      Commented out for now.
151                  */
152 #if 0
153  { 
154                 char            reply_msg[64];
155                 time_t          t;
156                 VALUE_PAIR      *vp;
157                 
158                 /*
159                  *      Reply with an ACK. We might want to add some more
160                  *      interesting reply attributes, such as server uptime.
161                  */
162                 t = request->timestamp - start_time;
163                 sprintf(reply_msg, "FreeRADIUS STUFF %d day%s, %02d:%02d",
164                         (int)(t / 86400), (t / 86400) == 1 ? "" : "s",
165                         (int)((t / 3600) % 24), (int)(t / 60) % 60);
166                 
167                 vp = pairmake("Reply-Message", reply_msg, T_OP_SET);
168                 pairadd(&request->reply->vps, vp); /* don't need to check if !vp */
169  }
170 #endif
171                 break;
172
173         case RAD_LISTEN_ACCT:
174                 request->reply->code = PW_ACCOUNTING_RESPONSE;
175                 break;
176
177         default:
178                 return 0;
179         }
180         
181
182         return 0;
183 }
184
185 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
186 {
187         size_t len;
188         listen_socket_t *sock = this->data;
189
190         if ((sock->ipaddr.af == AF_INET) &&
191             (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
192                 strcpy(buffer, "*");
193         } else {
194                 ip_ntoh(&sock->ipaddr, buffer, bufsize);
195         }
196
197         len = strlen(buffer);
198
199         return len + snprintf(buffer + len, bufsize - len, " port %d",
200                               sock->port);
201 }
202
203
204 /*
205  *      Parse an authentication or accounting socket.
206  */
207 static int common_socket_parse(const char *filename, int lineno,
208                              const CONF_SECTION *cs, rad_listen_t *this)
209 {
210         int             rcode;
211         int             listen_port;
212         lrad_ipaddr_t   ipaddr;
213         listen_socket_t *sock = this->data;
214         const char      *section_name = NULL;
215         CONF_SECTION    *client_cs;
216
217         /*
218          *      Try IPv4 first
219          */
220         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
221         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
222                               &ipaddr.ipaddr.ip4addr, NULL);
223         if (rcode < 0) return -1;
224         
225         if (rcode == 0) { /* successfully parsed IPv4 */
226                 ipaddr.af = AF_INET;
227                 
228         } else {        /* maybe IPv6? */
229                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
230                                       &ipaddr.ipaddr.ip6addr, NULL);
231                 if (rcode < 0) return -1;
232                 
233                 if (rcode == 1) {
234                         radlog(L_ERR, "%s[%d]: No address specified in listen section",
235                                filename, lineno);
236                         return -1;
237                 }
238                 ipaddr.af = AF_INET6;
239         }
240         
241         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
242                               &listen_port, "0");
243         if (rcode < 0) return -1;
244         
245         sock->ipaddr = ipaddr;
246         sock->port = listen_port;
247
248         /*
249          *      And bind it to the port.
250          */
251         if (listen_bind(this) < 0) {
252                 char buffer[128];
253                 radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s port %d",
254                        filename, cf_section_lineno(cs),
255                        ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
256                        sock->port);
257                 return -1;
258         }
259
260         /*
261          *      If we can bind to interfaces, do so,
262          *      else don't.
263          */
264         if (cf_pair_find(cs, "interface")) {
265 #ifndef SO_BINDTODEVICE
266                 radlog(L_CONS|L_ERR, "%s[%d]: System does not support binding to interfaces, delete this line from the configuration file.",
267                        filename, cf_section_lineno(cs));
268                 return -1;
269 #else
270                 const char *value;
271                 const CONF_PAIR *cp = cf_pair_find(cs, "interface");
272                 struct ifreq ifreq;
273
274                 rad_assert(cp != NULL);
275                 value = cf_pair_value(cp);
276                 rad_assert(value != NULL);
277                 
278                 strcpy(ifreq.ifr_name, value);
279         
280                 if (setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
281                                (char *)&ifreq, sizeof(ifreq)) < 0) {
282                         radlog(L_CONS|L_ERR, "%s[%d]: Failed binding to interface %s: %s",
283                                filename, cf_section_lineno(cs),
284                                value, strerror(errno));
285                         return -1;
286                 } /* else it worked. */
287 #endif
288         }
289
290         /*
291          *      Look for the name of a section that holds a list
292          *      of clients.
293          */
294         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
295                               &section_name, NULL);
296         if (rcode < 0) return -1; /* bad string */
297         if (rcode > 0) return 0; /* non-existent is OK. */
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                        filename, cf_section_lineno(cs), section_name);
304                 return -1;
305         }
306
307         sock->clients = clients_parse_section(filename, client_cs);
308         if (!sock->clients) {
309                 return -1;
310         }
311
312         return 0;
313 }
314
315 /*
316  *      Send an authentication response packet
317  */
318 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
319 {
320         rad_assert(request->listener == listener);
321         rad_assert(listener->send == auth_socket_send);
322
323         return rad_send(request->reply, request->packet, request->secret);
324 }
325
326
327 /*
328  *      Send an accounting response packet (or not)
329  */
330 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
331 {
332         rad_assert(request->listener == listener);
333         rad_assert(listener->send == acct_socket_send);
334
335         /*
336          *      Accounting reject's are silently dropped.
337          *
338          *      We do it here to avoid polluting the rest of the
339          *      code with this knowledge
340          */
341         if (request->reply->code == 0) return 0;
342
343         return rad_send(request->reply, request->packet, request->secret);
344 }
345
346
347 /*
348  *      Send a packet to a home server.
349  *
350  *      FIXME: have different code for proxy auth & acct!
351  */
352 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
353 {
354         listen_socket_t *sock = listener->data;
355
356         rad_assert(request->proxy_listener == listener);
357         rad_assert(listener->send == proxy_socket_send);
358
359         request->proxy->src_ipaddr = sock->ipaddr;
360         request->proxy->src_port = sock->port;
361
362         return rad_send(request->proxy, request->packet,
363                         request->home_server->secret);
364 }
365
366
367 /*
368  *      Check if an incoming request is "ok"
369  *
370  *      It takes packets, not requests.  It sees if the packet looks
371  *      OK.  If so, it does a number of sanity checks on it.
372   */
373 static int auth_socket_recv(rad_listen_t *listener,
374                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
375 {
376         RADIUS_PACKET   *packet;
377         RAD_REQUEST_FUNP fun = NULL;
378         char            buffer[128];
379         RADCLIENT       *client;
380
381         packet = rad_recv(listener->fd);
382         if (!packet) {
383                 radlog(L_ERR, "%s", librad_errstr);
384                 return 0;
385         }
386
387         RAD_SNMP_TYPE_INC(listener, total_requests); /* FIXME: auth specific */
388
389         if ((client = client_listener_find(listener,
390                                            &packet->src_ipaddr)) == NULL) {
391                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
392                 
393                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
394                        inet_ntop(packet->src_ipaddr.af,
395                                  &packet->src_ipaddr.ipaddr,
396                                  buffer, sizeof(buffer)),
397                        packet->src_port);
398                 rad_free(&packet);
399                 return 0;
400         }
401
402         /*
403          *      Some sanity checks, based on the packet code.
404          */
405         switch(packet->code) {
406         case PW_AUTHENTICATION_REQUEST:
407                 fun = rad_authenticate;
408                 break;
409                 
410         case PW_STATUS_SERVER:
411                 if (!mainconfig.status_server) {
412                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
413                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
414                         rad_free(&packet);
415                         return 0;
416                 }
417                 fun = rad_status_server;
418                 break;
419
420         default:
421                 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
422                 
423                 radlog(L_ERR, "Invalid packet code %d sent to authentication port from client %s port %d "
424                        "- ID %d : IGNORED",
425                        packet->code, client->shortname,
426                        packet->src_port, packet->id);
427                 rad_free(&packet);
428                 return 0;
429                 break;
430         } /* switch over packet types */
431         
432         if (!received_request(listener, packet, prequest, client)) {
433                 rad_free(&packet);
434                 return 0;
435         }
436
437         *pfun = fun;
438         return 1;
439 }
440
441
442 /*
443  *      Receive packets from an accounting socket
444  */
445 static int acct_socket_recv(rad_listen_t *listener,
446         RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
447 {
448         RADIUS_PACKET   *packet;
449         RAD_REQUEST_FUNP fun = NULL;
450         char            buffer[128];
451         RADCLIENT       *client;
452         
453         packet = rad_recv(listener->fd);
454         if (!packet) {
455                 radlog(L_ERR, "%s", librad_errstr);
456                 return 0;
457         }
458         
459         RAD_SNMP_TYPE_INC(listener, total_requests); /* FIXME: acct-specific */
460
461         if ((client = client_listener_find(listener,
462                                            &packet->src_ipaddr)) == NULL) {
463                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
464                 
465                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
466                        inet_ntop(packet->src_ipaddr.af,
467                                  &packet->src_ipaddr.ipaddr,
468                                  buffer, sizeof(buffer)),
469                        packet->src_port);
470                 rad_free(&packet);
471                 return 0;
472         }
473
474         switch(packet->code) {
475         case PW_ACCOUNTING_REQUEST:
476                 fun = rad_accounting;
477                 break;
478                 
479         case PW_STATUS_SERVER:
480                 if (!mainconfig.status_server) {
481                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
482                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
483                         rad_free(&packet);
484                         return 0;
485                 }
486                 fun = rad_status_server;
487                 break;
488
489         default:
490                 /*
491                  *      FIXME: Update MIB for packet types?
492                  */
493                 radlog(L_ERR, "Invalid packet code %d sent to a accounting port "
494                        "from client %s port %d - ID %d : IGNORED",
495                        packet->code, client->shortname,
496                        packet->src_port, packet->id);
497                 rad_free(&packet);
498                 return 0;
499         }
500
501         /*
502          *      FIXME: Accounting duplicates should be handled
503          *      differently than authentication duplicates.
504          */
505         if (!received_request(listener, packet, prequest, client)) {
506                 rad_free(&packet);
507                 return 0;
508         }
509
510         *pfun = fun;
511         return 1;
512 }
513
514
515 /*
516  *      Recieve packets from a proxy socket.
517  */
518 static int proxy_socket_recv(rad_listen_t *listener,
519                               RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
520 {
521         REQUEST         *request;
522         RADIUS_PACKET   *packet;
523         RAD_REQUEST_FUNP fun = NULL;
524         char            buffer[128];
525         
526         packet = rad_recv(listener->fd);
527         if (!packet) {
528                 radlog(L_ERR, "%s", librad_errstr);
529                 return 0;
530         }
531
532         /*
533          *      FIXME: Client MIB updates?
534          */
535         switch(packet->code) {
536         case PW_AUTHENTICATION_ACK:
537         case PW_ACCESS_CHALLENGE:
538         case PW_AUTHENTICATION_REJECT:
539                 fun = rad_authenticate;
540                 break;
541                 
542         case PW_ACCOUNTING_RESPONSE:
543                 fun = rad_accounting;
544                 break;
545                 
546         default:
547                 /*
548                  *      FIXME: Update MIB for packet types?
549                  */
550                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
551                        "from home server %s port %d - ID %d : IGNORED",
552                        packet->code,
553                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
554                        packet->src_port, packet->id);
555                 rad_free(&packet);
556                 return 0;
557         }
558
559         request = received_proxy_response(packet);
560         if (!request) {
561                 return 0;
562         }
563
564         rad_assert(fun != NULL);
565         *pfun = fun;
566         *prequest = request;
567
568         return 1;
569 }
570
571
572 static int client_socket_encode(rad_listen_t *listener, REQUEST *request)
573 {
574         if (!request->reply->code) return 0;
575
576         rad_encode(request->reply, request->packet, request->secret);
577         rad_sign(request->reply, request->packet, request->secret);
578
579         return 0;
580 }
581
582
583 static int client_socket_decode(rad_listen_t *listener, REQUEST *request)
584 {
585         if (rad_verify(request->packet, NULL, request->secret) < 0) {
586                 return -1;
587         }
588
589         return rad_decode(request->packet, NULL, request->secret);
590 }
591
592 static int proxy_socket_encode(rad_listen_t *listener, REQUEST *request)
593 {
594         rad_encode(request->proxy, NULL, request->home_server->secret);
595         rad_sign(request->proxy, NULL, request->home_server->secret);
596
597         return 0;
598 }
599
600
601 static int proxy_socket_decode(rad_listen_t *listener, REQUEST *request)
602 {
603         if (rad_verify(request->proxy_reply, request->proxy,
604                        request->home_server->secret) < 0) {
605                 return -1;
606         }
607
608         return rad_decode(request->proxy_reply, request->proxy,
609                            request->home_server->secret);
610 }
611
612
613 #define STATE_UNOPENED  (0)
614 #define STATE_UNLOCKED  (1)
615 #define STATE_HEADER    (2)
616 #define STATE_READING   (3)
617 #define STATE_DONE      (4)
618 #define STATE_WAITING   (5)
619
620 /*
621  *      If we're limiting outstanding packets, then mark the response
622  *      as being sent.
623  */
624 static int detail_send(rad_listen_t *listener, REQUEST *request)
625 {
626         listen_detail_t *data = listener->data;
627
628         rad_assert(request->listener == listener);
629         rad_assert(listener->send == detail_send);
630
631         if (request->simul_max >= 0) {
632                 rad_assert(data->outstanding != NULL);
633                 rad_assert(request->simul_max < data->max_outstanding);
634
635                 data->outstanding[request->simul_max] = 0;
636         }
637
638         return 0;
639 }
640
641
642 /*
643  *      Open the detail file..
644  *
645  *      FIXME: create it, if it's not already there, so that the main
646  *      server select() will wake us up if there's anything to read.
647  */
648 static int detail_open(rad_listen_t *this)
649 {
650         struct stat st;
651         char buffer[2048];
652         listen_detail_t *data = this->data;
653
654         rad_assert(data->state == STATE_UNOPENED);
655         snprintf(buffer, sizeof(buffer), "%s.work", data->detail);
656         
657         /*
658          *      FIXME: Have "one-shot" configuration, where it
659          *      will read the detail file, and exit once it's
660          *      done.
661          *
662          *      FIXME: Try harder to open the detail file.
663          *      Maybe sleep for X usecs if it doesn't exist?
664          */
665
666         /*
667          *      Open detail.work first, so we don't lose
668          *      accounting packets.  It's probably better to
669          *      duplicate them than to lose them.
670          *
671          *      Note that we're not writing to the file, but
672          *      we've got to open it for writing in order to
673          *      establish the lock, to prevent rlm_detail from
674          *      writing to it.
675          */
676         this->fd = open(buffer, O_RDWR);
677         if (this->fd < 0) {
678                 /*
679                  *      Try reading the detail file.  If it
680                  *      doesn't exist, we can't do anything.
681                  *
682                  *      Doing the stat will tell us if the file
683                  *      exists, even if we don't have permissions
684                  *      to read it.
685                  */
686                 if (stat(data->detail, &st) < 0) {
687                         return 0;
688                 }
689                 
690                 /*
691                  *      Open it BEFORE we rename it, just to
692                  *      be safe...
693                  */
694                 this->fd = open(data->detail, O_RDWR);
695                 if (this->fd < 0) {
696                         radlog(L_ERR, "Failed to open %s: %s",
697                                data->detail, strerror(errno));
698                         return 0;
699                 }
700                 
701                 /*
702                  *      Rename detail to detail.work
703                  */
704                 if (rename(data->detail, buffer) < 0) {
705                         close(this->fd);
706                         this->fd = -1;
707                         return 0;
708                 }
709         } /* else detail.work existed, and we opened it */
710         
711         rad_assert(data->vps == NULL);
712         
713         rad_assert(data->fp == NULL);
714         data->fp = fdopen(this->fd, "r");
715         if (!data->fp) {
716                 radlog(L_ERR, "Failed to re-open %s: %s",
717                        data->detail, strerror(errno));
718                 return 0;
719         }
720
721         data->state = STATE_UNLOCKED;
722
723         data->client_ip.af = AF_UNSPEC;
724         data->timestamp = 0;
725         
726         return 1;
727 }
728
729 /*
730  *      This is a bad hack, just so complaints have meaningful text.
731  */
732 static const RADCLIENT detail_client = {
733         {               /* ipaddr */
734                 AF_INET,
735                 {{ INADDR_NONE }}
736         },
737         32,
738         "<detail-file>",
739         "secret",
740         "UNKNOWN-CLIENT",
741         "other",
742         "",
743         "",
744         -1
745 };
746
747 static int detail_recv(rad_listen_t *listener,
748                        RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
749 {
750         int             free_slot = -1;
751         char            key[256], value[1024];
752         VALUE_PAIR      *vp, **tail;
753         RADIUS_PACKET   *packet;
754         char            buffer[2048];
755         listen_detail_t *data = listener->data;
756
757         if (data->state == STATE_UNOPENED) {
758                 rad_assert(listener->fd < 0);
759                 if (!detail_open(listener)) return 0;
760         }
761         rad_assert(listener->fd >= 0);
762
763         /*
764          *      Try to lock fd.  If we can't, return.  If we can,
765          *      continue.  This means that the server doesn't block
766          *      while waiting for the lock to open...
767          */
768         if (data->state == STATE_UNLOCKED) {
769                 /*
770                  *      Note that we do NOT block waiting for the
771                  *      lock.  We've re-named the file above, so we've
772                  *      already guaranteed that any *new* detail
773                  *      writer will not be opening this file.  The
774                  *      only purpose of the lock is to catch a race
775                  *      condition where the execution "ping-pongs"
776                  *      between radiusd & radrelay.
777                  */
778                 if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
779                         return 0;
780                 }
781                 /*
782                  *      Look for the header
783                  */
784                 data->state = STATE_HEADER;
785         }
786
787         /*
788          *      Catch an out of memory condition which will most likely
789          *      never be met.
790          */
791         if (data->state == STATE_DONE) goto alloc_packet;
792
793         /*
794          *      If we're in another state, then it means that we read
795          *      a partial packet, which is bad.
796          */
797         rad_assert(data->state == STATE_HEADER);
798         rad_assert(data->vps == NULL);
799
800         /*
801          *      We read the last packet, and returned it for
802          *      processing.  We later come back here to shut
803          *      everything down, and unlink the file.
804          */
805         if (feof(data->fp)) {
806                 rad_assert(data->state == STATE_HEADER);
807
808                 /*
809                  *      Don't unlink the file until we've received
810                  *      all of the responses.
811                  */
812                 if (data->max_outstanding > 0) {
813                         int i;
814
815                         for (i = 0; i < data->max_outstanding; i++) {
816                                 /*
817                                  *      FIXME: close the file?
818                                  */
819                                 if (data->outstanding[i]) {
820                                         data->state = STATE_WAITING;
821                                         return 0;
822                                 }
823                         }
824                 }
825
826         cleanup:
827                 rad_assert(data->vps == NULL);
828
829                 snprintf(buffer, sizeof(buffer), "%s.work", data->detail);
830                 unlink(buffer);
831                 fclose(data->fp); /* closes listener->fd */
832                 data->fp = NULL;
833                 listener->fd = -1;
834                 data->state = STATE_UNOPENED;
835
836                 /*
837                  *      Try to open "detail" again.  If we're on a
838                  *      busy RADIUS server, odds are that it will
839                  *      now exist.
840                  */
841                 detail_open(listener);
842                 return 0;
843         }
844
845         tail = &data->vps;
846
847         /*
848          *      Fill the buffer...
849          */
850         while (fgets(buffer, sizeof(buffer), data->fp)) {
851                 /*
852                  *      No CR, die.
853                  */
854                 if (!strchr(buffer, '\n')) {
855                         pairfree(&data->vps);
856                         goto cleanup;
857                 }
858
859                 /*
860                  *      We've read a header, possibly packet contents,
861                  *      and are now at the end of the packet.
862                  */
863                 if ((data->state == STATE_READING) &&
864                     (buffer[0] == '\n')) {
865                         data->state = STATE_DONE;
866                         break;
867                 }
868
869                 /*
870                  *      Look for date/time header, and read VP's if
871                  *      found.  If not, keep reading lines until we
872                  *      find one.
873                  */
874                 if (data->state == STATE_HEADER) {
875                         int y;
876                         
877                         if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
878                                 data->state = STATE_READING;
879                         }
880                         continue;
881                 }
882
883                 /*
884                  *      We have a full "attribute = value" line.
885                  *      If it doesn't look reasonable, skip it.
886                  */
887                 if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
888                         continue;
889                 }
890
891                 /*
892                  *      Skip non-protocol attributes.
893                  */
894                 if (!strcasecmp(key, "Request-Authenticator")) continue;
895
896                 /*
897                  *      Set the original client IP address, based on
898                  *      what's in the detail file.
899                  *
900                  *      Hmm... we don't set the server IP address.
901                  *      or port.  Oh well.
902                  */
903                 if (!strcasecmp(key, "Client-IP-Address")) {
904                         data->client_ip.af = AF_INET;
905                         ip_hton(value, AF_INET, &data->client_ip);
906                         continue;
907                 }
908
909                 /*
910                  *      The original time at which we received the
911                  *      packet.  We need this to properly calculate
912                  *      Acct-Delay-Time.
913                  */
914                 if (!strcasecmp(key, "Timestamp")) {
915                         data->timestamp = atoi(value);
916                         continue;
917                 }
918
919                 /*
920                  *      Read one VP.
921                  *
922                  *      FIXME: do we want to check for non-protocol
923                  *      attributes like radsqlrelay does?
924                  */
925                 vp = NULL;
926                 if ((userparse(buffer, &vp) > 0) &&
927                     (vp != NULL)) {
928                         *tail = vp;
929                         tail = &(vp->next);
930                 }               
931         }
932
933         /*
934          *      We got to EOF,  If we're in STATE_HEADER, it's OK.
935          *      Otherwise it's a problem.  In any case, nuke the file
936          *      and start over from scratch,
937          */
938         if (feof(data->fp)) {
939                 goto cleanup;
940         }
941
942         /*
943          *      FIXME: Do load management.
944          */
945
946         /*
947          *      If we're not done, then there's a problem.  The checks
948          *      above for EOF
949          */
950         rad_assert(data->state == STATE_DONE);
951
952         /*
953          *      The packet we read was empty, re-set the state to look
954          *      for a header, and don't return anything.
955          */
956         if (!data->vps) {
957                 data->state = STATE_HEADER;
958                 return 0;
959         }
960
961         /*
962          *      Allocate the packet.  If we fail, it's a serious
963          *      problem.
964          */
965  alloc_packet:
966         /*
967          *      If we keep track of the outstanding requests, do so
968          *      here.  Note that to minimize potential work, we do
969          *      so only once the file is opened & locked.
970          */
971         if (data->max_outstanding) {
972                 int i;
973
974                 for (i = 0; i < data->max_outstanding; i++) {
975                         if (!data->outstanding[i]) {
976                                 free_slot = i;
977                                 break;
978                         }
979                 }
980
981                 /*
982                  *      All of the slots are full.  Put the LF back,
983                  *      so select will say that data is ready, and set
984                  *      the state back to reading.  Then, return so
985                  *      that we don't overload the server.
986                  */
987                 if (free_slot < 0) {
988                         ungetc('\n', data->fp);
989                         data->state = STATE_READING;
990                         return 0;
991                 }
992         }
993
994         packet = rad_alloc(1);
995         if (!packet) {
996                 return 0;       /* maybe memory will magically free up... */
997         }
998
999         memset(packet, 0, sizeof(*packet));
1000         packet->sockfd = -1;
1001         packet->src_ipaddr.af = AF_INET;
1002         packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1003         packet->code = PW_ACCOUNTING_REQUEST;
1004         packet->timestamp = time(NULL);
1005
1006         /*
1007          *      Look for Acct-Delay-Time, and update
1008          *      based on Acct-Delay-Time += (time(NULL) - timestamp)
1009          */
1010         vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
1011         if (!vp) {
1012                 vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1013                 rad_assert(vp != NULL);
1014         }
1015         if (data->timestamp != 0) {
1016                 vp->lvalue += time(NULL) - data->timestamp;
1017         }
1018
1019         /*
1020          *      Remember where it came from, so that we don't
1021          *      proxy it to the place it came from...
1022          */
1023         if (data->client_ip.af != AF_UNSPEC) {
1024                 packet->src_ipaddr = data->client_ip;
1025         }
1026
1027         vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);
1028         if (vp) {
1029                 packet->src_ipaddr.af = AF_INET;
1030                 packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
1031         } else {
1032                 vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);
1033                 if (vp) {
1034                         packet->src_ipaddr.af = AF_INET6;
1035                         memcpy(&packet->src_ipaddr.ipaddr.ip6addr,
1036                                &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1037                 }
1038         }
1039
1040         vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);
1041         if (vp) {
1042                 packet->dst_ipaddr.af = AF_INET;
1043                 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
1044         } else {
1045                 vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);
1046                 if (vp) {
1047                         packet->dst_ipaddr.af = AF_INET6;
1048                         memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,
1049                                &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1050                 }
1051         }
1052
1053         /*
1054          *      We've got to give SOME value for Id & ports, so that
1055          *      the packets can be added to the request queue.
1056          *      However, we don't want to keep track of used/unused
1057          *      id's and ports, as that's a lot of work.  This hack
1058          *      ensures that (if we have real random numbers), that
1059          *      there will be a collision on every 2^(16+15+15+24 - 1)
1060          *      packets, on average.  That means we can read 2^37
1061          *      packets before having a collision, which means it's
1062          *      effectively impossible.
1063          */
1064         packet->id = lrad_rand() & 0xffff;
1065         packet->src_port = 1024 + (lrad_rand() & 0x7fff);
1066         packet->dst_port = 1024 + (lrad_rand() & 0x7fff);
1067
1068         packet->dst_ipaddr.af = AF_INET;
1069         packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
1070
1071         packet->vps = data->vps;
1072
1073         /*
1074          *      Re-set the state.
1075          */
1076         data->vps = NULL;
1077         data->state = STATE_HEADER;
1078
1079         /*
1080          *      Keep track of free slots, as a hack, in an otherwise
1081          *      unused 'int'
1082          */
1083         (*prequest)->simul_max = free_slot;
1084         data->outstanding[free_slot] = 1;
1085
1086         *pfun = rad_accounting;
1087
1088         if (debug_flag) {
1089                 printf("detail_recv: Read packet from %s\n", data->detail);
1090                 for (vp = packet->vps; vp; vp = vp->next) {
1091                         putchar('\t');
1092                         vp_print(stdout, vp);
1093                         putchar('\n');
1094                 }
1095         }
1096
1097         /*
1098          *      FIXME: many of these checks may not be necessary when
1099          *      reading from the detail file.
1100          */
1101         if (!received_request(listener, packet, prequest, &detail_client)) {
1102                 rad_free(&packet);
1103                 return 0;
1104         }
1105
1106         return 1;
1107 }
1108
1109
1110 /*
1111  *      Free detail-specific stuff.
1112  */
1113 static void detail_free(rad_listen_t *this)
1114 {
1115         listen_detail_t *data = this->data;
1116
1117         free(data->detail);
1118         pairfree(&data->vps);
1119         free(data->outstanding);
1120
1121         if (data->fp != NULL) fclose(data->fp);
1122 }
1123
1124
1125 static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
1126 {
1127         return snprintf(buffer, bufsize, "%s",
1128                         ((listen_detail_t *)(this->data))->detail);
1129 }
1130
1131 static int detail_encode(rad_listen_t *this, REQUEST *request)
1132 {
1133         /*
1134          *      We never encode responses "sent to" the detail file.
1135          */
1136         return 0;
1137 }
1138
1139 static int detail_decode(rad_listen_t *this, REQUEST *request)
1140 {
1141         /*
1142          *      We never decode responses read from the detail file.
1143          */
1144         return 0;
1145 }
1146
1147
1148 static const CONF_PARSER detail_config[] = {
1149         { "detail",   PW_TYPE_STRING_PTR,
1150           offsetof(listen_detail_t, detail), NULL,  NULL },
1151         { "max_outstanding",  PW_TYPE_INTEGER,
1152            offsetof(listen_detail_t, max_outstanding), NULL, "100" },
1153
1154         { NULL, -1, 0, NULL, NULL }             /* end the list */
1155 };
1156
1157
1158 /*
1159  *      Parse a detail section.
1160  */
1161 static int detail_parse(const char *filename, int lineno,
1162                         const CONF_SECTION *cs, rad_listen_t *this)
1163 {
1164         int             rcode;
1165         listen_detail_t *data;
1166
1167         data = this->data;
1168
1169         rcode = cf_section_parse(cs, data, detail_config);
1170         if (rcode < 0) {
1171                 radlog(L_ERR, "%s[%d]: Failed parsing listen section",
1172                        filename, lineno);
1173                 return -1;
1174         }
1175
1176         if (!data->detail) {
1177                 radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
1178                        filename, lineno);
1179                 return -1;
1180         }
1181         
1182         data->vps = NULL;
1183         data->fp = NULL;
1184         data->state = STATE_UNOPENED;
1185
1186         if (data->max_outstanding > 32768) data->max_outstanding = 32768;
1187
1188         if (data->max_outstanding > 0) {
1189                 data->outstanding = rad_malloc(sizeof(int) * data->max_outstanding);
1190         }
1191         
1192         detail_open(this);
1193
1194         return 0;
1195 }
1196
1197 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1198         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
1199
1200         /* authentication */
1201         { common_socket_parse, NULL,
1202           auth_socket_recv, auth_socket_send,
1203           socket_print, client_socket_encode, client_socket_decode },
1204
1205         /* accounting */
1206         { common_socket_parse, NULL,
1207           acct_socket_recv, acct_socket_send,
1208           socket_print, client_socket_encode, client_socket_decode},
1209
1210         /* proxying */
1211         { NULL, NULL,
1212           proxy_socket_recv, proxy_socket_send,
1213           socket_print, proxy_socket_encode, proxy_socket_decode },
1214
1215         /* detail */
1216         { detail_parse, detail_free,
1217           detail_recv, detail_send,
1218           detail_print, detail_encode, detail_decode }
1219 };
1220
1221
1222
1223 /*
1224  *      Binds a listener to a socket.
1225  */
1226 static int listen_bind(rad_listen_t *this)
1227 {
1228         rad_listen_t    **last;
1229         listen_socket_t *sock = this->data;
1230
1231         /*
1232          *      If the port is zero, then it means the appropriate
1233          *      thing from /etc/services.
1234          */
1235         if (sock->port == 0) {
1236                 struct servent  *svp;
1237
1238                 switch (this->type) {
1239                 case RAD_LISTEN_AUTH:
1240                         svp = getservbyname ("radius", "udp");
1241                         if (svp != NULL) {
1242                                 sock->port = ntohs(svp->s_port);
1243                         } else {
1244                                 sock->port = PW_AUTH_UDP_PORT;
1245                         }
1246                         break;
1247
1248                 case RAD_LISTEN_ACCT:
1249                         svp = getservbyname ("radacct", "udp");
1250                         if (svp != NULL) {
1251                                 sock->port = ntohs(svp->s_port);
1252                         } else {
1253                                 sock->port = PW_ACCT_UDP_PORT;
1254                         }
1255                         break;
1256
1257                 default:
1258                         radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
1259                         return -1;
1260                 }
1261         }
1262
1263         /*
1264          *      Find it in the old list, AFTER updating the port.  If
1265          *      it's there, use that, rather than creating a new
1266          *      socket.  This allows HUP's to re-use the old sockets,
1267          *      which means that packets waiting in the socket queue
1268          *      don't get lost.
1269          */
1270         for (last = &mainconfig.listen;
1271              *last != NULL;
1272              last = &((*last)->next)) {
1273                 if ((this->type == (*last)->type) &&
1274                     (sock->port == ((listen_socket_t *)((*last)->data))->port) &&
1275                     (sock->ipaddr.af == ((listen_socket_t *)((*last)->data))->ipaddr.af)) {
1276                         int equal;
1277
1278                         if (sock->ipaddr.af == AF_INET) {
1279                                 equal = (sock->ipaddr.ipaddr.ip4addr.s_addr == ((listen_socket_t *)((*last)->data))->ipaddr.ipaddr.ip4addr.s_addr);
1280                         } else if (sock->ipaddr.af == AF_INET6) {
1281                                 equal = IN6_ARE_ADDR_EQUAL(&(sock->ipaddr.ipaddr.ip6addr), &(((listen_socket_t *)((*last)->data))->ipaddr.ipaddr.ip6addr));
1282                         } else {
1283                                 equal = 0;
1284                         }
1285                         
1286                         if (equal) {
1287                                 this->fd = (*last)->fd;
1288                                 (*last)->fd = -1;
1289                                 return 0;
1290                         }
1291                 }
1292         }
1293
1294         this->fd = lrad_socket(&sock->ipaddr, sock->port);
1295         if (this->fd < 0) {
1296                 radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
1297                        librad_errstr);
1298                 return -1;
1299         }
1300
1301 #if 0
1302 #ifdef O_NONBLOCK
1303         if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0)  { 
1304                 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno)); 
1305                 return -1;
1306         }
1307
1308         flags |= O_NONBLOCK; 
1309         if( fcntl(this->fd, F_SETFL, flags) < 0) { 
1310                 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno)); 
1311                 return -1;
1312         }
1313 #endif
1314 #endif
1315
1316         return 0;
1317 }
1318
1319
1320 /*
1321  *      Allocate & initialize a new listener.
1322  */
1323 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1324 {
1325         rad_listen_t *this;
1326
1327         this = rad_malloc(sizeof(*this));
1328         memset(this, 0, sizeof(*this));
1329
1330         this->type = type;
1331         this->recv = master_listen[this->type].recv;
1332         this->send = master_listen[this->type].send;
1333         this->print = master_listen[this->type].print;
1334         this->encode = master_listen[this->type].encode;
1335         this->decode = master_listen[this->type].decode;
1336
1337         switch (type) {
1338         case RAD_LISTEN_AUTH:
1339         case RAD_LISTEN_ACCT:
1340         case RAD_LISTEN_PROXY:
1341                 this->data = rad_malloc(sizeof(listen_socket_t));
1342                 memset(this->data, 0, sizeof(listen_socket_t));
1343                 break;
1344
1345         case RAD_LISTEN_DETAIL:
1346                 this->data = rad_malloc(sizeof(listen_detail_t));
1347                 memset(this->data, 0, sizeof(listen_detail_t));
1348                 
1349         default:
1350                 break;
1351         }
1352
1353         return this;
1354 }
1355
1356
1357 /*
1358  *      Externally visible function for creating a new proxy LISTENER.
1359  *
1360  *      For now, don't take ipaddr or port.
1361  *
1362  *      Not thread-safe, but all calls to it are protected by the
1363  *      proxy mutex in request_list.c
1364  */
1365 rad_listen_t *proxy_new_listener()
1366 {
1367         int last_proxy_port, port;
1368         rad_listen_t *this, *tmp, **last;
1369         listen_socket_t *sock, *old;
1370
1371         this = listen_alloc(RAD_LISTEN_PROXY);
1372
1373         /*
1374          *      Find an existing proxy socket to copy.
1375          *
1376          *      FIXME: Make it per-realm, or per-home server!
1377          */
1378         last_proxy_port = 0;
1379         old = NULL;
1380         last = &mainconfig.listen;
1381         for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1382                 if (tmp->type == RAD_LISTEN_PROXY) {
1383                         sock = tmp->data;
1384                         if (sock->port > last_proxy_port) {
1385                                 last_proxy_port = sock->port + 1;
1386                         }
1387                         if (!old) old = sock;
1388                 }
1389
1390                 last = &(tmp->next);
1391         }
1392
1393         if (!old) return NULL;  /* This is a serious error. */
1394
1395         /*
1396          *      FIXME: find a new IP address to listen on?
1397          */
1398         sock = this->data;
1399         memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1400
1401         /*
1402          *      Keep going until we find an unused port.
1403          */
1404         for (port = last_proxy_port; port < 64000; port++) {
1405                 sock->port = port;
1406                 if (listen_bind(this) == 0) {
1407                         /*
1408                          *      Add the new listener to the list of
1409                          *      listeners.
1410                          */
1411                         *last = this;
1412                         return this;
1413                 }
1414         }
1415
1416         return NULL;
1417 }
1418
1419
1420 static const LRAD_NAME_NUMBER listen_compare[] = {
1421         { "auth",       RAD_LISTEN_AUTH },
1422         { "acct",       RAD_LISTEN_ACCT },
1423         { "detail",     RAD_LISTEN_DETAIL },
1424         { NULL, 0 },
1425 };
1426
1427
1428 /*
1429  *      Generate a list of listeners.  Takes an input list of
1430  *      listeners, too, so we don't close sockets with waiting packets.
1431  */
1432 int listen_init(const char *filename, rad_listen_t **head)
1433 {
1434         int             rcode;
1435         CONF_SECTION    *cs;
1436         rad_listen_t    **last;
1437         rad_listen_t    *this;
1438         lrad_ipaddr_t   server_ipaddr;
1439         int             auth_port = 0;
1440
1441         /*
1442          *      We shouldn't be called with a pre-existing list.
1443          */
1444         rad_assert(head && (*head == NULL));
1445         
1446         if (start_time != 0) start_time = time(NULL);
1447
1448         last = head;
1449         server_ipaddr.af = AF_UNSPEC;
1450
1451         /*
1452          *      If the port is specified on the command-line,
1453          *      it over-rides the configuration file.
1454          */
1455         if (mainconfig.port >= 0) {
1456                 auth_port = mainconfig.port;
1457         } else {
1458                 rcode = cf_item_parse(mainconfig.config, "port",
1459                                       PW_TYPE_INTEGER, &auth_port,
1460                                       Stringify(PW_AUTH_UDP_PORT));
1461                 if (rcode < 0) return -1; /* error parsing it */
1462
1463                 if (rcode == 0)
1464                         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'.");
1465         }
1466
1467         /*
1468          *      If the IP address was configured on the command-line,
1469          *      use that as the "bind_address"
1470          */
1471         if (mainconfig.myip.af != AF_UNSPEC) {
1472                 memcpy(&server_ipaddr, &mainconfig.myip,
1473                        sizeof(server_ipaddr));
1474                 goto bind_it;
1475         }
1476
1477         /*
1478          *      Else look for bind_address and/or listen sections.
1479          */
1480         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1481         rcode = cf_item_parse(mainconfig.config, "bind_address",
1482                               PW_TYPE_IPADDR,
1483                               &server_ipaddr.ipaddr.ip4addr, NULL);
1484         if (rcode < 0) return -1; /* error parsing it */
1485         
1486         if (rcode == 0) { /* successfully parsed IPv4 */
1487                 listen_socket_t *sock;
1488                 server_ipaddr.af = AF_INET;
1489
1490                 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'.");
1491
1492         bind_it:
1493                 this = listen_alloc(RAD_LISTEN_AUTH);
1494                 sock = this->data;
1495
1496                 sock->ipaddr = server_ipaddr;
1497                 sock->port = auth_port;
1498                 
1499                 if (listen_bind(this) < 0) {
1500                         listen_free(&this);
1501                         listen_free(head);
1502                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1503                         return -1;
1504                 }
1505                 auth_port = sock->port; /* may have been updated in listen_bind */
1506                 *last = this;
1507                 last = &(this->next);
1508                 
1509                 /*
1510                  *      Open Accounting Socket.
1511                  *
1512                  *      If we haven't already gotten acct_port from
1513                  *      /etc/services, then make it auth_port + 1.
1514                  */
1515                 this = listen_alloc(RAD_LISTEN_ACCT);
1516                 sock = this->data;
1517                 
1518                 /*
1519                  *      Create the accounting socket.
1520                  *
1521                  *      The accounting port is always the
1522                  *      authentication port + 1
1523                  */
1524                 sock->ipaddr = server_ipaddr;
1525                 sock->port = auth_port + 1;
1526                 
1527                 if (listen_bind(this) < 0) {
1528                         listen_free(&this);
1529                         listen_free(head);
1530                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1531                         return -1;
1532                 }
1533
1534                 *last = this;
1535                 last = &(this->next);
1536
1537         } else if (mainconfig.port > 0) { /* no bind address, but a port */
1538                 radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1539                        mainconfig.port);
1540                 return -1;
1541         }
1542
1543         /*
1544          *      They specified an IP on the command-line, ignore
1545          *      all listen sections.
1546          */
1547         if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
1548
1549         /*
1550          *      Walk through the "listen" sections, if they exist.
1551          */
1552         for (cs = cf_subsection_find_next(mainconfig.config, NULL, "listen");
1553              cs != NULL;
1554              cs = cf_subsection_find_next(mainconfig.config, cs, "listen")) {
1555                 int             type;
1556                 char            *listen_type, *identity;
1557                 int             lineno = cf_section_lineno(cs);
1558
1559                 listen_type = identity = NULL;
1560                 
1561                 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1562                                       &listen_type, "");
1563                 if (rcode < 0) return -1;
1564                 if (rcode == 1) {
1565                         listen_free(head);
1566                         free(listen_type);
1567                         radlog(L_ERR, "%s[%d]: No type specified in listen section",
1568                                filename, lineno);
1569                         return -1;
1570                 }
1571
1572                 /*
1573                  *      See if there's an identity.
1574                  */
1575                 rcode = cf_item_parse(cs, "identity", PW_TYPE_STRING_PTR,
1576                                       &identity, NULL);
1577                 if (rcode < 0) {
1578                         listen_free(head);
1579                         free(identity);
1580                         return -1;
1581                 }
1582
1583                 type = lrad_str2int(listen_compare, listen_type,
1584                                     RAD_LISTEN_NONE);
1585                 free(listen_type);
1586                 if (type == RAD_LISTEN_NONE) {
1587                         listen_free(head);
1588                         radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
1589                                filename, lineno);
1590                         return -1;
1591                 }
1592
1593                 /*
1594                  *      Set up cross-type data.
1595                  */
1596                 this = listen_alloc(type);
1597                 this->identity = identity;
1598                 this->fd = -1;
1599                 
1600                 /*
1601                  *      Call per-type parser.
1602                  */
1603                 if (master_listen[type].parse(filename, lineno,
1604                                               cs, this) < 0) {
1605                         listen_free(&this);
1606                         listen_free(head);
1607                         return -1;
1608                 }
1609
1610                 *last = this;
1611                 last = &(this->next);   
1612         }
1613
1614         /*
1615          *      If we're proxying requests, open the proxy FD.
1616          *      Otherwise, don't do anything.
1617          */
1618  do_proxy:
1619         if (mainconfig.proxy_requests == TRUE) {
1620                 int             port = -1;
1621                 listen_socket_t *sock = NULL;
1622
1623                 /*
1624                  *      No sockets to receive packets, therefore
1625                  *      proxying is pointless.
1626                  */
1627                 if (!*head) return -1;
1628
1629                 /*
1630                  *      If we previously had proxy sockets, copy them
1631                  *      to the new config.
1632                  */
1633                 if (mainconfig.listen != NULL) {
1634                         rad_listen_t *old, *next, **tail;
1635
1636                         tail = &mainconfig.listen;
1637                         for (old = mainconfig.listen;
1638                              old != NULL;
1639                              old = next) {
1640                                 next = old->next;
1641
1642                                 if (old->type != RAD_LISTEN_PROXY) {
1643                                         tail = &((*tail)->next);
1644                                         continue;
1645                                 }
1646
1647                                 *last = old;
1648                                 *tail = next;
1649                                 old->next = NULL;
1650                                 last = &(old->next);
1651                         }
1652
1653                         goto done;
1654                 }
1655
1656                 /*
1657                  *      Find the first authentication port,
1658                  *      and use it
1659                  */
1660                 for (this = *head; this != NULL; this = this->next) {
1661                         if (this->type == RAD_LISTEN_AUTH) {
1662                                 sock = this->data;
1663                                 if (server_ipaddr.af == AF_UNSPEC) {
1664                                         server_ipaddr = sock->ipaddr;
1665                                 }
1666                                 port = sock->port + 2; /* skip acct port */
1667                                 break;
1668                         }
1669                 }
1670
1671                 if (port < 0) port = 1024 + (lrad_rand() & 0x1ff);
1672
1673                 /*
1674                  *      Address is still unspecified, use IPv4.
1675                  */
1676                 if (server_ipaddr.af == AF_UNSPEC) {
1677                         server_ipaddr.af = AF_INET;
1678                         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
1679                 }
1680
1681                 this = listen_alloc(RAD_LISTEN_PROXY);
1682                 sock = this->data;
1683
1684                 /*
1685                  *      Create the first proxy socket.
1686                  */
1687                 sock->ipaddr = server_ipaddr;
1688
1689                 /*
1690                  *      Try to find a proxy port (value doesn't matter)
1691                  */
1692                 for (sock->port = port;
1693                      sock->port < 64000;
1694                      sock->port++) {
1695                         if (listen_bind(this) == 0) {
1696                                 *last = this;
1697                                 last = &(this->next); /* just in case */
1698                                 break;
1699                         }
1700                 }
1701
1702                 if (sock->port >= 64000) {
1703                         listen_free(head);
1704                         listen_free(&this);
1705                         radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
1706                         return -1;
1707                 }
1708         }
1709
1710         /*
1711          *      Sanity check the configuration.
1712          */
1713         rcode = 0;
1714         for (this = *head; this != NULL; this = this->next) {
1715                 if (((this->type == RAD_LISTEN_ACCT) &&
1716                      (rcode == RAD_LISTEN_DETAIL)) ||
1717                     ((this->type == RAD_LISTEN_DETAIL) &&
1718                      (rcode == RAD_LISTEN_ACCT))) {
1719                         rad_assert(0 == 1); /* FIXME: configuration error */
1720                 }
1721
1722                 if (rcode != 0) continue;
1723
1724                 if ((this->type == RAD_LISTEN_ACCT) ||
1725                     (this->type == RAD_LISTEN_DETAIL)) {
1726                         rcode = this->type;
1727                 }
1728         }
1729
1730  done:
1731         return 0;
1732 }
1733
1734 /*
1735  *      Free a linked list of listeners;
1736  */
1737 void listen_free(rad_listen_t **head)
1738 {
1739         rad_listen_t *this;
1740
1741         if (!head || !*head) return;
1742
1743         this = *head;
1744         while (this) {
1745                 rad_listen_t *next = this->next;
1746                 
1747                 free(this->identity);
1748
1749                 /*
1750                  *      Other code may have eaten the FD.
1751                  */
1752                 if (this->fd >= 0) close(this->fd);
1753
1754                 if (master_listen[this->type].free) {
1755                         master_listen[this->type].free(this);
1756                 }
1757                 free(this->data);
1758                 free(this);
1759                 
1760                 this = next;
1761         }
1762
1763         *head = NULL;
1764 }