Allow IPv6 to bind to interface with scope.
[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/modules.h>
29 #include <freeradius-devel/rad_assert.h>
30 #include <freeradius-devel/vqp.h>
31 #include <freeradius-devel/dhcp.h>
32
33 #include <freeradius-devel/vmps.h>
34 #include <freeradius-devel/detail.h>
35
36 #ifdef WITH_UDPFROMTO
37 #include <freeradius-devel/udpfromto.h>
38 #endif
39
40 #ifdef HAVE_SYS_RESOURCE_H
41 #include <sys/resource.h>
42 #endif
43
44 #ifdef HAVE_NET_IF_H
45 #include <net/if.h>
46 #endif
47
48 #ifdef HAVE_FCNTL_H
49 #include <fcntl.h>
50 #endif
51
52
53 void print_packet(RADIUS_PACKET *packet)
54 {
55         char src[256], dst[256];
56
57         ip_ntoh(&packet->src_ipaddr, src, sizeof(src));
58         ip_ntoh(&packet->dst_ipaddr, dst, sizeof(dst));
59
60         fprintf(stderr, "ID %d: %s %d -> %s %d\n", packet->id,
61                 src, packet->src_port, dst, packet->dst_port);
62
63 }
64
65
66 /*
67  *      We'll use this below.
68  */
69 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
70 typedef void (*rad_listen_free_t)(rad_listen_t *);
71
72 typedef struct rad_listen_master_t {
73         rad_listen_parse_t      parse;
74         rad_listen_free_t       free;
75         rad_listen_recv_t       recv;
76         rad_listen_send_t       send;
77         rad_listen_print_t      print;
78         rad_listen_encode_t     encode;
79         rad_listen_decode_t     decode;
80 } rad_listen_master_t;
81
82 typedef struct listen_socket_t {
83         /*
84          *      For normal sockets.
85          */
86         fr_ipaddr_t     ipaddr;
87         int             port;
88         const char              *interface;
89         RADCLIENT_LIST  *clients;
90 } listen_socket_t;
91
92 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
93
94 /*
95  *      Find a per-socket client.
96  */
97 RADCLIENT *client_listener_find(const rad_listen_t *listener,
98                                 const fr_ipaddr_t *ipaddr, int src_port)
99 {
100 #ifdef WITH_DYNAMIC_CLIENTS
101         int rcode;
102         REQUEST *request;
103         RADCLIENT *created;
104 #endif
105         time_t now;
106         RADCLIENT *client;
107         RADCLIENT_LIST *clients;
108         listen_socket_t *sock;
109
110         rad_assert(listener != NULL);
111         rad_assert(ipaddr != NULL);
112
113         sock = listener->data;
114         clients = sock->clients;
115
116         /*
117          *      This HAS to have been initialized previously.
118          */
119         rad_assert(clients != NULL);
120
121         client = client_find(clients, ipaddr,sock->proto);
122         if (!client) {
123                 char name[256], buffer[128];
124                                         
125 #ifdef WITH_DYNAMIC_CLIENTS
126         unknown:                /* used only for dynamic clients */
127 #endif
128
129                 /*
130                  *      DoS attack quenching, but only in daemon mode.
131                  *      If they're running in debug mode, show them
132                  *      every packet.
133                  */
134                 if (debug_flag == 0) {
135                         static time_t last_printed = 0;
136
137                         now = time(NULL);
138                         if (last_printed == now) return NULL;
139                         
140                         last_printed = now;
141                 }
142
143                 listener->print(listener, name, sizeof(name));
144
145                 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d"
146 #ifdef WITH_TCP
147                        " proto %s"
148 #endif
149                        , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
150                                          buffer, sizeof(buffer)), src_port
151 #ifdef WITH_TCP
152                        , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp"
153 #endif
154                        );
155                 return NULL;
156         }
157
158 #ifndef WITH_DYNAMIC_CLIENTS
159         return client;          /* return the found client. */
160 #else
161
162         /*
163          *      No server defined, and it's not dynamic.  Return it.
164          */
165         if (!client->client_server && !client->dynamic) return client;
166
167         now = time(NULL);
168         
169         /*
170          *      It's a dynamically generated client, check it.
171          */
172         if (client->dynamic && (src_port != 0)) {
173                 /*
174                  *      Lives forever.  Return it.
175                  */
176                 if (client->lifetime == 0) return client;
177                 
178                 /*
179                  *      Rate-limit the deletion of known clients.
180                  *      This makes them last a little longer, but
181                  *      prevents the server from melting down if (say)
182                  *      10k clients all expire at once.
183                  */
184                 if (now == client->last_new_client) return client;
185
186                 /*
187                  *      It's not dead yet.  Return it.
188                  */
189                 if ((client->created + client->lifetime) > now) return client;
190                 
191                 /*
192                  *      This really puts them onto a queue for later
193                  *      deletion.
194                  */
195                 client_delete(clients, client);
196
197                 /*
198                  *      Go find the enclosing network again.
199                  */
200                 client = client_find(clients, ipaddr, sock->proto);
201
202                 /*
203                  *      WTF?
204                  */
205                 if (!client) goto unknown;
206                 if (!client->client_server) goto unknown;
207
208                 /*
209                  *      At this point, 'client' is the enclosing
210                  *      network that configures where dynamic clients
211                  *      can be defined.
212                  */
213                 rad_assert(client->dynamic == 0);
214         } else {
215                 /*
216                  *      The IP is unknown, so we've found an enclosing
217                  *      network.  Enable DoS protection.  We only
218                  *      allow one new client per second.  Known
219                  *      clients aren't subject to this restriction.
220                  */
221                 if (now == client->last_new_client) goto unknown;
222         }
223
224         client->last_new_client = now;
225
226         request = request_alloc();
227         if (!request) goto unknown;
228
229         request->listener = listener;
230         request->client = client;
231         request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
232         if (!request->packet) {                         /* badly formed, etc */
233                 request_free(&request);
234                 goto unknown;
235         }
236         request->reply = rad_alloc_reply(request->packet);
237         if (!request->reply) {
238                 request_free(&request);
239                 goto unknown;
240         }
241         request->packet->timestamp = request->timestamp;
242         request->number = 0;
243         request->priority = listener->type;
244         request->server = client->client_server;
245         request->root = &mainconfig;
246
247         /*
248          *      Run a fake request through the given virtual server.
249          *      Look for FreeRADIUS-Client-IP-Address
250          *               FreeRADIUS-Client-Secret
251          *              ...
252          *
253          *      and create the RADCLIENT structure from that.
254          */
255         DEBUG("server %s {", request->server);
256
257         rcode = module_authorize(0, request);
258
259         DEBUG("} # server %s", request->server);
260
261         if (rcode != RLM_MODULE_OK) {
262                 request_free(&request);
263                 goto unknown;
264         }
265
266         /*
267          *      If the client was updated by rlm_dynamic_clients,
268          *      don't create the client from attribute-value pairs.
269          */
270         if (request->client == client) {
271                 created = client_create(clients, request);
272         } else {
273                 created = request->client;
274
275                 /*
276                  *      This frees the client if it isn't valid.
277                  */
278                 if (!client_validate(clients, client, created)) goto unknown;
279         }
280         request_free(&request);
281
282         if (!created) goto unknown;
283
284         return created;
285 #endif
286 }
287
288 static int listen_bind(rad_listen_t *this);
289
290
291 /*
292  *      Process and reply to a server-status request.
293  *      Like rad_authenticate and rad_accounting this should
294  *      live in it's own file but it's so small we don't bother.
295  */
296 static int rad_status_server(REQUEST *request)
297 {
298         int rcode = RLM_MODULE_OK;
299         DICT_VALUE *dval;
300
301         switch (request->listener->type) {
302 #ifdef WITH_STATS
303         case RAD_LISTEN_NONE:
304 #endif
305         case RAD_LISTEN_AUTH:
306                 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
307                 if (dval) {
308                         rcode = module_authorize(dval->value, request);
309                 } else {
310                         rcode = RLM_MODULE_OK;
311                 }
312
313                 switch (rcode) {
314                 case RLM_MODULE_OK:
315                 case RLM_MODULE_UPDATED:
316                         request->reply->code = PW_AUTHENTICATION_ACK;
317                         break;
318
319                 case RLM_MODULE_FAIL:
320                 case RLM_MODULE_HANDLED:
321                         request->reply->code = 0; /* don't reply */
322                         break;
323
324                 default:
325                 case RLM_MODULE_REJECT:
326                         request->reply->code = PW_AUTHENTICATION_REJECT;
327                         break;
328                 }
329                 break;
330
331 #ifdef WITH_ACCOUNTING
332         case RAD_LISTEN_ACCT:
333                 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
334                 if (dval) {
335                         rcode = module_accounting(dval->value, request);
336                 } else {
337                         rcode = RLM_MODULE_OK;
338                 }
339
340                 switch (rcode) {
341                 case RLM_MODULE_OK:
342                 case RLM_MODULE_UPDATED:
343                         request->reply->code = PW_ACCOUNTING_RESPONSE;
344                         break;
345
346                 default:
347                         request->reply->code = 0; /* don't reply */
348                         break;
349                 }
350                 break;
351 #endif
352
353 #ifdef WITH_COA
354                 /*
355                  *      This is a vendor extension.  Suggested by Glen
356                  *      Zorn in IETF 72, and rejected by the rest of
357                  *      the WG.  We like it, so it goes in here.
358                  */
359         case RAD_LISTEN_COA:
360                 dval = dict_valbyname(PW_RECV_COA_TYPE, "Status-Server");
361                 if (dval) {
362                         rcode = module_recv_coa(dval->value, request);
363                 } else {
364                         rcode = RLM_MODULE_OK;
365                 }
366
367                 switch (rcode) {
368                 case RLM_MODULE_OK:
369                 case RLM_MODULE_UPDATED:
370                         request->reply->code = PW_COA_ACK;
371                         break;
372
373                 default:
374                         request->reply->code = 0; /* don't reply */
375                         break;
376                 }
377                 break;
378 #endif
379
380         default:
381                 return 0;
382         }
383
384 #ifdef WITH_STATS
385         /*
386          *      Full statistics are available only on a statistics
387          *      socket.
388          */
389         if (request->listener->type == RAD_LISTEN_NONE) {
390                 request_stats_reply(request);
391         }
392 #endif
393
394         return 0;
395 }
396
397 #ifdef WITH_TCP
398 static int auth_tcp_recv(rad_listen_t *listener,
399                          RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
400 {
401         int rcode;
402         RADIUS_PACKET   *packet;
403         RAD_REQUEST_FUNP fun = NULL;
404         listen_socket_t *sock = listener->data;
405         RADCLIENT       *client = sock->client;
406
407         /*
408          *      Allocate a packet for partial reads.
409          */
410         if (!sock->packet) {
411                 sock->packet = rad_alloc(0);
412                 if (!sock->packet) return 0;
413
414                 sock->packet->sockfd = listener->fd;
415                 sock->packet->src_ipaddr = sock->other_ipaddr;
416                 sock->packet->src_port = sock->other_port;
417                 sock->packet->dst_ipaddr = sock->my_ipaddr;
418                 sock->packet->dst_port = sock->my_port;
419         }
420         
421         /*
422          *      Grab the packet currently being processed.
423          */
424         packet = sock->packet;
425
426         rcode = fr_tcp_read_packet(packet, 0);
427
428         /*
429          *      Still only a partial packet.  Put it back, and return,
430          *      so that we'll read more data when it's ready.
431          */
432         if (rcode == 0) {
433                 return 0;
434         }
435
436         if (rcode == -1) {      /* error reading packet */
437                 char buffer[256];
438
439                 radlog(L_ERR, "Invalid packet from %s port %d: closing socket",
440                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
441                        packet->src_port);
442         }
443
444         if (rcode < 0) {        /* error or connection reset */
445                 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
446
447                 /*
448                  *      Decrement the number of connections.
449                  */
450                 if (sock->parent->num_connections > 0) {
451                         sock->parent->num_connections--;
452                 }
453                 if (sock->client->num_connections > 0) {
454                         sock->client->num_connections--;
455                 }
456
457                 /*
458                  *      Tell the event handler that an FD has disappeared.
459                  */
460                 DEBUG("Client has closed connection");
461                 event_new_fd(listener);
462
463                 /*
464                  *      Do NOT free the listener here.  It's in use by
465                  *      a request, and will need to hang around until
466                  *      all of the requests are done.
467                  *
468                  *      It is instead free'd in remove_from_request_hash()
469                  */
470                 return 0;
471         }
472
473         RAD_STATS_TYPE_INC(listener, total_requests);
474
475         /*
476          *      Some sanity checks, based on the packet code.
477          */
478         switch(packet->code) {
479         case PW_AUTHENTICATION_REQUEST:
480                 RAD_STATS_CLIENT_INC(listener, client, total_requests);
481                 fun = rad_authenticate;
482                 break;
483
484         case PW_STATUS_SERVER:
485                 if (!mainconfig.status_server) {
486                         RAD_STATS_TYPE_INC(listener, total_packets_dropped);
487                         RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
488                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
489                         rad_free(&sock->packet);
490                         return 0;
491                 }
492                 fun = rad_status_server;
493                 break;
494
495         default:
496                 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
497                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
498
499                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
500                       packet->code, client->shortname, packet->src_port);
501                 rad_free(&sock->packet);
502                 return 0;
503         } /* switch over packet types */
504
505         if (!received_request(listener, packet, prequest, sock->client)) {
506                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
507                 RAD_STATS_CLIENT_INC(listener, sock->client, total_packets_dropped);
508                 rad_free(&sock->packet);
509                 return 0;
510         }
511
512         *pfun = fun;
513         sock->packet = NULL;    /* we have no need for more partial reads */
514         return 1;
515 }
516
517 static int auth_tcp_accept(rad_listen_t *listener,
518                            UNUSED RAD_REQUEST_FUNP *pfun,
519                            UNUSED REQUEST **prequest)
520 {
521         int newfd, src_port;
522         rad_listen_t *this;
523         socklen_t salen;
524         struct sockaddr_storage src;
525         listen_socket_t *sock;
526         fr_ipaddr_t src_ipaddr;
527         RADCLIENT *client;
528         
529         salen = sizeof(src);
530
531         DEBUG2(" ... new connection request on TCP socket.");
532         
533         newfd = accept(listener->fd, (struct sockaddr *) &src, &salen);
534         if (newfd < 0) {
535                 /*
536                  *      Non-blocking sockets must handle this.
537                  */
538                 if (errno == EWOULDBLOCK) {
539                         return 0;
540                 }
541
542                 DEBUG2(" ... failed to accept connection.");
543                 return -1;
544         }
545
546         if (!fr_sockaddr2ipaddr(&src, salen, &src_ipaddr, &src_port)) {
547                 DEBUG2(" ... unknown address family.");
548                 return 0;
549         }
550
551         /*
552          *      Enforce client IP address checks on accept, not on
553          *      every packet.
554          */
555         if ((client = client_listener_find(listener,
556                                            &src_ipaddr, src_port)) == NULL) {
557                 close(newfd);
558                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
559                 return 0;
560         }
561
562         /*
563          *      Enforce max_connectionsx on client && listen section.
564          */
565         if ((client->max_connections != 0) &&
566             (client->max_connections == client->num_connections)) {
567                 /*
568                  *      FIXME: Print client IP/port, and server IP/port.
569                  */
570                 radlog(L_INFO, "Ignoring new connection due to client max_connections (%d)", client->max_connections);
571                 close(newfd);
572                 return 0;
573         }
574
575         sock = listener->data;
576         if ((sock->max_connections != 0) &&
577             (sock->max_connections == sock->num_connections)) {
578                 /*
579                  *      FIXME: Print client IP/port, and server IP/port.
580                  */
581                 radlog(L_INFO, "Ignoring new connection due to socket max_connections");
582                 close(newfd);
583                 return 0;
584         }
585         client->num_connections++;
586         sock->num_connections++;
587
588         /*
589          *      Add the new listener.
590          */
591         this = listen_alloc(listener->type);
592         if (!this) return -1;
593
594         /*
595          *      Copy everything, including the pointer to the socket
596          *      information.
597          */
598         sock = this->data;
599         memcpy(this->data, listener->data, sizeof(*sock));
600         memcpy(this, listener, sizeof(*this));
601         this->next = NULL;
602         this->data = sock;      /* fix it back */
603
604         sock->parent = listener->data;
605         sock->other_ipaddr = src_ipaddr;
606         sock->other_port = src_port;
607         sock->client = client;
608
609         this->fd = newfd;
610         this->status = RAD_LISTEN_STATUS_INIT;
611         this->recv = auth_tcp_recv;
612
613         /*
614          *      FIXME: set O_NONBLOCK on the accept'd fd.
615          *      See djb's portability rants for details.
616          */
617
618         /*
619          *      Tell the event loop that we have a new FD.
620          *      This can be called from a child thread...
621          */
622         event_new_fd(this);
623
624         return 0;
625 }
626 #endif
627
628
629 /*
630  *      This function is stupid and complicated.
631  */
632 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
633 {
634         size_t len;
635         listen_socket_t *sock = this->data;
636         const char *name;
637
638         switch (this->type) {
639 #ifdef WITH_STATS
640         case RAD_LISTEN_NONE:   /* what a hack... */
641                 name = "status";
642                 break;
643 #endif
644
645         case RAD_LISTEN_AUTH:
646                 name = "authentication";
647                 break;
648
649 #ifdef WITH_ACCOUNTING
650         case RAD_LISTEN_ACCT:
651                 name = "accounting";
652                 break;
653 #endif
654
655 #ifdef WITH_PROXY
656         case RAD_LISTEN_PROXY:
657                 name = "proxy";
658                 break;
659 #endif
660
661 #ifdef WITH_VMPS
662         case RAD_LISTEN_VQP:
663                 name = "vmps";
664                 break;
665 #endif
666
667 #ifdef WITH_DHCP
668         case RAD_LISTEN_DHCP:
669                 name = "dhcp";
670                 break;
671 #endif
672
673 #ifdef WITH_COA
674         case RAD_LISTEN_COA:
675                 name = "coa";
676                 break;
677 #endif
678
679         default:
680                 name = "??";
681                 break;
682         }
683
684 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
685 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
686
687         ADDSTRING(name);
688
689         if (sock->interface) {
690                 ADDSTRING(" interface ");
691                 ADDSTRING(sock->interface);
692         }
693
694 #ifdef WITH_TCP
695         if (this->recv == auth_tcp_accept) {
696                 ADDSTRING(" proto tcp");
697         }
698 #endif
699
700 #ifdef WITH_TCP
701         /*
702          *      TCP sockets get printed a little differently, to make
703          *      it clear what's going on.
704          */
705         if (sock->client) {
706                 ADDSTRING(" from client (");
707                 ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
708                 FORWARD;
709
710                 ADDSTRING(", ");
711                 snprintf(buffer, bufsize, "%d", sock->other_port);
712                 FORWARD;
713                 ADDSTRING(") -> (");
714
715                 if ((sock->my_ipaddr.af == AF_INET) &&
716                     (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
717                         strlcpy(buffer, "*", bufsize);
718                 } else {
719                         ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
720                 }
721                 FORWARD;
722                 
723                 ADDSTRING(", ");
724                 snprintf(buffer, bufsize, "%d", sock->my_port);
725                 FORWARD;
726
727                 if (this->server) {
728                         ADDSTRING(", virtual-server=");
729                         ADDSTRING(this->server);
730                 }
731
732                 ADDSTRING(")");
733
734                 return 1;
735         }
736
737         /*
738          *      Maybe it's a socket that we opened to a home server.
739          */
740         if ((sock->proto == IPPROTO_TCP) &&
741             (this->type == RAD_LISTEN_PROXY)) {
742                 ADDSTRING(" (");
743                 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
744                 FORWARD;
745
746                 ADDSTRING(", ");
747                 snprintf(buffer, bufsize, "%d", sock->my_port);
748                 FORWARD;
749                 ADDSTRING(") -> home_server (");
750
751                 if ((sock->other_ipaddr.af == AF_INET) &&
752                     (sock->other_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
753                         strlcpy(buffer, "*", bufsize);
754                 } else {
755                         ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
756                 }
757                 FORWARD;
758                 
759                 ADDSTRING(", ");
760                 snprintf(buffer, bufsize, "%d", sock->other_port);
761                 FORWARD;
762
763                 ADDSTRING(")");
764
765                 return 1;
766         }
767 #endif
768
769         ADDSTRING(" address ");
770         
771         if ((sock->my_ipaddr.af == AF_INET) &&
772             (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
773                 strlcpy(buffer, "*", bufsize);
774         } else {
775                 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
776         }
777         FORWARD;
778
779         ADDSTRING(" port ");
780         snprintf(buffer, bufsize, "%d", sock->my_port);
781         FORWARD;
782
783         if (this->server) {
784                 ADDSTRING(" as server ");
785                 ADDSTRING(this->server);
786         }
787
788 #undef ADDSTRING
789 #undef FORWARD
790
791         return 1;
792 }
793
794
795 /*
796  *      Parse an authentication or accounting socket.
797  */
798 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
799 {
800         int             rcode;
801         int             listen_port;
802         fr_ipaddr_t     ipaddr;
803         listen_socket_t *sock = this->data;
804         char            *section_name = NULL;
805         CONF_SECTION    *client_cs, *parentcs;
806
807         /*
808          *      Try IPv4 first
809          */
810         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
811         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
812                               &ipaddr.ipaddr.ip4addr, NULL);
813         if (rcode < 0) return -1;
814
815         if (rcode == 0) { /* successfully parsed IPv4 */
816                 ipaddr.af = AF_INET;
817
818         } else {        /* maybe IPv6? */
819                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
820                                       &ipaddr.ipaddr.ip6addr, NULL);
821                 if (rcode < 0) return -1;
822
823                 if (rcode == 1) {
824                         cf_log_err(cf_sectiontoitem(cs),
825                                    "No address specified in listen section");
826                         return -1;
827                 }
828                 ipaddr.af = AF_INET6;
829         }
830
831         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
832                               &listen_port, "0");
833         if (rcode < 0) return -1;
834
835         if ((listen_port < 0) || (listen_port > 65535)) {
836                         cf_log_err(cf_sectiontoitem(cs),
837                                    "Invalid value for \"port\"");
838                         return -1;
839         }
840
841         sock->proto = IPPROTO_UDP;
842
843         if (cf_pair_find(cs, "proto")) {
844 #ifndef WITH_TCP
845                 cf_log_err(cf_sectiontoitem(cs),
846                            "System does not support the TCP protocol.  Delete this line from the configuration file.");
847                 return -1;
848 #else
849                 char *proto = NULL;
850
851
852                 rcode = cf_item_parse(cs, "proto", PW_TYPE_STRING_PTR,
853                                       &proto, "udp");
854                 if (rcode < 0) return -1;
855
856                 if (strcmp(proto, "udp") == 0) {
857                         sock->proto = IPPROTO_UDP;
858
859                 } else if (strcmp(proto, "tcp") == 0) {
860                         sock->proto = IPPROTO_TCP;
861
862                         rcode = cf_item_parse(cs, "max_connections", PW_TYPE_INTEGER,
863                                               &sock->max_connections, "64");
864                         if (rcode < 0) return -1;
865
866                 } else {
867                         cf_log_err(cf_sectiontoitem(cs),
868                                    "Unknown proto name \"%s\"", proto);
869                         free(proto);
870                         return -1;
871                 }
872                 free(proto);
873
874                 /*
875                  *      TCP requires a destination IP for sockets.
876                  *      UDP doesn't, so it's allowed.
877                  */
878                 if ((this->type == RAD_LISTEN_PROXY) &&
879                     (sock->proto != IPPROTO_UDP)) {
880                         cf_log_err(cf_sectiontoitem(cs),
881                                    "Proxy listeners can only listen on proto = udp");
882                         return -1;
883                 }
884 #endif
885         }
886
887         sock->my_ipaddr = ipaddr;
888         sock->my_port = listen_port;
889
890         /*
891          *      If we can bind to interfaces, do so,
892          *      else don't.
893          */
894         if (cf_pair_find(cs, "interface")) {
895                 const char *value;
896                 CONF_PAIR *cp = cf_pair_find(cs, "interface");
897
898                 rad_assert(cp != NULL);
899                 value = cf_pair_value(cp);
900                 if (!value) {
901                         cf_log_err(cf_sectiontoitem(cs),
902                                    "No interface name given");
903                         return -1;
904                 }
905                 sock->interface = value;
906         }
907
908 #ifdef WITH_DHCP
909         /*
910          *      If we can do broadcasts..
911          */
912         if (cf_pair_find(cs, "broadcast")) {
913 #ifndef SO_BROADCAST
914                 cf_log_err(cf_sectiontoitem(cs),
915                            "System does not support broadcast sockets.  Delete this line from the configuration file.");
916                 return -1;
917 #else
918                 const char *value;
919                 CONF_PAIR *cp = cf_pair_find(cs, "broadcast");
920
921                 if (this->type != RAD_LISTEN_DHCP) {
922                         cf_log_err(cf_pairtoitem(cp),
923                                    "Broadcast can only be set for DHCP listeners.  Delete this line from the configuration file.");
924                         return -1;
925                 }
926                 
927                 rad_assert(cp != NULL);
928                 value = cf_pair_value(cp);
929                 if (!value) {
930                         cf_log_err(cf_sectiontoitem(cs),
931                                    "No broadcast value given");
932                         return -1;
933                 }
934
935                 /*
936                  *      Hack... whatever happened to cf_section_parse?
937                  */
938                 sock->broadcast = (strcmp(value, "yes") == 0);
939 #endif
940         }
941 #endif
942
943         /*
944          *      And bind it to the port.
945          */
946         if (listen_bind(this) < 0) {
947                 char buffer[128];
948                 cf_log_err(cf_sectiontoitem(cs),
949                            "Error binding to port for %s port %d",
950                            ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
951                            sock->my_port);
952                 return -1;
953         }
954
955 #ifdef WITH_PROXY
956         /*
957          *      Proxy sockets don't have clients.
958          */
959         if (this->type == RAD_LISTEN_PROXY) return 0;
960 #endif
961         
962         /*
963          *      The more specific configurations are preferred to more
964          *      generic ones.
965          */
966         client_cs = NULL;
967         parentcs = cf_top_section(cs);
968         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
969                               &section_name, NULL);
970         if (rcode < 0) return -1; /* bad string */
971         if (rcode == 0) {
972                 /*
973                  *      Explicit list given: use it.
974                  */
975                 client_cs = cf_section_sub_find_name2(parentcs,
976                                                       "clients",
977                                                       section_name);
978                 if (!client_cs) {
979                         client_cs = cf_section_find(section_name);
980                 }
981                 if (!client_cs) {
982                         cf_log_err(cf_sectiontoitem(cs),
983                                    "Failed to find clients %s {...}",
984                                    section_name);
985                         free(section_name);
986                         return -1;
987                 }
988                 free(section_name);
989         } /* else there was no "clients = " entry. */
990
991         if (!client_cs) {
992                 CONF_SECTION *server_cs;
993
994                 server_cs = cf_section_sub_find_name2(parentcs,
995                                                       "server",
996                                                       this->server);
997                 /*
998                  *      Found a "server foo" section.  If there are clients
999                  *      in it, use them.
1000                  */
1001                 if (server_cs &&
1002                     (cf_section_sub_find(server_cs, "client") != NULL)) {
1003                         client_cs = server_cs;
1004                 }
1005         }
1006
1007         /*
1008          *      Still nothing.  Look for global clients.
1009          */
1010         if (!client_cs) client_cs = parentcs;
1011
1012         sock->clients = clients_parse_section(client_cs);
1013         if (!sock->clients) {
1014                 cf_log_err(cf_sectiontoitem(cs),
1015                            "Failed to load clients for this listen section");
1016                 return -1;
1017         }
1018
1019 #ifdef WITH_TCP
1020         if (sock->proto == IPPROTO_TCP) {
1021                 /*
1022                  *      Re-write the listener receive function to
1023                  *      allow us to accept the socket.
1024                  */
1025                 this->recv = auth_tcp_accept;
1026         }
1027 #endif
1028
1029         return 0;
1030 }
1031
1032 /*
1033  *      Send an authentication response packet
1034  */
1035 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
1036 {
1037         rad_assert(request->listener == listener);
1038         rad_assert(listener->send == auth_socket_send);
1039
1040         return rad_send(request->reply, request->packet,
1041                         request->client->secret);
1042 }
1043
1044
1045 #ifdef WITH_ACCOUNTING
1046 /*
1047  *      Send an accounting response packet (or not)
1048  */
1049 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
1050 {
1051         rad_assert(request->listener == listener);
1052         rad_assert(listener->send == acct_socket_send);
1053
1054         /*
1055          *      Accounting reject's are silently dropped.
1056          *
1057          *      We do it here to avoid polluting the rest of the
1058          *      code with this knowledge
1059          */
1060         if (request->reply->code == 0) return 0;
1061
1062         return rad_send(request->reply, request->packet,
1063                         request->client->secret);
1064 }
1065 #endif
1066
1067 #ifdef WITH_PROXY
1068 /*
1069  *      Send a packet to a home server.
1070  *
1071  *      FIXME: have different code for proxy auth & acct!
1072  */
1073 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
1074 {
1075         rad_assert(request->proxy_listener == listener);
1076         rad_assert(listener->send == proxy_socket_send);
1077
1078         return rad_send(request->proxy, request->packet,
1079                         request->home_server->secret);
1080 }
1081 #endif
1082
1083 #ifdef WITH_STATS
1084 /*
1085  *      Check if an incoming request is "ok"
1086  *
1087  *      It takes packets, not requests.  It sees if the packet looks
1088  *      OK.  If so, it does a number of sanity checks on it.
1089   */
1090 static int stats_socket_recv(rad_listen_t *listener,
1091                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1092 {
1093         ssize_t         rcode;
1094         int             code, src_port;
1095         RADIUS_PACKET   *packet;
1096         RADCLIENT       *client;
1097         fr_ipaddr_t     src_ipaddr;
1098
1099         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1100         if (rcode < 0) return 0;
1101
1102         RAD_STATS_TYPE_INC(listener, total_requests);
1103
1104         if (rcode < 20) {       /* AUTH_HDR_LEN */
1105                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1106                 return 0;
1107         }
1108
1109         if ((client = client_listener_find(listener,
1110                                            &src_ipaddr, src_port)) == NULL) {
1111                 rad_recv_discard(listener->fd);
1112                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1113                 return 0;
1114         }
1115
1116         /*
1117          *      We only understand Status-Server on this socket.
1118          */
1119         if (code != PW_STATUS_SERVER) {
1120                 DEBUG("Ignoring packet code %d sent to Status-Server port",
1121                       code);
1122                 rad_recv_discard(listener->fd);
1123                 RAD_STATS_TYPE_INC(listener, total_unknown_types);
1124                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
1125                 return 0;
1126         }
1127
1128         /*
1129          *      Now that we've sanity checked everything, receive the
1130          *      packet.
1131          */
1132         packet = rad_recv(listener->fd, 1); /* require message authenticator */
1133         if (!packet) {
1134                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1135                 DEBUG("%s", fr_strerror());
1136                 return 0;
1137         }
1138
1139         if (!received_request(listener, packet, prequest, client)) {
1140                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1141                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
1142                 rad_free(&packet);
1143                 return 0;
1144         }
1145
1146         *pfun = rad_status_server;
1147         return 1;
1148 }
1149 #endif
1150
1151
1152 /*
1153  *      Check if an incoming request is "ok"
1154  *
1155  *      It takes packets, not requests.  It sees if the packet looks
1156  *      OK.  If so, it does a number of sanity checks on it.
1157   */
1158 static int auth_socket_recv(rad_listen_t *listener,
1159                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1160 {
1161         ssize_t         rcode;
1162         int             code, src_port;
1163         RADIUS_PACKET   *packet;
1164         RAD_REQUEST_FUNP fun = NULL;
1165         RADCLIENT       *client;
1166         fr_ipaddr_t     src_ipaddr;
1167
1168         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1169         if (rcode < 0) return 0;
1170
1171         RAD_STATS_TYPE_INC(listener, total_requests);
1172
1173         if (rcode < 20) {       /* AUTH_HDR_LEN */
1174                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1175                 return 0;
1176         }
1177
1178         if ((client = client_listener_find(listener,
1179                                            &src_ipaddr, src_port)) == NULL) {
1180                 rad_recv_discard(listener->fd);
1181                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1182                 return 0;
1183         }
1184
1185         /*
1186          *      Some sanity checks, based on the packet code.
1187          */
1188         switch(code) {
1189         case PW_AUTHENTICATION_REQUEST:
1190                 RAD_STATS_CLIENT_INC(listener, client, total_requests);
1191                 fun = rad_authenticate;
1192                 break;
1193
1194         case PW_STATUS_SERVER:
1195                 if (!mainconfig.status_server) {
1196                         rad_recv_discard(listener->fd);
1197                         RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1198                         RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
1199                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1200                         return 0;
1201                 }
1202                 fun = rad_status_server;
1203                 break;
1204
1205         default:
1206                 rad_recv_discard(listener->fd);
1207                 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
1208                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
1209
1210                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
1211                       code, client->shortname, src_port);
1212                 return 0;
1213                 break;
1214         } /* switch over packet types */
1215
1216         /*
1217          *      Now that we've sanity checked everything, receive the
1218          *      packet.
1219          */
1220         packet = rad_recv(listener->fd, client->message_authenticator);
1221         if (!packet) {
1222                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1223                 DEBUG("%s", fr_strerror());
1224                 return 0;
1225         }
1226
1227         if (!received_request(listener, packet, prequest, client)) {
1228                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1229                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
1230                 rad_free(&packet);
1231                 return 0;
1232         }
1233
1234         *pfun = fun;
1235         return 1;
1236 }
1237
1238
1239 #ifdef WITH_ACCOUNTING
1240 /*
1241  *      Receive packets from an accounting socket
1242  */
1243 static int acct_socket_recv(rad_listen_t *listener,
1244                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1245 {
1246         ssize_t         rcode;
1247         int             code, src_port;
1248         RADIUS_PACKET   *packet;
1249         RAD_REQUEST_FUNP fun = NULL;
1250         RADCLIENT       *client;
1251         fr_ipaddr_t     src_ipaddr;
1252
1253         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1254         if (rcode < 0) return 0;
1255
1256         RAD_STATS_TYPE_INC(listener, total_requests);
1257
1258         if (rcode < 20) {       /* AUTH_HDR_LEN */
1259                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1260                 return 0;
1261         }
1262
1263         if ((client = client_listener_find(listener,
1264                                            &src_ipaddr, src_port)) == NULL) {
1265                 rad_recv_discard(listener->fd);
1266                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1267                 return 0;
1268         }
1269
1270         /*
1271          *      Some sanity checks, based on the packet code.
1272          */
1273         switch(code) {
1274         case PW_ACCOUNTING_REQUEST:
1275                 RAD_STATS_CLIENT_INC(listener, client, total_requests);
1276                 fun = rad_accounting;
1277                 break;
1278
1279         case PW_STATUS_SERVER:
1280                 if (!mainconfig.status_server) {
1281                         rad_recv_discard(listener->fd);
1282                         RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1283                         RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
1284
1285                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1286                         return 0;
1287                 }
1288                 fun = rad_status_server;
1289                 break;
1290
1291         default:
1292                 rad_recv_discard(listener->fd);
1293                 RAD_STATS_TYPE_INC(listener, total_unknown_types);
1294                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
1295
1296                 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1297                       code, client->shortname, src_port);
1298                 return 0;
1299         } /* switch over packet types */
1300
1301         /*
1302          *      Now that we've sanity checked everything, receive the
1303          *      packet.
1304          */
1305         packet = rad_recv(listener->fd, 0);
1306         if (!packet) {
1307                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1308                 radlog(L_ERR, "%s", fr_strerror());
1309                 return 0;
1310         }
1311
1312         /*
1313          *      There can be no duplicate accounting packets.
1314          */
1315         if (!received_request(listener, packet, prequest, client)) {
1316                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1317                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
1318                 rad_free(&packet);
1319                 return 0;
1320         }
1321
1322         *pfun = fun;
1323         return 1;
1324 }
1325 #endif
1326
1327
1328 #ifdef WITH_COA
1329 /*
1330  *      For now, all CoA requests are *only* originated, and not
1331  *      proxied.  So all of the necessary work is done in the
1332  *      post-proxy section, which is automatically handled by event.c.
1333  *      As a result, we don't have to do anything here.
1334  */
1335 static int rad_coa_reply(REQUEST *request)
1336 {
1337         VALUE_PAIR *s1, *s2;
1338
1339         /*
1340          *      Inform the user about RFC requirements.
1341          */
1342         s1 = pairfind(request->proxy->vps, PW_STATE);
1343         if (s1) {
1344                 s2 = pairfind(request->proxy_reply->vps, PW_STATE);
1345
1346                 if (!s2) {
1347                         DEBUG("WARNING: Client was sent State in CoA, and did not respond with State.");
1348
1349                 } else if ((s1->length != s2->length) ||
1350                            (memcmp(s1->vp_octets, s2->vp_octets,
1351                                    s1->length) != 0)) {
1352                         DEBUG("WARNING: Client was sent State in CoA, and did not respond with the same State.");
1353                 }
1354         }
1355
1356         return RLM_MODULE_OK;
1357 }
1358
1359 /*
1360  *      Receive a CoA packet.
1361  */
1362 static int rad_coa_recv(REQUEST *request)
1363 {
1364         int rcode = RLM_MODULE_OK;
1365         int ack, nak;
1366         VALUE_PAIR *vp;
1367
1368         /*
1369          *      Get the correct response
1370          */
1371         switch (request->packet->code) {
1372         case PW_COA_REQUEST:
1373                 ack = PW_COA_ACK;
1374                 nak = PW_COA_NAK;
1375                 break;
1376
1377         case PW_DISCONNECT_REQUEST:
1378                 ack = PW_DISCONNECT_ACK;
1379                 nak = PW_DISCONNECT_NAK;
1380                 break;
1381
1382         default:                /* shouldn't happen */
1383                 return RLM_MODULE_FAIL;
1384         }
1385
1386 #ifdef WITH_PROXY
1387 #define WAS_PROXIED (request->proxy)
1388 #else
1389 #define WAS_PROXIED (0)
1390 #endif
1391
1392         if (!WAS_PROXIED) {
1393                 /*
1394                  *      RFC 5176 Section 3.3.  If we have a CoA-Request
1395                  *      with Service-Type = Authorize-Only, it MUST
1396                  *      have a State attribute in it.
1397                  */
1398                 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE);
1399                 if (request->packet->code == PW_COA_REQUEST) {
1400                         if (vp && (vp->vp_integer == 17)) {
1401                                 vp = pairfind(request->packet->vps, PW_STATE);
1402                                 if (!vp || (vp->length == 0)) {
1403                                         RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1404                                         request->reply->code = PW_COA_NAK;
1405                                         return RLM_MODULE_FAIL;
1406                                 }
1407                         }
1408                 } else if (vp) {
1409                         /*
1410                          *      RFC 5176, Section 3.2.
1411                          */
1412                         RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
1413                         request->reply->code = PW_DISCONNECT_NAK;
1414                         return RLM_MODULE_FAIL;
1415                 }
1416
1417                 rcode = module_recv_coa(0, request);
1418                 switch (rcode) {
1419                 case RLM_MODULE_FAIL:
1420                 case RLM_MODULE_INVALID:
1421                 case RLM_MODULE_REJECT:
1422                 case RLM_MODULE_USERLOCK:
1423                 default:
1424                         request->reply->code = nak;
1425                         break;
1426                         
1427                 case RLM_MODULE_HANDLED:
1428                         return rcode;
1429                         
1430                 case RLM_MODULE_NOOP:
1431                 case RLM_MODULE_NOTFOUND:
1432                 case RLM_MODULE_OK:
1433                 case RLM_MODULE_UPDATED:
1434                         request->reply->code = ack;
1435                         break;
1436                 }
1437         } else {
1438                 /*
1439                  *      Start the reply code with the proxy reply
1440                  *      code.
1441                  */
1442                 request->reply->code = request->proxy_reply->code;
1443         }
1444
1445         /*
1446          *      Copy State from the request to the reply.
1447          *      See RFC 5176 Section 3.3.
1448          */
1449         vp = paircopy2(request->packet->vps, PW_STATE);
1450         if (vp) pairadd(&request->reply->vps, vp);
1451
1452         /*
1453          *      We may want to over-ride the reply.
1454          */
1455         rcode = module_send_coa(0, request);
1456         switch (rcode) {
1457                 /*
1458                  *      We need to send CoA-NAK back if Service-Type
1459                  *      is Authorize-Only.  Rely on the user's policy
1460                  *      to do that.  We're not a real NAS, so this
1461                  *      restriction doesn't (ahem) apply to us.
1462                  */
1463                 case RLM_MODULE_FAIL:
1464                 case RLM_MODULE_INVALID:
1465                 case RLM_MODULE_REJECT:
1466                 case RLM_MODULE_USERLOCK:
1467                 default:
1468                         /*
1469                          *      Over-ride an ACK with a NAK
1470                          */
1471                         request->reply->code = nak;
1472                         break;
1473                         
1474                 case RLM_MODULE_HANDLED:
1475                         return rcode;
1476                         
1477                 case RLM_MODULE_NOOP:
1478                 case RLM_MODULE_NOTFOUND:
1479                 case RLM_MODULE_OK:
1480                 case RLM_MODULE_UPDATED:
1481                         /*
1482                          *      Do NOT over-ride a previously set value.
1483                          *      Otherwise an "ok" here will re-write a
1484                          *      NAK to an ACK.
1485                          */
1486                         if (request->reply->code == 0) {
1487                                 request->reply->code = ack;
1488                         }
1489                         break;
1490
1491         }
1492
1493         return RLM_MODULE_OK;
1494 }
1495
1496
1497 /*
1498  *      Check if an incoming request is "ok"
1499  *
1500  *      It takes packets, not requests.  It sees if the packet looks
1501  *      OK.  If so, it does a number of sanity checks on it.
1502   */
1503 static int coa_socket_recv(rad_listen_t *listener,
1504                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1505 {
1506         ssize_t         rcode;
1507         int             code, src_port;
1508         RADIUS_PACKET   *packet;
1509         RAD_REQUEST_FUNP fun = NULL;
1510         RADCLIENT       *client;
1511         fr_ipaddr_t     src_ipaddr;
1512
1513         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1514         if (rcode < 0) return 0;
1515
1516         RAD_STATS_TYPE_INC(listener, total_requests);
1517
1518         if (rcode < 20) {       /* AUTH_HDR_LEN */
1519                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1520                 return 0;
1521         }
1522
1523         if ((client = client_listener_find(listener,
1524                                            &src_ipaddr, src_port)) == NULL) {
1525                 rad_recv_discard(listener->fd);
1526                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1527                 return 0;
1528         }
1529
1530         /*
1531          *      Some sanity checks, based on the packet code.
1532          */
1533         switch(code) {
1534         case PW_COA_REQUEST:
1535         case PW_DISCONNECT_REQUEST:
1536                 fun = rad_coa_recv;
1537                 break;
1538
1539         default:
1540                 rad_recv_discard(listener->fd);
1541                 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1542                       code, client->shortname, src_port);
1543                 return 0;
1544                 break;
1545         } /* switch over packet types */
1546
1547         /*
1548          *      Now that we've sanity checked everything, receive the
1549          *      packet.
1550          */
1551         packet = rad_recv(listener->fd, client->message_authenticator);
1552         if (!packet) {
1553                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1554                 DEBUG("%s", fr_strerror());
1555                 return 0;
1556         }
1557
1558         if (!received_request(listener, packet, prequest, client)) {
1559                 rad_free(&packet);
1560                 return 0;
1561         }
1562
1563         *pfun = fun;
1564         return 1;
1565 }
1566 #endif
1567
1568 #ifdef WITH_PROXY
1569 /*
1570  *      Recieve packets from a proxy socket.
1571  */
1572 static int proxy_socket_recv(rad_listen_t *listener,
1573                               RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1574 {
1575         REQUEST         *request;
1576         RADIUS_PACKET   *packet;
1577         RAD_REQUEST_FUNP fun = NULL;
1578         char            buffer[128];
1579
1580         packet = rad_recv(listener->fd, 0);
1581         if (!packet) {
1582                 radlog(L_ERR, "%s", fr_strerror());
1583                 return 0;
1584         }
1585
1586         /*
1587          *      FIXME: Client MIB updates?
1588          */
1589         switch(packet->code) {
1590         case PW_AUTHENTICATION_ACK:
1591         case PW_ACCESS_CHALLENGE:
1592         case PW_AUTHENTICATION_REJECT:
1593                 fun = rad_authenticate;
1594                 break;
1595
1596 #ifdef WITH_ACCOUNTING
1597         case PW_ACCOUNTING_RESPONSE:
1598                 fun = rad_accounting;
1599                 break;
1600 #endif
1601
1602 #ifdef WITH_COA
1603         case PW_DISCONNECT_ACK:
1604         case PW_DISCONNECT_NAK:
1605         case PW_COA_ACK:
1606         case PW_COA_NAK:
1607                 fun = rad_coa_reply;
1608                 break;
1609 #endif
1610
1611         default:
1612                 /*
1613                  *      FIXME: Update MIB for packet types?
1614                  */
1615                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1616                        "from home server %s port %d - ID %d : IGNORED",
1617                        packet->code,
1618                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1619                        packet->src_port, packet->id);
1620                 rad_free(&packet);
1621                 return 0;
1622         }
1623
1624         request = received_proxy_response(packet);
1625         if (!request) {
1626                 rad_free(&packet);
1627                 return 0;
1628         }
1629
1630 #ifdef WITH_COA
1631         /*
1632          *      Distinguish proxied CoA requests from ones we
1633          *      originate.
1634          */
1635         if ((fun == rad_coa_reply) &&
1636             (request->packet->code == request->proxy->code)) {
1637                 fun = rad_coa_recv;
1638         }
1639 #endif
1640
1641         rad_assert(fun != NULL);
1642         *pfun = fun;
1643         *prequest = request;
1644
1645         return 1;
1646 }
1647
1648 #ifdef WITH_TCP
1649 /*
1650  *      Recieve packets from a proxy socket.
1651  */
1652 static int proxy_socket_tcp_recv(rad_listen_t *listener,
1653                                  RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1654 {
1655         REQUEST         *request;
1656         RADIUS_PACKET   *packet;
1657         RAD_REQUEST_FUNP fun = NULL;
1658         listen_socket_t *sock = listener->data;
1659         char            buffer[128];
1660
1661         packet = fr_tcp_recv(listener->fd, 0);
1662         if (!packet) {
1663                 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
1664                 event_new_fd(listener);
1665                 return 0;
1666         }
1667
1668         /*
1669          *      FIXME: Client MIB updates?
1670          */
1671         switch(packet->code) {
1672         case PW_AUTHENTICATION_ACK:
1673         case PW_ACCESS_CHALLENGE:
1674         case PW_AUTHENTICATION_REJECT:
1675                 fun = rad_authenticate;
1676                 break;
1677
1678 #ifdef WITH_ACCOUNTING
1679         case PW_ACCOUNTING_RESPONSE:
1680                 fun = rad_accounting;
1681                 break;
1682 #endif
1683
1684         default:
1685                 /*
1686                  *      FIXME: Update MIB for packet types?
1687                  */
1688                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1689                        "from home server %s port %d - ID %d : IGNORED",
1690                        packet->code,
1691                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1692                        packet->src_port, packet->id);
1693                 rad_free(&packet);
1694                 return 0;
1695         }
1696
1697         packet->src_ipaddr = sock->other_ipaddr;
1698         packet->src_port = sock->other_port;
1699         packet->dst_ipaddr = sock->my_ipaddr;
1700         packet->dst_port = sock->my_port;
1701
1702         /*
1703          *      FIXME: Have it return an indication of packets that
1704          *      are OK to ignore (dups, too late), versus ones that
1705          *      aren't OK to ignore (unknown response, spoofed, etc.)
1706          *
1707          *      Close the socket on bad packets...
1708          */
1709         request = received_proxy_response(packet);
1710         if (!request) {
1711                 return 0;
1712         }
1713
1714         rad_assert(fun != NULL);
1715         sock->opened = sock->last_packet = request->timestamp;
1716
1717         *pfun = fun;
1718         *prequest = request;
1719
1720         return 1;
1721 }
1722 #endif
1723 #endif
1724
1725
1726 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1727 {
1728         if (!request->reply->code) return 0;
1729
1730         rad_encode(request->reply, request->packet,
1731                    request->client->secret);
1732         rad_sign(request->reply, request->packet,
1733                  request->client->secret);
1734
1735         return 0;
1736 }
1737
1738
1739 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1740 {
1741         if (rad_verify(request->packet, NULL,
1742                        request->client->secret) < 0) {
1743                 return -1;
1744         }
1745
1746         return rad_decode(request->packet, NULL,
1747                           request->client->secret);
1748 }
1749
1750 #ifdef WITH_PROXY
1751 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1752 {
1753         rad_encode(request->proxy, NULL, request->home_server->secret);
1754         rad_sign(request->proxy, NULL, request->home_server->secret);
1755
1756         return 0;
1757 }
1758
1759
1760 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1761 {
1762         /*
1763          *      rad_verify is run in event.c, received_proxy_response()
1764          */
1765
1766         return rad_decode(request->proxy_reply, request->proxy,
1767                            request->home_server->secret);
1768 }
1769 #endif
1770
1771 #include "dhcpd.c"
1772
1773 #include "command.c"
1774
1775 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1776 #ifdef WITH_STATS
1777         { common_socket_parse, NULL,
1778           stats_socket_recv, auth_socket_send,
1779           socket_print, client_socket_encode, client_socket_decode },
1780 #else
1781         /*
1782          *      This always gets defined.
1783          */
1784         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
1785 #endif
1786
1787 #ifdef WITH_PROXY
1788         /* proxying */
1789         { common_socket_parse, NULL,
1790           proxy_socket_recv, proxy_socket_send,
1791           socket_print, proxy_socket_encode, proxy_socket_decode },
1792 #endif
1793
1794         /* authentication */
1795         { common_socket_parse, NULL,
1796           auth_socket_recv, auth_socket_send,
1797           socket_print, client_socket_encode, client_socket_decode },
1798
1799 #ifdef WITH_ACCOUNTING
1800         /* accounting */
1801         { common_socket_parse, NULL,
1802           acct_socket_recv, acct_socket_send,
1803           socket_print, client_socket_encode, client_socket_decode},
1804 #endif
1805
1806 #ifdef WITH_DETAIL
1807         /* detail */
1808         { detail_parse, detail_free,
1809           detail_recv, detail_send,
1810           detail_print, detail_encode, detail_decode },
1811 #endif
1812
1813 #ifdef WITH_VMPS
1814         /* vlan query protocol */
1815         { common_socket_parse, NULL,
1816           vqp_socket_recv, vqp_socket_send,
1817           socket_print, vqp_socket_encode, vqp_socket_decode },
1818 #endif
1819
1820 #ifdef WITH_DHCP
1821         /* dhcp query protocol */
1822         { dhcp_socket_parse, NULL,
1823           dhcp_socket_recv, dhcp_socket_send,
1824           socket_print, dhcp_socket_encode, dhcp_socket_decode },
1825 #endif
1826
1827 #ifdef WITH_COMMAND_SOCKET
1828         /* TCP command socket */
1829         { command_socket_parse, NULL,
1830           command_domain_accept, command_domain_send,
1831           command_socket_print, command_socket_encode, command_socket_decode },
1832 #endif
1833
1834 #ifdef WITH_COA
1835         /* Change of Authorization */
1836         { common_socket_parse, NULL,
1837           coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1838           socket_print, client_socket_encode, client_socket_decode },
1839 #endif
1840
1841 };
1842
1843
1844
1845 /*
1846  *      Binds a listener to a socket.
1847  */
1848 static int listen_bind(rad_listen_t *this)
1849 {
1850         int rcode;
1851         struct sockaddr_storage salocal;
1852         socklen_t       salen;
1853         listen_socket_t *sock = this->data;
1854 #ifndef WITH_TCP
1855 #define proto_for_port "udp"
1856 #define sock_type SOCK_DGRAM
1857 #else
1858         const char *proto_for_port = "udp";
1859         int sock_type = SOCK_DGRAM;
1860         
1861         if (sock->proto == IPPROTO_TCP) {
1862 #ifdef WITH_VMPS
1863                 if (this->type == RAD_LISTEN_VQP) {
1864                         radlog(L_ERR, "VQP does not support TCP transport");
1865                         return -1;
1866                 }
1867 #endif
1868
1869                 proto_for_port = "tcp";
1870                 sock_type = SOCK_STREAM;        
1871         }
1872 #endif
1873
1874         /*
1875          *      If the port is zero, then it means the appropriate
1876          *      thing from /etc/services.
1877          */
1878         if (sock->my_port == 0) {
1879                 struct servent  *svp;
1880
1881                 switch (this->type) {
1882                 case RAD_LISTEN_AUTH:
1883                         svp = getservbyname ("radius", proto_for_port);
1884                         if (svp != NULL) {
1885                                 sock->my_port = ntohs(svp->s_port);
1886                         } else {
1887                                 sock->my_port = PW_AUTH_UDP_PORT;
1888                         }
1889                         break;
1890
1891 #ifdef WITH_ACCOUNTING
1892                 case RAD_LISTEN_ACCT:
1893                         svp = getservbyname ("radacct", proto_for_port);
1894                         if (svp != NULL) {
1895                                 sock->my_port = ntohs(svp->s_port);
1896                         } else {
1897                                 sock->my_port = PW_ACCT_UDP_PORT;
1898                         }
1899                         break;
1900 #endif
1901
1902 #ifdef WITH_PROXY
1903                 case RAD_LISTEN_PROXY:
1904                         /* leave it at zero */
1905                         break;
1906 #endif
1907
1908 #ifdef WITH_VMPS
1909                 case RAD_LISTEN_VQP:
1910                         sock->my_port = 1589;
1911                         break;
1912 #endif
1913
1914 #ifdef WITH_COA
1915                 case RAD_LISTEN_COA:
1916                         svp = getservbyname ("radius-dynauth", "udp");
1917                         if (svp != NULL) {
1918                                 sock->port = ntohs(svp->s_port);
1919                         } else {
1920                                 sock->port = PW_COA_UDP_PORT;
1921                         }
1922                         break;
1923 #endif
1924
1925                 default:
1926                         radlog(L_ERR, "ERROR: Non-fatal internal sanity check failed in bind.");
1927                         return -1;
1928                 }
1929         }
1930
1931         /*
1932          *      Copy fr_socket() here, as we may need to bind to a device.
1933          */
1934         this->fd = socket(sock->my_ipaddr.af, sock_type, 0);
1935         if (this->fd < 0) {
1936                 radlog(L_ERR, "Failed opening socket: %s", strerror(errno));
1937                 return -1;
1938         }
1939                 
1940         /*
1941          *      Bind to a device BEFORE touching IP addresses.
1942          */
1943         if (sock->interface) {
1944 #ifdef SO_BINDTODEVICE
1945                 struct ifreq ifreq;
1946                 strcpy(ifreq.ifr_name, sock->interface);
1947
1948                 fr_suid_up();
1949                 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
1950                                    (char *)&ifreq, sizeof(ifreq));
1951                 fr_suid_down();
1952                 if (rcode < 0) {
1953                         close(this->fd);
1954                         radlog(L_ERR, "Failed binding to interface %s: %s",
1955                                sock->interface, strerror(errno));
1956                         return -1;
1957                 } /* else it worked. */
1958 #else
1959 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1960 #ifdef HAVE_NET_IF_H
1961                 /*
1962                  *      Odds are that any system supporting "bind to
1963                  *      device" also supports IPv6, so this next bit
1964                  *      isn't necessary.  But it's here for
1965                  *      completeness.
1966                  *
1967                  *      If we're doing IPv6, and the scope hasn't yet
1968                  *      been defined, set the scope to the scope of
1969                  *      the interface.
1970                  */
1971                 if (sock->ipaddr.af == AF_INET6) {
1972                         if (sock->ipaddr.scope == 0) {
1973                                 sock->ipaddr.scope = if_nametoindex(sock->interface);
1974                                 if (sock->ipaddr.scope == 0) {
1975                                         close(this->fd);
1976                                         radlog(L_ERR, "Failed finding interface %s: %s",
1977                                                sock->interface, strerror(errno));
1978                                         return -1;
1979                                 }
1980                         } /* else scope was defined: we're OK. */
1981                 } else
1982 #endif
1983 #endif
1984                                 /*
1985                                  *      IPv4: no link local addresses,
1986                                  *      and no bind to device.
1987                                  */
1988                 {
1989                         close(this->fd);
1990                         radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
1991                         return -1;
1992                 }
1993 #endif
1994         }
1995
1996 #ifdef WITH_TCP
1997         if (sock->proto == IPPROTO_TCP) {
1998                 int on = 1;
1999
2000                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2001                         close(this->fd);
2002                         radlog(L_ERR, "Failed to reuse address: %s", strerror(errno));
2003                         return -1;
2004                 }
2005         }
2006 #endif
2007
2008 #if defined(WITH_TCP) && defined(WITH_UDPFROMTO)
2009         else                    /* UDP sockets get UDPfromto */
2010 #endif
2011
2012 #ifdef WITH_UDPFROMTO
2013         /*
2014          *      Initialize udpfromto for all sockets.
2015          */
2016         if (udpfromto_init(this->fd) != 0) {
2017                 close(this->fd);
2018                 return -1;
2019         }
2020 #endif
2021
2022         /*
2023          *      Set up sockaddr stuff.
2024          */
2025         if (!fr_ipaddr2sockaddr(&sock->my_ipaddr, sock->my_port, &salocal, &salen)) {
2026                 close(this->fd);
2027                 return -1;
2028         }
2029                 
2030 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2031         if (sock->my_ipaddr.af == AF_INET6) {
2032                 /*
2033                  *      Listening on '::' does NOT get you IPv4 to
2034                  *      IPv6 mapping.  You've got to listen on an IPv4
2035                  *      address, too.  This makes the rest of the server
2036                  *      design a little simpler.
2037                  */
2038 #ifdef IPV6_V6ONLY
2039                 
2040                 if (IN6_IS_ADDR_UNSPECIFIED(&sock->my_ipaddr.ipaddr.ip6addr)) {
2041                         int on = 1;
2042                         
2043                         setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
2044                                    (char *)&on, sizeof(on));
2045                 }
2046 #endif /* IPV6_V6ONLY */
2047         }
2048 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
2049
2050         if (sock->my_ipaddr.af == AF_INET) {
2051                 UNUSED int flag;
2052                 
2053 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
2054                 /*
2055                  *      Disable PMTU discovery.  On Linux, this
2056                  *      also makes sure that the "don't fragment"
2057                  *      flag is zero.
2058                  */
2059                 flag = IP_PMTUDISC_DONT;
2060                 setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
2061                            &flag, sizeof(flag));
2062 #endif
2063
2064 #if defined(IP_DONTFRAG)
2065                 /*
2066                  *      Ensure that the "don't fragment" flag is zero.
2067                  */
2068                 flag = 0;
2069                 setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
2070                            &flag, sizeof(flag));
2071 #endif
2072         }
2073
2074 #ifdef WITH_DHCP
2075 #ifdef SO_BROADCAST
2076         if (sock->broadcast) {
2077                 int on = 1;
2078                 
2079                 if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
2080                         radlog(L_ERR, "Can't set broadcast option: %s\n",
2081                                strerror(errno));
2082                         return -1;
2083                 }
2084         }
2085 #endif
2086 #endif
2087
2088         /*
2089          *      May be binding to priviledged ports.
2090          */
2091         if (sock->my_port != 0) {
2092 #ifdef SO_REUSEADDR
2093                 int on = 1;
2094
2095                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2096                         radlog(L_ERR, "Can't set re-use address option: %s\n",
2097                                strerror(errno));
2098                         return -1;
2099                 }
2100 #endif
2101
2102                 fr_suid_up();
2103                 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
2104                 fr_suid_down();
2105                 if (rcode < 0) {
2106                         char buffer[256];
2107                         close(this->fd);
2108                         
2109                         this->print(this, buffer, sizeof(buffer));
2110                         radlog(L_ERR, "Failed binding to %s: %s\n",
2111                                buffer, strerror(errno));
2112                         return -1;
2113                 }
2114         
2115                 /*
2116                  *      FreeBSD jail issues.  We bind to 0.0.0.0, but the
2117                  *      kernel instead binds us to a 1.2.3.4.  If this
2118                  *      happens, notice, and remember our real IP.
2119                  */
2120                 {
2121                         struct sockaddr_storage src;
2122                         socklen_t               sizeof_src = sizeof(src);
2123                         
2124                         memset(&src, 0, sizeof_src);
2125                         if (getsockname(this->fd, (struct sockaddr *) &src,
2126                                         &sizeof_src) < 0) {
2127                                 radlog(L_ERR, "Failed getting socket name: %s",
2128                                        strerror(errno));
2129                                 return -1;
2130                         }
2131                         
2132                         if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2133                                                 &sock->my_ipaddr, &sock->my_port)) {
2134                                 radlog(L_ERR, "Socket has unsupported address family");
2135                                 return -1;
2136                         }
2137                 }
2138         }
2139
2140 #ifdef WITH_TCP
2141         if (sock->proto == IPPROTO_TCP) {
2142                 if (listen(this->fd, 8) < 0) {
2143                         close(this->fd);
2144                         radlog(L_ERR, "Failed in listen(): %s", strerror(errno));
2145                         return -1;
2146                 }
2147         } else
2148 #endif
2149
2150           if (fr_nonblock(this->fd) < 0) {
2151                   close(this->fd);
2152                   radlog(L_ERR, "Failed setting non-blocking on socket: %s",
2153                          strerror(errno));
2154                   return -1;
2155           }
2156
2157         /*
2158          *      Mostly for proxy sockets.
2159          */
2160         sock->other_ipaddr.af = sock->my_ipaddr.af;
2161
2162 /*
2163  *      Don't screw up other people.
2164  */
2165 #undef proto_for_port
2166 #undef sock_type
2167
2168         return 0;
2169 }
2170
2171
2172 /*
2173  *      Allocate & initialize a new listener.
2174  */
2175 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
2176 {
2177         rad_listen_t *this;
2178
2179         this = rad_malloc(sizeof(*this));
2180         memset(this, 0, sizeof(*this));
2181
2182         this->type = type;
2183         this->recv = master_listen[this->type].recv;
2184         this->send = master_listen[this->type].send;
2185         this->print = master_listen[this->type].print;
2186         this->encode = master_listen[this->type].encode;
2187         this->decode = master_listen[this->type].decode;
2188
2189         switch (type) {
2190 #ifdef WITH_STATS
2191         case RAD_LISTEN_NONE:
2192 #endif
2193         case RAD_LISTEN_AUTH:
2194 #ifdef WITH_ACCOUNTING
2195         case RAD_LISTEN_ACCT:
2196 #endif
2197 #ifdef WITH_PROXY
2198         case RAD_LISTEN_PROXY:
2199 #endif
2200 #ifdef WITH_VMPS
2201         case RAD_LISTEN_VQP:
2202 #endif
2203 #ifdef WITH_COA
2204         case RAD_LISTEN_COA:
2205 #endif
2206                 this->data = rad_malloc(sizeof(listen_socket_t));
2207                 memset(this->data, 0, sizeof(listen_socket_t));
2208                 break;
2209
2210 #ifdef WITH_DHCP
2211         case RAD_LISTEN_DHCP:
2212                 this->data = rad_malloc(sizeof(dhcp_socket_t));
2213                 memset(this->data, 0, sizeof(dhcp_socket_t));
2214                 break;
2215 #endif
2216
2217 #ifdef WITH_DETAIL
2218         case RAD_LISTEN_DETAIL:
2219                 this->data = NULL;
2220                 break;
2221 #endif
2222
2223 #ifdef WITH_COMMAND_SOCKET
2224         case RAD_LISTEN_COMMAND:
2225                 this->data = rad_malloc(sizeof(fr_command_socket_t));
2226                 memset(this->data, 0, sizeof(fr_command_socket_t));
2227                 break;
2228 #endif
2229
2230         default:
2231                 rad_assert("Unsupported option!" == NULL);
2232                 break;
2233         }
2234
2235         return this;
2236 }
2237
2238 #ifdef WITH_PROXY
2239 /*
2240  *      Externally visible function for creating a new proxy LISTENER.
2241  *
2242  *      Not thread-safe, but all calls to it are protected by the
2243  *      proxy mutex in event.c
2244  */
2245 int proxy_new_listener(home_server *home, int src_port)
2246 {
2247         rad_listen_t *this;
2248         listen_socket_t *sock;
2249
2250         if (!home) return 0;
2251
2252         if ((home->max_connections > 0) &&
2253             (home->num_connections >= home->max_connections)) {
2254                 DEBUG("WARNING: Home server has too many open connections (%d)",
2255                       home->max_connections);
2256                 return 0;
2257         }
2258
2259         this = listen_alloc(RAD_LISTEN_PROXY);
2260
2261         sock = this->data;
2262         sock->other_ipaddr = home->ipaddr;
2263         sock->other_port = home->port;
2264         sock->home = home;
2265
2266         sock->my_ipaddr = home->src_ipaddr;
2267         sock->my_port = src_port;
2268         sock->proto = home->proto;
2269
2270 #ifdef WITH_TCP
2271         sock->last_packet = time(NULL);
2272
2273         if (home->proto == IPPROTO_TCP) {
2274                 this->recv = proxy_socket_tcp_recv;
2275
2276                 /*
2277                  *      FIXME: connect() is blocking!
2278                  *      We do this with the proxy mutex locked, which may
2279                  *      cause large delays!
2280                  *
2281                  *      http://www.developerweb.net/forum/showthread.php?p=13486
2282                  */
2283                 this->fd = fr_tcp_client_socket(&home->src_ipaddr,
2284                                                 &home->ipaddr, home->port);
2285         } else
2286 #endif
2287                 this->fd = fr_socket(&home->src_ipaddr, src_port);
2288
2289         if (this->fd < 0) {
2290                 DEBUG("Failed opening client socket: %s", fr_strerror());
2291                 listen_free(&this);
2292                 return 0;
2293         }
2294
2295         /*
2296          *      Figure out which port we were bound to.
2297          */
2298         if (sock->my_port == 0) {
2299                 struct sockaddr_storage src;
2300                 socklen_t               sizeof_src = sizeof(src);
2301                 
2302                 memset(&src, 0, sizeof_src);
2303                 if (getsockname(this->fd, (struct sockaddr *) &src,
2304                                 &sizeof_src) < 0) {
2305                         radlog(L_ERR, "Failed getting socket name: %s",
2306                                strerror(errno));
2307                         listen_free(&this);
2308                         return 0;
2309                 }
2310                 
2311                 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2312                                         &sock->my_ipaddr, &sock->my_port)) {
2313                         radlog(L_ERR, "Socket has unsupported address family");
2314                         listen_free(&this);
2315                         return 0;
2316                 }
2317         }
2318
2319         /*
2320          *      Tell the event loop that we have a new FD
2321          */
2322         if (!event_new_fd(this)) {
2323                 listen_free(&this);
2324                 return 0;
2325         }
2326         
2327         return 1;
2328 }
2329 #endif
2330
2331
2332 static const FR_NAME_NUMBER listen_compare[] = {
2333 #ifdef WITH_STATS
2334         { "status",     RAD_LISTEN_NONE },
2335 #endif
2336         { "auth",       RAD_LISTEN_AUTH },
2337 #ifdef WITH_ACCOUNTING
2338         { "acct",       RAD_LISTEN_ACCT },
2339 #endif
2340 #ifdef WITH_DETAIL
2341         { "detail",     RAD_LISTEN_DETAIL },
2342 #endif
2343 #ifdef WITH_PROXY
2344         { "proxy",      RAD_LISTEN_PROXY },
2345 #endif
2346 #ifdef WITH_VMPS
2347         { "vmps",       RAD_LISTEN_VQP },
2348 #endif
2349 #ifdef WITH_DHCP
2350         { "dhcp",       RAD_LISTEN_DHCP },
2351 #endif
2352 #ifdef WITH_COMMAND_SOCKET
2353         { "control",    RAD_LISTEN_COMMAND },
2354 #endif
2355 #ifdef WITH_COA
2356         { "coa",        RAD_LISTEN_COA },
2357 #endif
2358         { NULL, 0 },
2359 };
2360
2361
2362 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
2363 {
2364         int             type, rcode;
2365         char            *listen_type;
2366         rad_listen_t    *this;
2367
2368         listen_type = NULL;
2369         
2370         cf_log_info(cs, "listen {");
2371
2372         rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
2373                               &listen_type, "");
2374         if (rcode < 0) return NULL;
2375         if (rcode == 1) {
2376                 free(listen_type);
2377                 cf_log_err(cf_sectiontoitem(cs),
2378                            "No type specified in listen section");
2379                 return NULL;
2380         }
2381
2382         type = fr_str2int(listen_compare, listen_type, -1);
2383         if (type < 0) {
2384                 cf_log_err(cf_sectiontoitem(cs),
2385                            "Invalid type \"%s\" in listen section.",
2386                            listen_type);
2387                 free(listen_type);
2388                 return NULL;
2389         }
2390         free(listen_type);
2391
2392         /*
2393          *      Allow listen sections in the default config to
2394          *      refer to a server.
2395          */
2396         if (!server) {
2397                 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
2398                                       &server, NULL);
2399                 if (rcode == 1) { /* compatiblity with 2.0-pre */
2400                         rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
2401                                               &server, NULL);
2402                 }
2403                 if (rcode < 0) return NULL;
2404         }
2405
2406 #ifdef WITH_PROXY
2407         /*
2408          *      We were passed a virtual server, so the caller is
2409          *      defining a proxy listener inside of a virtual server.
2410          *      This isn't allowed right now.
2411          */
2412         else if (type == RAD_LISTEN_PROXY) {
2413                 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2414                 return NULL;
2415         }
2416 #endif
2417
2418         /*
2419          *      Set up cross-type data.
2420          */
2421         this = listen_alloc(type);
2422         this->server = server;
2423         this->fd = -1;
2424
2425         /*
2426          *      Call per-type parser.
2427          */
2428         if (master_listen[type].parse(cs, this) < 0) {
2429                 listen_free(&this);
2430                 return NULL;
2431         }
2432
2433         cf_log_info(cs, "}");
2434
2435         return this;
2436 }
2437
2438 /*
2439  *      Generate a list of listeners.  Takes an input list of
2440  *      listeners, too, so we don't close sockets with waiting packets.
2441  */
2442 int listen_init(CONF_SECTION *config, rad_listen_t **head)
2443 {
2444         int             override = FALSE;
2445         int             rcode;
2446         CONF_SECTION    *cs = NULL;
2447         rad_listen_t    **last;
2448         rad_listen_t    *this;
2449         fr_ipaddr_t     server_ipaddr;
2450         int             auth_port = 0;
2451 #ifdef WITH_PROXY
2452         int             defined_proxy = 0;
2453 #endif
2454
2455         /*
2456          *      We shouldn't be called with a pre-existing list.
2457          */
2458         rad_assert(head && (*head == NULL));
2459
2460         last = head;
2461         server_ipaddr.af = AF_UNSPEC;
2462
2463         /*
2464          *      If the port is specified on the command-line,
2465          *      it over-rides the configuration file.
2466          *
2467          *      FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
2468          */
2469         if (mainconfig.port >= 0) auth_port = mainconfig.port;
2470
2471         /*
2472          *      If the IP address was configured on the command-line,
2473          *      use that as the "bind_address"
2474          */
2475         if (mainconfig.myip.af != AF_UNSPEC) {
2476                 memcpy(&server_ipaddr, &mainconfig.myip,
2477                        sizeof(server_ipaddr));
2478                 override = TRUE;
2479                 goto bind_it;
2480         }
2481
2482         /*
2483          *      Else look for bind_address and/or listen sections.
2484          */
2485         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
2486         rcode = cf_item_parse(config, "bind_address",
2487                               PW_TYPE_IPADDR,
2488                               &server_ipaddr.ipaddr.ip4addr, NULL);
2489         if (rcode < 0) return -1; /* error parsing it */
2490
2491         if (rcode == 0) { /* successfully parsed IPv4 */
2492                 listen_socket_t *sock;
2493                 server_ipaddr.af = AF_INET;
2494
2495                 radlog(L_INFO, "WARNING: The directive 'bind_address' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
2496
2497         bind_it:
2498 #ifdef WITH_VMPS
2499                 if (strcmp(progname, "vmpsd") == 0) {
2500                         this = listen_alloc(RAD_LISTEN_VQP);
2501                         if (!auth_port) auth_port = 1589;
2502                 } else
2503 #endif
2504                         this = listen_alloc(RAD_LISTEN_AUTH);
2505
2506                 sock = this->data;
2507
2508                 sock->my_ipaddr = server_ipaddr;
2509                 sock->my_port = auth_port;
2510
2511                 sock->clients = clients_parse_section(config);
2512                 if (!sock->clients) {
2513                         cf_log_err(cf_sectiontoitem(config),
2514                                    "Failed to find any clients for this listen section");
2515                         listen_free(&this);
2516                         return -1;
2517                 }
2518
2519                 if (listen_bind(this) < 0) {
2520                         listen_free(head);
2521                         radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->my_port);
2522                         listen_free(&this);
2523                         return -1;
2524                 }
2525                 auth_port = sock->my_port;      /* may have been updated in listen_bind */
2526                 if (override) {
2527                         cs = cf_section_sub_find_name2(config, "server",
2528                                                        mainconfig.name);
2529                         if (cs) this->server = mainconfig.name;
2530                 }
2531
2532                 *last = this;
2533                 last = &(this->next);
2534
2535 #ifdef WITH_VMPS
2536                 /*
2537                  *      No acct for vmpsd
2538                  */
2539                 if (strcmp(progname, "vmpsd") == 0) goto add_sockets;
2540 #endif
2541
2542 #ifdef WITH_ACCOUNTING
2543                 /*
2544                  *      Open Accounting Socket.
2545                  *
2546                  *      If we haven't already gotten acct_port from
2547                  *      /etc/services, then make it auth_port + 1.
2548                  */
2549                 this = listen_alloc(RAD_LISTEN_ACCT);
2550                 sock = this->data;
2551
2552                 /*
2553                  *      Create the accounting socket.
2554                  *
2555                  *      The accounting port is always the
2556                  *      authentication port + 1
2557                  */
2558                 sock->my_ipaddr = server_ipaddr;
2559                 sock->my_port = auth_port + 1;
2560
2561                 sock->clients = clients_parse_section(config);
2562                 if (!sock->clients) {
2563                         cf_log_err(cf_sectiontoitem(config),
2564                                    "Failed to find any clients for this listen section");
2565                         return -1;
2566                 }
2567
2568                 if (listen_bind(this) < 0) {
2569                         listen_free(&this);
2570                         listen_free(head);
2571                         radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->my_port);
2572                         return -1;
2573                 }
2574
2575                 if (override) {
2576                         cs = cf_section_sub_find_name2(config, "server",
2577                                                        mainconfig.name);
2578                         if (cs) this->server = mainconfig.name;
2579                 }
2580
2581                 *last = this;
2582                 last = &(this->next);
2583 #endif
2584         } else if (mainconfig.port > 0) { /* no bind address, but a port */
2585                 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2586                        mainconfig.port);
2587                 return -1;
2588         }
2589
2590         /*
2591          *      They specified an IP on the command-line, ignore
2592          *      all listen sections except the one in '-n'.
2593          */
2594         if (mainconfig.myip.af != AF_UNSPEC) {
2595                 CONF_SECTION *subcs;
2596                 const char *name2 = cf_section_name2(cs);
2597
2598                 cs = cf_section_sub_find_name2(config, "server",
2599                                                mainconfig.name);
2600                 if (!cs) goto add_sockets;
2601
2602                 /*
2603                  *      Should really abstract this code...
2604                  */
2605                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2606                      subcs != NULL;
2607                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2608                         this = listen_parse(subcs, name2);
2609                         if (!this) {
2610                                 listen_free(head);
2611                                 return -1;
2612                         }
2613
2614                         *last = this;
2615                         last = &(this->next);
2616                 } /* loop over "listen" directives in server <foo> */
2617
2618                 goto add_sockets;
2619         }
2620
2621         /*
2622          *      Walk through the "listen" sections, if they exist.
2623          */
2624         for (cs = cf_subsection_find_next(config, NULL, "listen");
2625              cs != NULL;
2626              cs = cf_subsection_find_next(config, cs, "listen")) {
2627                 this = listen_parse(cs, NULL);
2628                 if (!this) {
2629                         listen_free(head);
2630                         return -1;
2631                 }
2632
2633                 *last = this;
2634                 last = &(this->next);
2635         }
2636
2637         /*
2638          *      Check virtual servers for "listen" sections, too.
2639          *
2640          *      FIXME: Move to virtual server init?
2641          */
2642         for (cs = cf_subsection_find_next(config, NULL, "server");
2643              cs != NULL;
2644              cs = cf_subsection_find_next(config, cs, "server")) {
2645                 CONF_SECTION *subcs;
2646                 const char *name2 = cf_section_name2(cs);
2647                 
2648                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2649                      subcs != NULL;
2650                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2651                         this = listen_parse(subcs, name2);
2652                         if (!this) {
2653                                 listen_free(head);
2654                                 return -1;
2655                         }
2656                         
2657                         *last = this;
2658                         last = &(this->next);
2659                 } /* loop over "listen" directives in virtual servers */
2660         } /* loop over virtual servers */
2661
2662 add_sockets:
2663         /*
2664          *      Print out which sockets we're listening on, and
2665          *      add them to the event list.
2666          */
2667         for (this = *head; this != NULL; this = this->next) {
2668 #ifdef WITH_PROXY
2669                 if (this->type == RAD_LISTEN_PROXY) {
2670                         defined_proxy = 1;
2671                 }
2672
2673 #endif
2674                 event_new_fd(this);
2675         }
2676
2677         /*
2678          *      If we're proxying requests, open the proxy FD.
2679          *      Otherwise, don't do anything.
2680          */
2681 #ifdef WITH_PROXY
2682         if ((mainconfig.proxy_requests == TRUE) &&
2683             (*head != NULL) && !defined_proxy) {
2684                 listen_socket_t *sock = NULL;
2685                 int             port = 0;
2686                 home_server     home;
2687
2688                 memset(&home, 0, sizeof(home));
2689
2690                 /*
2691                  *      
2692                  */
2693                 home.proto = IPPROTO_UDP;
2694                 home.src_ipaddr = server_ipaddr;
2695
2696                 /*
2697                  *      Find the first authentication port,
2698                  *      and use it
2699                  */
2700                 for (this = *head; this != NULL; this = this->next) {
2701                         if (this->type == RAD_LISTEN_AUTH) {
2702                                 sock = this->data;
2703                                 if (home.src_ipaddr.af == AF_UNSPEC) {
2704                                         home.src_ipaddr = sock->my_ipaddr;
2705                                 }
2706                                 port = sock->my_port + 2;
2707                                 break;
2708                         }
2709 #ifdef WITH_ACCT
2710                         if (this->type == RAD_LISTEN_ACCT) {
2711                                 sock = this->data;
2712                                 if (home.src_ipaddr.af == AF_UNSPEC) {
2713                                         home.src_ipaddr = sock->my_ipaddr;
2714                                 }
2715                                 port = sock->my_port + 1;
2716                                 break;
2717                         }
2718 #endif
2719                 }
2720
2721                 /*
2722                  *      Address is still unspecified, use IPv4.
2723                  */
2724                 if (home.src_ipaddr.af == AF_UNSPEC) {
2725                         home.src_ipaddr.af = AF_INET;
2726                         /* everything else is already set to zero */
2727                 }
2728
2729                 home.ipaddr.af = home.src_ipaddr.af;
2730                 /* everything else is already set to zero */
2731
2732                 if (!proxy_new_listener(&home, port)) {
2733                         listen_free(head);
2734                         return -1;
2735                 }
2736         }
2737 #endif
2738
2739         /*
2740          *      Haven't defined any sockets.  Die.
2741          */
2742         if (!*head) return -1;
2743
2744
2745         return 0;
2746 }
2747
2748 /*
2749  *      Free a linked list of listeners;
2750  */
2751 void listen_free(rad_listen_t **head)
2752 {
2753         rad_listen_t *this;
2754
2755         if (!head || !*head) return;
2756
2757         this = *head;
2758         while (this) {
2759                 rad_listen_t *next = this->next;
2760
2761                 /*
2762                  *      Other code may have eaten the FD.
2763                  */
2764                 if (this->fd >= 0) close(this->fd);
2765
2766                 if (master_listen[this->type].free) {
2767                         master_listen[this->type].free(this);
2768                 }
2769
2770 #ifdef WITH_TCP
2771                 if ((this->type == RAD_LISTEN_AUTH) ||
2772 #ifdef WITH_ACCT
2773                     (this->type == RAD_LISTEN_ACCT) ||
2774 #endif
2775 #ifdef WITH_PROXY
2776                     (this->type == RAD_LISTEN_PROXY)
2777 #endif
2778                         ) {
2779                         listen_socket_t *sock = this->data;
2780                         rad_free(&sock->packet);
2781                 }
2782 #endif
2783
2784                 free(this->data);
2785                 free(this);
2786
2787                 this = next;
2788         }
2789
2790         *head = NULL;
2791 }
2792
2793 #ifdef WITH_STATS
2794 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
2795                                           int port)
2796 {
2797         rad_listen_t *this;
2798
2799         for (this = mainconfig.listen; this != NULL; this = this->next) {
2800                 listen_socket_t *sock;
2801
2802                 if ((this->type != RAD_LISTEN_AUTH) &&
2803                     (this->type != RAD_LISTEN_ACCT)) continue;
2804                 
2805                 sock = this->data;
2806
2807                 if ((sock->my_port == port) &&
2808                     (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) == 0)) {
2809                         return sock->clients;
2810                 }
2811         }
2812
2813         return NULL;
2814 }
2815 #endif
2816
2817 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port)
2818 {
2819         rad_listen_t *this;
2820
2821         for (this = mainconfig.listen; this != NULL; this = this->next) {
2822                 listen_socket_t *sock;
2823
2824                 /*
2825                  *      FIXME: For TCP, ignore the *secondary*
2826                  *      listeners associated with the main socket.
2827                  */
2828                 if ((this->type != RAD_LISTEN_AUTH) &&
2829                     (this->type != RAD_LISTEN_ACCT)) continue;
2830                 
2831                 sock = this->data;
2832
2833                 if ((sock->my_port == port) &&
2834                     (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) == 0)) {
2835                         return this;
2836                 }
2837
2838                 if ((sock->my_port == port) &&
2839                     ((sock->my_ipaddr.af == AF_INET) &&
2840                      (sock->my_ipaddr.ipaddr.ip4addr.s_addr == INADDR_ANY))) {
2841                         return this;
2842                 }
2843
2844 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2845                 if ((sock->my_port == port) &&
2846                     (sock->my_ipaddr.af == AF_INET6) &&
2847                     (IN6_IS_ADDR_UNSPECIFIED(&sock->my_ipaddr.ipaddr.ip6addr))) {
2848                         return this;
2849                 }
2850 #endif
2851         }
2852
2853         return NULL;
2854 }