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