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