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