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