2 * listen.c Handle socket stuff
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.
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.
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
20 * Copyright 2005,2006 The FreeRADIUS server project
21 * Copyright 2005 Alan DeKok <aland@ox.org>
24 #include <freeradius-devel/ident.h>
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>
33 #include <freeradius-devel/vmps.h>
34 #include <freeradius-devel/detail.h>
37 #include <freeradius-devel/udpfromto.h>
40 #ifdef HAVE_SYS_RESOURCE_H
41 #include <sys/resource.h>
54 * We'll use this below.
56 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
57 typedef void (*rad_listen_free_t)(rad_listen_t *);
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;
69 typedef struct listen_socket_t {
75 const char *interface;
76 RADCLIENT_LIST *clients;
79 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
82 * Find a per-socket client.
84 RADCLIENT *client_listener_find(const rad_listen_t *listener,
85 const fr_ipaddr_t *ipaddr, int src_port)
87 #ifdef WITH_DYNAMIC_CLIENTS
94 RADCLIENT_LIST *clients;
96 rad_assert(listener != NULL);
97 rad_assert(ipaddr != NULL);
99 clients = ((listen_socket_t *)listener->data)->clients;
102 * This HAS to have been initialized previously.
104 rad_assert(clients != NULL);
106 client = client_find(clients, ipaddr);
108 static time_t last_printed = 0;
109 char name[256], buffer[128];
111 #ifdef WITH_DYNAMIC_CLIENTS
112 unknown: /* used only for dynamic clients */
116 * DoS attack quenching, but only in debug mode.
117 * If they're running in debug mode, show them
120 if (debug_flag == 0) {
122 if (last_printed == now) return NULL;
127 listener->print(listener, name, sizeof(name));
129 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d",
130 name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
131 buffer, sizeof(buffer)),
136 #ifndef WITH_DYNAMIC_CLIENTS
137 return client; /* return the found client. */
141 * No server defined, and it's not dynamic. Return it.
143 if (!client->client_server && !client->dynamic) return client;
148 * It's a dynamically generated client, check it.
150 if (client->dynamic && (src_port != 0)) {
152 * Lives forever. Return it.
154 if (client->lifetime == 0) return client;
157 * Rate-limit the deletion of known clients.
158 * This makes them last a little longer, but
159 * prevents the server from melting down if (say)
160 * 10k clients all expire at once.
162 if (now == client->last_new_client) return client;
165 * It's not dead yet. Return it.
167 if ((client->created + client->lifetime) > now) return client;
170 * This really puts them onto a queue for later
173 client_delete(clients, client);
176 * Go find the enclosing network again.
178 client = client_find(clients, ipaddr);
183 if (!client) goto unknown;
184 if (!client->client_server) goto unknown;
187 * At this point, 'client' is the enclosing
188 * network that configures where dynamic clients
191 rad_assert(client->dynamic == 0);
193 } else if (!client->dynamic && client->rate_limit) {
195 * The IP is unknown, so we've found an enclosing
196 * network. Enable DoS protection. We only
197 * allow one new client per second. Known
198 * clients aren't subject to this restriction.
200 if (now == client->last_new_client) goto unknown;
203 client->last_new_client = now;
205 request = request_alloc();
206 if (!request) goto unknown;
208 request->listener = listener;
209 request->client = client;
210 request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
211 if (!request->packet) { /* badly formed, etc */
212 request_free(&request);
215 request->reply = rad_alloc_reply(request->packet);
216 if (!request->reply) {
217 request_free(&request);
220 request->packet->timestamp = request->timestamp;
222 request->priority = listener->type;
223 request->server = client->client_server;
224 request->root = &mainconfig;
227 * Run a fake request through the given virtual server.
228 * Look for FreeRADIUS-Client-IP-Address
229 * FreeRADIUS-Client-Secret
232 * and create the RADCLIENT structure from that.
234 DEBUG("server %s {", request->server);
236 rcode = module_authorize(0, request);
238 DEBUG("} # server %s", request->server);
240 if (rcode != RLM_MODULE_OK) {
241 request_free(&request);
246 * If the client was updated by rlm_dynamic_clients,
247 * don't create the client from attribute-value pairs.
249 if (request->client == client) {
250 created = client_create(clients, request);
252 created = request->client;
255 * This frees the client if it isn't valid.
257 if (!client_validate(clients, client, created)) goto unknown;
259 request_free(&request);
261 if (!created) goto unknown;
267 static int listen_bind(rad_listen_t *this);
271 * Process and reply to a server-status request.
272 * Like rad_authenticate and rad_accounting this should
273 * live in it's own file but it's so small we don't bother.
275 static int rad_status_server(REQUEST *request)
277 int rcode = RLM_MODULE_OK;
280 switch (request->listener->type) {
282 case RAD_LISTEN_NONE:
284 case RAD_LISTEN_AUTH:
285 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
287 rcode = module_authorize(dval->value, request);
289 rcode = RLM_MODULE_OK;
294 case RLM_MODULE_UPDATED:
295 request->reply->code = PW_AUTHENTICATION_ACK;
298 case RLM_MODULE_FAIL:
299 case RLM_MODULE_HANDLED:
300 request->reply->code = 0; /* don't reply */
304 case RLM_MODULE_REJECT:
305 request->reply->code = PW_AUTHENTICATION_REJECT;
310 #ifdef WITH_ACCOUNTING
311 case RAD_LISTEN_ACCT:
312 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
314 rcode = module_accounting(dval->value, request);
316 rcode = RLM_MODULE_OK;
321 case RLM_MODULE_UPDATED:
322 request->reply->code = PW_ACCOUNTING_RESPONSE;
326 request->reply->code = 0; /* don't reply */
334 * This is a vendor extension. Suggested by Glen
335 * Zorn in IETF 72, and rejected by the rest of
336 * the WG. We like it, so it goes in here.
339 dval = dict_valbyname(PW_RECV_COA_TYPE, "Status-Server");
341 rcode = module_recv_coa(dval->value, request);
343 rcode = RLM_MODULE_OK;
348 case RLM_MODULE_UPDATED:
349 request->reply->code = PW_COA_ACK;
353 request->reply->code = 0; /* don't reply */
365 * Full statistics are available only on a statistics
368 if (request->listener->type == RAD_LISTEN_NONE) {
369 request_stats_reply(request);
377 static int socket_print(const rad_listen_t *this, char *buffer, size_t bufsize)
380 listen_socket_t *sock = this->data;
383 switch (this->type) {
385 case RAD_LISTEN_NONE: /* what a hack... */
390 case RAD_LISTEN_AUTH:
391 name = "authentication";
394 #ifdef WITH_ACCOUNTING
395 case RAD_LISTEN_ACCT:
401 case RAD_LISTEN_PROXY:
413 case RAD_LISTEN_DHCP:
429 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
430 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
434 if (sock->interface) {
435 ADDSTRING(" interface ");
436 ADDSTRING(sock->interface);
439 ADDSTRING(" address ");
441 if ((sock->ipaddr.af == AF_INET) &&
442 (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
443 strlcpy(buffer, "*", bufsize);
445 ip_ntoh(&sock->ipaddr, buffer, bufsize);
450 snprintf(buffer, bufsize, "%d", sock->port);
454 ADDSTRING(" as server ");
455 ADDSTRING(this->server);
464 extern int check_config; /* radiusd.c */
468 * Parse an authentication or accounting socket.
470 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
475 listen_socket_t *sock = this->data;
476 char *section_name = NULL;
477 CONF_SECTION *client_cs, *parentcs;
482 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
483 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
484 &ipaddr.ipaddr.ip4addr, NULL);
485 if (rcode < 0) return -1;
487 if (rcode == 0) { /* successfully parsed IPv4 */
490 } else { /* maybe IPv6? */
491 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
492 &ipaddr.ipaddr.ip6addr, NULL);
493 if (rcode < 0) return -1;
496 cf_log_err(cf_sectiontoitem(cs),
497 "No address specified in listen section");
500 ipaddr.af = AF_INET6;
503 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
505 if (rcode < 0) return -1;
507 if ((listen_port < 0) || (listen_port > 65535)) {
508 cf_log_err(cf_sectiontoitem(cs),
509 "Invalid value for \"port\"");
513 sock->ipaddr = ipaddr;
514 sock->port = listen_port;
517 if (home_server_find(&sock->ipaddr, sock->port)) {
520 DEBUG("ERROR: We have been asked to listen on %s port %d, which is also listed as a home server. This can create a proxy loop.",
521 ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
526 return 0; /* don't do anything */
530 * If we can bind to interfaces, do so,
533 if (cf_pair_find(cs, "interface")) {
535 CONF_PAIR *cp = cf_pair_find(cs, "interface");
537 rad_assert(cp != NULL);
538 value = cf_pair_value(cp);
540 cf_log_err(cf_sectiontoitem(cs),
541 "No interface name given");
544 sock->interface = value;
548 * And bind it to the port.
550 if (listen_bind(this) < 0) {
552 cf_log_err(cf_sectiontoitem(cs),
553 "Error binding to port for %s port %d",
554 ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
561 * Proxy sockets don't have clients.
563 if (this->type == RAD_LISTEN_PROXY) return 0;
567 * The more specific configurations are preferred to more
571 parentcs = cf_top_section(cs);
572 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
573 §ion_name, NULL);
574 if (rcode < 0) return -1; /* bad string */
577 * Explicit list given: use it.
579 client_cs = cf_section_sub_find_name2(parentcs,
583 client_cs = cf_section_find(section_name);
586 cf_log_err(cf_sectiontoitem(cs),
587 "Failed to find clients %s {...}",
593 } /* else there was no "clients = " entry. */
596 CONF_SECTION *server_cs;
598 server_cs = cf_section_sub_find_name2(parentcs,
602 * Found a "server foo" section. If there are clients
606 (cf_section_sub_find(server_cs, "client") != NULL)) {
607 client_cs = server_cs;
612 * Still nothing. Look for global clients.
614 if (!client_cs) client_cs = parentcs;
616 sock->clients = clients_parse_section(client_cs);
617 if (!sock->clients) {
618 cf_log_err(cf_sectiontoitem(cs),
619 "Failed to load clients for this listen section");
627 * Send an authentication response packet
629 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
631 rad_assert(request->listener == listener);
632 rad_assert(listener->send == auth_socket_send);
634 return rad_send(request->reply, request->packet,
635 request->client->secret);
639 #ifdef WITH_ACCOUNTING
641 * Send an accounting response packet (or not)
643 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
645 rad_assert(request->listener == listener);
646 rad_assert(listener->send == acct_socket_send);
649 * Accounting reject's are silently dropped.
651 * We do it here to avoid polluting the rest of the
652 * code with this knowledge
654 if (request->reply->code == 0) return 0;
656 return rad_send(request->reply, request->packet,
657 request->client->secret);
663 * Send a packet to a home server.
665 * FIXME: have different code for proxy auth & acct!
667 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
669 listen_socket_t *sock = listener->data;
671 rad_assert(request->proxy_listener == listener);
672 rad_assert(listener->send == proxy_socket_send);
674 request->proxy->src_ipaddr = sock->ipaddr;
675 request->proxy->src_port = sock->port;
677 return rad_send(request->proxy, request->packet,
678 request->home_server->secret);
684 * Check if an incoming request is "ok"
686 * It takes packets, not requests. It sees if the packet looks
687 * OK. If so, it does a number of sanity checks on it.
689 static int stats_socket_recv(rad_listen_t *listener,
690 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
694 RADIUS_PACKET *packet;
696 fr_ipaddr_t src_ipaddr;
698 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
699 if (rcode < 0) return 0;
701 RAD_STATS_TYPE_INC(listener, total_requests);
703 if (rcode < 20) { /* AUTH_HDR_LEN */
704 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
708 if ((client = client_listener_find(listener,
709 &src_ipaddr, src_port)) == NULL) {
710 rad_recv_discard(listener->fd);
711 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
716 * We only understand Status-Server on this socket.
718 if (code != PW_STATUS_SERVER) {
719 DEBUG("Ignoring packet code %d sent to Status-Server port",
721 rad_recv_discard(listener->fd);
722 RAD_STATS_TYPE_INC(listener, total_unknown_types);
723 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
728 * Now that we've sanity checked everything, receive the
731 packet = rad_recv(listener->fd, 1); /* require message authenticator */
733 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
734 DEBUG("%s", fr_strerror());
738 if (!received_request(listener, packet, prequest, client)) {
739 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
740 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
745 *pfun = rad_status_server;
752 * Check if an incoming request is "ok"
754 * It takes packets, not requests. It sees if the packet looks
755 * OK. If so, it does a number of sanity checks on it.
757 static int auth_socket_recv(rad_listen_t *listener,
758 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
762 RADIUS_PACKET *packet;
763 RAD_REQUEST_FUNP fun = NULL;
765 fr_ipaddr_t src_ipaddr;
767 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
768 if (rcode < 0) return 0;
770 RAD_STATS_TYPE_INC(listener, total_requests);
772 if (rcode < 20) { /* AUTH_HDR_LEN */
773 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
777 if ((client = client_listener_find(listener,
778 &src_ipaddr, src_port)) == NULL) {
779 rad_recv_discard(listener->fd);
780 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
785 * Some sanity checks, based on the packet code.
788 case PW_AUTHENTICATION_REQUEST:
789 RAD_STATS_CLIENT_INC(listener, client, total_requests);
790 fun = rad_authenticate;
793 case PW_STATUS_SERVER:
794 if (!mainconfig.status_server) {
795 rad_recv_discard(listener->fd);
796 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
797 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
798 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
801 fun = rad_status_server;
805 rad_recv_discard(listener->fd);
806 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
807 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
809 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
810 code, client->shortname, src_port);
813 } /* switch over packet types */
816 * Now that we've sanity checked everything, receive the
819 packet = rad_recv(listener->fd, client->message_authenticator);
821 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
822 DEBUG("%s", fr_strerror());
826 if (!received_request(listener, packet, prequest, client)) {
827 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
828 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
838 #ifdef WITH_ACCOUNTING
840 * Receive packets from an accounting socket
842 static int acct_socket_recv(rad_listen_t *listener,
843 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
847 RADIUS_PACKET *packet;
848 RAD_REQUEST_FUNP fun = NULL;
850 fr_ipaddr_t src_ipaddr;
852 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
853 if (rcode < 0) return 0;
855 RAD_STATS_TYPE_INC(listener, total_requests);
857 if (rcode < 20) { /* AUTH_HDR_LEN */
858 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
862 if ((client = client_listener_find(listener,
863 &src_ipaddr, src_port)) == NULL) {
864 rad_recv_discard(listener->fd);
865 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
870 * Some sanity checks, based on the packet code.
873 case PW_ACCOUNTING_REQUEST:
874 RAD_STATS_CLIENT_INC(listener, client, total_requests);
875 fun = rad_accounting;
878 case PW_STATUS_SERVER:
879 if (!mainconfig.status_server) {
880 rad_recv_discard(listener->fd);
881 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
882 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
884 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
887 fun = rad_status_server;
891 rad_recv_discard(listener->fd);
892 RAD_STATS_TYPE_INC(listener, total_unknown_types);
893 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
895 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
896 code, client->shortname, src_port);
898 } /* switch over packet types */
901 * Now that we've sanity checked everything, receive the
904 packet = rad_recv(listener->fd, 0);
906 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
907 radlog(L_ERR, "%s", fr_strerror());
912 * There can be no duplicate accounting packets.
914 if (!received_request(listener, packet, prequest, client)) {
915 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
916 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
929 * For now, all CoA requests are *only* originated, and not
930 * proxied. So all of the necessary work is done in the
931 * post-proxy section, which is automatically handled by event.c.
932 * As a result, we don't have to do anything here.
934 static int rad_coa_reply(REQUEST *request)
939 * Inform the user about RFC requirements.
941 s1 = pairfind(request->proxy->vps, PW_STATE);
943 s2 = pairfind(request->proxy_reply->vps, PW_STATE);
946 DEBUG("WARNING: Client was sent State in CoA, and did not respond with State.");
948 } else if ((s1->length != s2->length) ||
949 (memcmp(s1->vp_octets, s2->vp_octets,
951 DEBUG("WARNING: Client was sent State in CoA, and did not respond with the same State.");
955 return RLM_MODULE_OK;
959 * Receive a CoA packet.
961 static int rad_coa_recv(REQUEST *request)
963 int rcode = RLM_MODULE_OK;
968 * Get the correct response
970 switch (request->packet->code) {
976 case PW_DISCONNECT_REQUEST:
977 ack = PW_DISCONNECT_ACK;
978 nak = PW_DISCONNECT_NAK;
981 default: /* shouldn't happen */
982 return RLM_MODULE_FAIL;
986 #define WAS_PROXIED (request->proxy)
988 #define WAS_PROXIED (0)
993 * RFC 5176 Section 3.3. If we have a CoA-Request
994 * with Service-Type = Authorize-Only, it MUST
995 * have a State attribute in it.
997 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE);
998 if (request->packet->code == PW_COA_REQUEST) {
999 if (vp && (vp->vp_integer == 17)) {
1000 vp = pairfind(request->packet->vps, PW_STATE);
1001 if (!vp || (vp->length == 0)) {
1002 RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1003 request->reply->code = PW_COA_NAK;
1004 return RLM_MODULE_FAIL;
1009 * RFC 5176, Section 3.2.
1011 RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
1012 request->reply->code = PW_DISCONNECT_NAK;
1013 return RLM_MODULE_FAIL;
1016 rcode = module_recv_coa(0, request);
1018 case RLM_MODULE_FAIL:
1019 case RLM_MODULE_INVALID:
1020 case RLM_MODULE_REJECT:
1021 case RLM_MODULE_USERLOCK:
1023 request->reply->code = nak;
1026 case RLM_MODULE_HANDLED:
1029 case RLM_MODULE_NOOP:
1030 case RLM_MODULE_NOTFOUND:
1032 case RLM_MODULE_UPDATED:
1033 request->reply->code = ack;
1038 * Start the reply code with the proxy reply
1041 request->reply->code = request->proxy_reply->code;
1045 * Copy State from the request to the reply.
1046 * See RFC 5176 Section 3.3.
1048 vp = paircopy2(request->packet->vps, PW_STATE);
1049 if (vp) pairadd(&request->reply->vps, vp);
1052 * We may want to over-ride the reply.
1054 rcode = module_send_coa(0, request);
1057 * We need to send CoA-NAK back if Service-Type
1058 * is Authorize-Only. Rely on the user's policy
1059 * to do that. We're not a real NAS, so this
1060 * restriction doesn't (ahem) apply to us.
1062 case RLM_MODULE_FAIL:
1063 case RLM_MODULE_INVALID:
1064 case RLM_MODULE_REJECT:
1065 case RLM_MODULE_USERLOCK:
1068 * Over-ride an ACK with a NAK
1070 request->reply->code = nak;
1073 case RLM_MODULE_HANDLED:
1076 case RLM_MODULE_NOOP:
1077 case RLM_MODULE_NOTFOUND:
1079 case RLM_MODULE_UPDATED:
1081 * Do NOT over-ride a previously set value.
1082 * Otherwise an "ok" here will re-write a
1085 if (request->reply->code == 0) {
1086 request->reply->code = ack;
1092 return RLM_MODULE_OK;
1097 * Check if an incoming request is "ok"
1099 * It takes packets, not requests. It sees if the packet looks
1100 * OK. If so, it does a number of sanity checks on it.
1102 static int coa_socket_recv(rad_listen_t *listener,
1103 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1107 RADIUS_PACKET *packet;
1108 RAD_REQUEST_FUNP fun = NULL;
1111 fr_ipaddr_t src_ipaddr;
1113 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1114 if (rcode < 0) return 0;
1116 RAD_STATS_TYPE_INC(listener, total_requests);
1118 if (rcode < 20) { /* AUTH_HDR_LEN */
1119 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1123 if ((client = client_listener_find(listener,
1124 &src_ipaddr, src_port)) == NULL) {
1125 rad_recv_discard(listener->fd);
1126 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1128 if (debug_flag > 0) {
1131 listener->print(listener, name, sizeof(name));
1134 * This is debugging rather than logging, so that
1135 * DoS attacks don't affect us.
1137 DEBUG("Ignoring request to %s from unknown client %s port %d",
1139 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
1140 buffer, sizeof(buffer)), src_port);
1147 * Some sanity checks, based on the packet code.
1150 case PW_COA_REQUEST:
1151 case PW_DISCONNECT_REQUEST:
1156 rad_recv_discard(listener->fd);
1157 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1158 code, client->shortname, src_port);
1161 } /* switch over packet types */
1164 * Now that we've sanity checked everything, receive the
1167 packet = rad_recv(listener->fd, client->message_authenticator);
1169 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1170 DEBUG("%s", fr_strerror());
1174 if (!received_request(listener, packet, prequest, client)) {
1186 * Recieve packets from a proxy socket.
1188 static int proxy_socket_recv(rad_listen_t *listener,
1189 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1192 RADIUS_PACKET *packet;
1193 RAD_REQUEST_FUNP fun = NULL;
1196 packet = rad_recv(listener->fd, 0);
1198 radlog(L_ERR, "%s", fr_strerror());
1203 * FIXME: Client MIB updates?
1205 switch(packet->code) {
1206 case PW_AUTHENTICATION_ACK:
1207 case PW_ACCESS_CHALLENGE:
1208 case PW_AUTHENTICATION_REJECT:
1209 fun = rad_authenticate;
1212 #ifdef WITH_ACCOUNTING
1213 case PW_ACCOUNTING_RESPONSE:
1214 fun = rad_accounting;
1219 case PW_DISCONNECT_ACK:
1220 case PW_DISCONNECT_NAK:
1223 fun = rad_coa_reply;
1229 * FIXME: Update MIB for packet types?
1231 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1232 "from home server %s port %d - ID %d : IGNORED",
1234 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1235 packet->src_port, packet->id);
1240 request = received_proxy_response(packet);
1248 * Distinguish proxied CoA requests from ones we
1251 if ((fun == rad_coa_reply) &&
1252 (request->packet->code == request->proxy->code)) {
1257 rad_assert(fun != NULL);
1259 *prequest = request;
1266 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1268 if (!request->reply->code) return 0;
1270 rad_encode(request->reply, request->packet,
1271 request->client->secret);
1272 rad_sign(request->reply, request->packet,
1273 request->client->secret);
1279 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1281 if (rad_verify(request->packet, NULL,
1282 request->client->secret) < 0) {
1286 return rad_decode(request->packet, NULL,
1287 request->client->secret);
1291 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1293 rad_encode(request->proxy, NULL, request->home_server->secret);
1294 rad_sign(request->proxy, NULL, request->home_server->secret);
1300 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1303 * rad_verify is run in event.c, received_proxy_response()
1306 return rad_decode(request->proxy_reply, request->proxy,
1307 request->home_server->secret);
1313 #include "command.c"
1315 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1317 { common_socket_parse, NULL,
1318 stats_socket_recv, auth_socket_send,
1319 socket_print, client_socket_encode, client_socket_decode },
1322 * This always gets defined.
1324 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
1329 { common_socket_parse, NULL,
1330 proxy_socket_recv, proxy_socket_send,
1331 socket_print, proxy_socket_encode, proxy_socket_decode },
1334 /* authentication */
1335 { common_socket_parse, NULL,
1336 auth_socket_recv, auth_socket_send,
1337 socket_print, client_socket_encode, client_socket_decode },
1339 #ifdef WITH_ACCOUNTING
1341 { common_socket_parse, NULL,
1342 acct_socket_recv, acct_socket_send,
1343 socket_print, client_socket_encode, client_socket_decode},
1348 { detail_parse, detail_free,
1349 detail_recv, detail_send,
1350 detail_print, detail_encode, detail_decode },
1354 /* vlan query protocol */
1355 { common_socket_parse, NULL,
1356 vqp_socket_recv, vqp_socket_send,
1357 socket_print, vqp_socket_encode, vqp_socket_decode },
1361 /* dhcp query protocol */
1362 { dhcp_socket_parse, NULL,
1363 dhcp_socket_recv, dhcp_socket_send,
1364 socket_print, dhcp_socket_encode, dhcp_socket_decode },
1367 #ifdef WITH_COMMAND_SOCKET
1368 /* TCP command socket */
1369 { command_socket_parse, command_socket_free,
1370 command_domain_accept, command_domain_send,
1371 command_socket_print, command_socket_encode, command_socket_decode },
1375 /* Change of Authorization */
1376 { common_socket_parse, NULL,
1377 coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1378 socket_print, client_socket_encode, client_socket_decode },
1386 * Binds a listener to a socket.
1388 static int listen_bind(rad_listen_t *this)
1391 struct sockaddr_storage salocal;
1393 listen_socket_t *sock = this->data;
1396 * If the port is zero, then it means the appropriate
1397 * thing from /etc/services.
1399 if (sock->port == 0) {
1400 struct servent *svp;
1402 switch (this->type) {
1403 case RAD_LISTEN_AUTH:
1404 svp = getservbyname ("radius", "udp");
1406 sock->port = ntohs(svp->s_port);
1408 sock->port = PW_AUTH_UDP_PORT;
1412 #ifdef WITH_ACCOUNTING
1413 case RAD_LISTEN_ACCT:
1414 svp = getservbyname ("radacct", "udp");
1416 sock->port = ntohs(svp->s_port);
1418 sock->port = PW_ACCT_UDP_PORT;
1424 case RAD_LISTEN_PROXY:
1430 case RAD_LISTEN_VQP:
1436 case RAD_LISTEN_COA:
1437 svp = getservbyname ("radius-dynauth", "udp");
1439 sock->port = ntohs(svp->s_port);
1441 sock->port = PW_COA_UDP_PORT;
1447 DEBUG("WARNING: Internal sanity check failed in binding to socket. Ignoring problem.");
1453 * Copy fr_socket() here, as we may need to bind to a device.
1455 this->fd = socket(sock->ipaddr.af, SOCK_DGRAM, 0);
1457 radlog(L_ERR, "Failed opening socket: %s", strerror(errno));
1462 * Bind to a device BEFORE touching IP addresses.
1464 if (sock->interface) {
1465 #ifdef SO_BINDTODEVICE
1467 strcpy(ifreq.ifr_name, sock->interface);
1470 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
1471 (char *)&ifreq, sizeof(ifreq));
1475 radlog(L_ERR, "Failed binding to interface %s: %s",
1476 sock->interface, strerror(errno));
1478 } /* else it worked. */
1480 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1481 #ifdef HAVE_NET_IF_H
1483 * Odds are that any system supporting "bind to
1484 * device" also supports IPv6, so this next bit
1485 * isn't necessary. But it's here for
1488 * If we're doing IPv6, and the scope hasn't yet
1489 * been defined, set the scope to the scope of
1492 if (sock->ipaddr.af == AF_INET6) {
1493 if (sock->ipaddr.scope == 0) {
1494 sock->ipaddr.scope = if_nametoindex(sock->interface);
1495 if (sock->ipaddr.scope == 0) {
1497 radlog(L_ERR, "Failed finding interface %s: %s",
1498 sock->interface, strerror(errno));
1501 } /* else scope was defined: we're OK. */
1506 * IPv4: no link local addresses,
1507 * and no bind to device.
1511 radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
1517 #ifdef WITH_UDPFROMTO
1519 * Initialize udpfromto for all sockets.
1521 if (udpfromto_init(this->fd) != 0) {
1528 * Set up sockaddr stuff.
1530 if (!fr_ipaddr2sockaddr(&sock->ipaddr, sock->port, &salocal, &salen)) {
1535 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1536 if (sock->ipaddr.af == AF_INET6) {
1538 * Listening on '::' does NOT get you IPv4 to
1539 * IPv6 mapping. You've got to listen on an IPv4
1540 * address, too. This makes the rest of the server
1541 * design a little simpler.
1545 if (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr)) {
1548 setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
1549 (char *)&on, sizeof(on));
1551 #endif /* IPV6_V6ONLY */
1553 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
1556 if (sock->ipaddr.af == AF_INET) {
1559 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
1561 * Disable PMTU discovery. On Linux, this
1562 * also makes sure that the "don't fragment"
1565 flag = IP_PMTUDISC_DONT;
1566 setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
1567 &flag, sizeof(flag));
1570 #if defined(IP_DONTFRAG)
1572 * Ensure that the "don't fragment" flag is zero.
1575 setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
1576 &flag, sizeof(flag));
1581 * May be binding to priviledged ports.
1584 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
1590 this->print(this, buffer, sizeof(buffer));
1591 radlog(L_ERR, "Failed binding to %s: %s\n",
1592 buffer, strerror(errno));
1597 * FreeBSD jail issues. We bind to 0.0.0.0, but the
1598 * kernel instead binds us to a 1.2.3.4. If this
1599 * happens, notice, and remember our real IP.
1602 struct sockaddr_storage src;
1603 socklen_t sizeof_src = sizeof(src);
1605 memset(&src, 0, sizeof_src);
1606 if (getsockname(this->fd, (struct sockaddr *) &src,
1608 radlog(L_ERR, "Failed getting socket name: %s",
1613 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
1614 &sock->ipaddr, &sock->port)) {
1615 radlog(L_ERR, "Socket has unsupported address family");
1624 if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0) {
1625 radlog(L_ERR, "Failure getting socket flags: %s)\n",
1630 flags |= O_NONBLOCK;
1631 if( fcntl(this->fd, F_SETFL, flags) < 0) {
1632 radlog(L_ERR, "Failure setting socket flags: %s)\n",
1644 * Allocate & initialize a new listener.
1646 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1650 this = rad_malloc(sizeof(*this));
1651 memset(this, 0, sizeof(*this));
1654 this->recv = master_listen[this->type].recv;
1655 this->send = master_listen[this->type].send;
1656 this->print = master_listen[this->type].print;
1657 this->encode = master_listen[this->type].encode;
1658 this->decode = master_listen[this->type].decode;
1662 case RAD_LISTEN_NONE:
1664 case RAD_LISTEN_AUTH:
1665 #ifdef WITH_ACCOUNTING
1666 case RAD_LISTEN_ACCT:
1669 case RAD_LISTEN_PROXY:
1672 case RAD_LISTEN_VQP:
1675 case RAD_LISTEN_COA:
1677 this->data = rad_malloc(sizeof(listen_socket_t));
1678 memset(this->data, 0, sizeof(listen_socket_t));
1682 case RAD_LISTEN_DHCP:
1683 this->data = rad_malloc(sizeof(dhcp_socket_t));
1684 memset(this->data, 0, sizeof(dhcp_socket_t));
1689 case RAD_LISTEN_DETAIL:
1694 #ifdef WITH_COMMAND_SOCKET
1695 case RAD_LISTEN_COMMAND:
1696 this->data = rad_malloc(sizeof(fr_command_socket_t));
1697 memset(this->data, 0, sizeof(fr_command_socket_t));
1702 rad_assert("Unsupported option!" == NULL);
1712 * Externally visible function for creating a new proxy LISTENER.
1714 * Not thread-safe, but all calls to it are protected by the
1715 * proxy mutex in event.c
1717 rad_listen_t *proxy_new_listener(fr_ipaddr_t *ipaddr, int exists)
1719 rad_listen_t *this, *tmp, **last;
1720 listen_socket_t *sock, *old;
1723 * Find an existing proxy socket to copy.
1726 last = &mainconfig.listen;
1727 for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1729 * Not proxy, ignore it.
1731 if (tmp->type != RAD_LISTEN_PROXY) goto next;
1736 * If we were asked to copy a specific one, do
1737 * so. If we're just finding one that already
1738 * exists, return a pointer to it. Otherwise,
1739 * create ANOTHER one with the same IP address.
1741 if ((ipaddr->af != AF_UNSPEC) &&
1742 (fr_ipaddr_cmp(&sock->ipaddr, ipaddr) != 0)) {
1743 if (exists) return tmp;
1747 if (!old) old = sock;
1750 last = &(tmp->next);
1753 this = listen_alloc(RAD_LISTEN_PROXY);
1758 * The socket MUST already exist if we're binding
1759 * to an address while proxying.
1761 * If we're initializing the server, it's OK for the
1762 * socket to NOT exist.
1765 DEBUG("WARNING: No previous template for proxy socket. Source IP address may be chosen by the OS");
1768 if (ipaddr->af != AF_UNSPEC) {
1769 sock->ipaddr = *ipaddr;
1771 memset(&sock->ipaddr, 0, sizeof(sock->ipaddr));
1772 sock->ipaddr.af = AF_INET; /* Oh well */
1775 sock->ipaddr = old->ipaddr;
1780 if (listen_bind(this) >= 0) {
1782 * Add the new listener to the list of
1789 DEBUG("Failed binding to new proxy socket");
1795 static const FR_NAME_NUMBER listen_compare[] = {
1797 { "status", RAD_LISTEN_NONE },
1799 { "auth", RAD_LISTEN_AUTH },
1800 #ifdef WITH_ACCOUNTING
1801 { "acct", RAD_LISTEN_ACCT },
1804 { "detail", RAD_LISTEN_DETAIL },
1807 { "proxy", RAD_LISTEN_PROXY },
1810 { "vmps", RAD_LISTEN_VQP },
1813 { "dhcp", RAD_LISTEN_DHCP },
1815 #ifdef WITH_COMMAND_SOCKET
1816 { "control", RAD_LISTEN_COMMAND },
1819 { "coa", RAD_LISTEN_COA },
1825 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
1833 cf_log_info(cs, "listen {");
1835 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1837 if (rcode < 0) return NULL;
1840 cf_log_err(cf_sectiontoitem(cs),
1841 "No type specified in listen section");
1845 type = fr_str2int(listen_compare, listen_type, -1);
1847 cf_log_err(cf_sectiontoitem(cs),
1848 "Invalid type \"%s\" in listen section.",
1856 * Allow listen sections in the default config to
1857 * refer to a server.
1860 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
1862 if (rcode == 1) { /* compatiblity with 2.0-pre */
1863 rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
1866 if (rcode < 0) return NULL;
1870 * Set up cross-type data.
1872 this = listen_alloc(type);
1873 this->server = server;
1877 * Call per-type parser.
1879 if (master_listen[type].parse(cs, this) < 0) {
1884 cf_log_info(cs, "}");
1890 * Generate a list of listeners. Takes an input list of
1891 * listeners, too, so we don't close sockets with waiting packets.
1893 int listen_init(CONF_SECTION *config, rad_listen_t **head)
1895 int override = FALSE;
1897 CONF_SECTION *cs = NULL;
1898 rad_listen_t **last;
1900 fr_ipaddr_t server_ipaddr;
1903 int defined_proxy = 0;
1907 * We shouldn't be called with a pre-existing list.
1909 rad_assert(head && (*head == NULL));
1912 server_ipaddr.af = AF_UNSPEC;
1915 * If the port is specified on the command-line,
1916 * it over-rides the configuration file.
1918 * FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
1920 if (mainconfig.port >= 0) auth_port = mainconfig.port;
1923 * If the IP address was configured on the command-line,
1924 * use that as the "bind_address"
1926 if (mainconfig.myip.af != AF_UNSPEC) {
1927 memcpy(&server_ipaddr, &mainconfig.myip,
1928 sizeof(server_ipaddr));
1934 * Else look for bind_address and/or listen sections.
1936 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1937 rcode = cf_item_parse(config, "bind_address",
1939 &server_ipaddr.ipaddr.ip4addr, NULL);
1940 if (rcode < 0) return -1; /* error parsing it */
1942 if (rcode == 0) { /* successfully parsed IPv4 */
1943 listen_socket_t *sock;
1944 server_ipaddr.af = AF_INET;
1946 radlog(L_INFO, "WARNING: The directive 'bind_address' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1950 if (strcmp(progname, "vmpsd") == 0) {
1951 this = listen_alloc(RAD_LISTEN_VQP);
1952 if (!auth_port) auth_port = 1589;
1955 this = listen_alloc(RAD_LISTEN_AUTH);
1959 sock->ipaddr = server_ipaddr;
1960 sock->port = auth_port;
1962 sock->clients = clients_parse_section(config);
1963 if (!sock->clients) {
1964 cf_log_err(cf_sectiontoitem(config),
1965 "Failed to find any clients for this listen section");
1970 if (listen_bind(this) < 0) {
1972 radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1976 auth_port = sock->port; /* may have been updated in listen_bind */
1978 cs = cf_section_sub_find_name2(config, "server",
1980 if (cs) this->server = mainconfig.name;
1984 last = &(this->next);
1990 if (strcmp(progname, "vmpsd") == 0) goto do_proxy;
1993 #ifdef WITH_ACCOUNTING
1995 * Open Accounting Socket.
1997 * If we haven't already gotten acct_port from
1998 * /etc/services, then make it auth_port + 1.
2000 this = listen_alloc(RAD_LISTEN_ACCT);
2004 * Create the accounting socket.
2006 * The accounting port is always the
2007 * authentication port + 1
2009 sock->ipaddr = server_ipaddr;
2010 sock->port = auth_port + 1;
2012 sock->clients = clients_parse_section(config);
2013 if (!sock->clients) {
2014 cf_log_err(cf_sectiontoitem(config),
2015 "Failed to find any clients for this listen section");
2019 if (listen_bind(this) < 0) {
2022 radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
2027 cs = cf_section_sub_find_name2(config, "server",
2029 if (cs) this->server = mainconfig.name;
2033 last = &(this->next);
2035 } else if (mainconfig.port > 0) { /* no bind address, but a port */
2036 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2042 * They specified an IP on the command-line, ignore
2043 * all listen sections except the one in '-n'.
2045 if (mainconfig.myip.af != AF_UNSPEC) {
2046 CONF_SECTION *subcs;
2047 const char *name2 = cf_section_name2(cs);
2049 cs = cf_section_sub_find_name2(config, "server",
2051 if (!cs) goto do_proxy;
2054 * Should really abstract this code...
2056 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2058 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2059 this = listen_parse(subcs, name2);
2066 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
2070 last = &(this->next);
2071 } /* loop over "listen" directives in server <foo> */
2077 * Walk through the "listen" sections, if they exist.
2079 for (cs = cf_subsection_find_next(config, NULL, "listen");
2081 cs = cf_subsection_find_next(config, cs, "listen")) {
2082 this = listen_parse(cs, NULL);
2089 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
2093 last = &(this->next);
2097 * Check virtual servers for "listen" sections, too.
2099 * FIXME: Move to virtual server init?
2101 for (cs = cf_subsection_find_next(config, NULL, "server");
2103 cs = cf_subsection_find_next(config, cs, "server")) {
2104 CONF_SECTION *subcs;
2105 const char *name2 = cf_section_name2(cs);
2107 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2109 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2110 this = listen_parse(subcs, name2);
2117 if (this->type == RAD_LISTEN_PROXY) {
2118 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2125 last = &(this->next);
2126 } /* loop over "listen" directives in virtual servers */
2127 } /* loop over virtual servers */
2130 * If we're proxying requests, open the proxy FD.
2131 * Otherwise, don't do anything.
2135 * No sockets to receive packets, this is an error.
2136 * proxying is pointless.
2139 radlog(L_ERR, "The server is not configured to listen on any ports. Cannot start.");
2144 if (mainconfig.proxy_requests == TRUE) {
2146 listen_socket_t *sock = NULL;
2148 if (defined_proxy) goto check_home_servers;
2151 * Find the first authentication port,
2154 for (this = *head; this != NULL; this = this->next) {
2155 if (this->type == RAD_LISTEN_AUTH) {
2159 * We shouldn't proxy on loopback.
2161 if ((sock->ipaddr.af == AF_INET) &&
2162 (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_LOOPBACK))) continue;
2165 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2166 if ((sock->ipaddr.af == AF_INET6) &&
2167 (IN6_IS_ADDR_LINKLOCAL(&sock->ipaddr.ipaddr.ip6addr))) continue;
2170 if (server_ipaddr.af == AF_UNSPEC) {
2171 server_ipaddr = sock->ipaddr;
2173 port = sock->port + 2; /* skip acct port */
2177 if (this->type == RAD_LISTEN_VQP) {
2179 if (server_ipaddr.af == AF_UNSPEC) {
2180 server_ipaddr = sock->ipaddr;
2182 port = sock->port + 1;
2188 if (port < 0) port = 1024 + (fr_rand() & 0x1ff);
2191 * Address is still unspecified, use IPv4.
2193 if (server_ipaddr.af == AF_UNSPEC) {
2194 server_ipaddr.af = AF_INET;
2195 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
2198 this = listen_alloc(RAD_LISTEN_PROXY);
2202 * Create the first proxy socket.
2204 sock->ipaddr = server_ipaddr;
2207 * Try to find a proxy port (value doesn't matter)
2209 for (sock->port = port;
2212 if (listen_bind(this) == 0) {
2214 last = &(this->next); /* just in case */
2219 if (sock->port >= 64000) {
2222 radlog(L_ERR, "Failed to open socket for proxying");
2227 * Create *additional* proxy listeners, based
2228 * on their src_ipaddr.
2231 if (home_server_create_listeners() != 0) return -1;
2239 * Free a linked list of listeners;
2241 void listen_free(rad_listen_t **head)
2245 if (!head || !*head) return;
2249 rad_listen_t *next = this->next;
2252 * Other code may have eaten the FD.
2254 if (this->fd >= 0) close(this->fd);
2256 if (master_listen[this->type].free) {
2257 master_listen[this->type].free(this);
2269 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
2274 for (this = mainconfig.listen; this != NULL; this = this->next) {
2275 listen_socket_t *sock;
2277 if ((this->type != RAD_LISTEN_AUTH) &&
2278 (this->type != RAD_LISTEN_ACCT)) continue;
2282 if ((sock->port == port) &&
2283 (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
2284 return sock->clients;
2292 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port)
2296 for (this = mainconfig.listen; this != NULL; this = this->next) {
2297 listen_socket_t *sock;
2300 * FIXME: For TCP, ignore the *secondary*
2301 * listeners associated with the main socket.
2303 if ((this->type != RAD_LISTEN_AUTH) &&
2304 (this->type != RAD_LISTEN_ACCT)) continue;
2308 if ((sock->port == port) &&
2309 (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
2313 if ((sock->port == port) &&
2314 ((sock->ipaddr.af == AF_INET) &&
2315 (sock->ipaddr.ipaddr.ip4addr.s_addr == INADDR_ANY))) {
2319 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2320 if ((sock->port == port) &&
2321 (sock->ipaddr.af == AF_INET6) &&
2322 (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr))) {