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