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