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>
32 #include <freeradius-devel/process.h>
34 #include <freeradius-devel/vmps.h>
35 #include <freeradius-devel/detail.h>
38 #include <freeradius-devel/udpfromto.h>
41 #ifdef HAVE_SYS_RESOURCE_H
42 #include <sys/resource.h>
54 #ifdef DEBUG_PRINT_PACKET
55 static void print_packet(RADIUS_PACKET *packet)
57 char src[256], dst[256];
59 ip_ntoh(&packet->src_ipaddr, src, sizeof(src));
60 ip_ntoh(&packet->dst_ipaddr, dst, sizeof(dst));
62 fprintf(stderr, "ID %d: %s %d -> %s %d\n", packet->id,
63 src, packet->src_port, dst, packet->dst_port);
69 * We'll use this below.
71 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
72 typedef void (*rad_listen_free_t)(rad_listen_t *);
74 typedef struct rad_listen_master_t {
75 rad_listen_parse_t parse;
76 rad_listen_free_t free;
77 rad_listen_recv_t recv;
78 rad_listen_send_t send;
79 rad_listen_print_t print;
80 rad_listen_encode_t encode;
81 rad_listen_decode_t decode;
82 } rad_listen_master_t;
84 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
86 #ifdef WITH_COMMAND_SOCKET
87 static int command_tcp_recv(rad_listen_t *listener);
88 static int command_tcp_send(rad_listen_t *listener, REQUEST *request);
89 static int command_write_magic(int newfd, listen_socket_t *sock);
93 * Xlat for %{listen:foo}
95 static size_t xlat_listen(UNUSED void *instance, REQUEST *request,
96 const char *fmt, char *out,
99 const char *value = NULL;
102 if (!fmt || !out || (outlen < 1)) return 0;
104 if (!request || !request->listener) {
109 cp = cf_pair_find(request->listener->cs, fmt);
110 if (!cp || !(value = cf_pair_value(cp))) {
115 strlcpy(out, value, outlen);
121 * Find a per-socket client.
123 RADCLIENT *client_listener_find(rad_listen_t *listener,
124 const fr_ipaddr_t *ipaddr, int src_port)
126 #ifdef WITH_DYNAMIC_CLIENTS
133 RADCLIENT_LIST *clients;
134 listen_socket_t *sock;
136 rad_assert(listener != NULL);
137 rad_assert(ipaddr != NULL);
139 sock = listener->data;
140 clients = sock->clients;
143 * This HAS to have been initialized previously.
145 rad_assert(clients != NULL);
147 client = client_find(clients, ipaddr,sock->proto);
149 char name[256], buffer[128];
151 #ifdef WITH_DYNAMIC_CLIENTS
152 unknown: /* used only for dynamic clients */
156 * DoS attack quenching, but only in daemon mode.
157 * If they're running in debug mode, show them
160 if (debug_flag == 0) {
161 static time_t last_printed = 0;
164 if (last_printed == now) return NULL;
169 listener->print(listener, name, sizeof(name));
171 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d"
175 , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
176 buffer, sizeof(buffer)), src_port
178 , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp"
184 #ifndef WITH_DYNAMIC_CLIENTS
185 return client; /* return the found client. */
189 * No server defined, and it's not dynamic. Return it.
191 if (!client->client_server && !client->dynamic) return client;
196 * It's a dynamically generated client, check it.
198 if (client->dynamic && (src_port != 0)) {
200 * Lives forever. Return it.
202 if (client->lifetime == 0) return client;
205 * Rate-limit the deletion of known clients.
206 * This makes them last a little longer, but
207 * prevents the server from melting down if (say)
208 * 10k clients all expire at once.
210 if (now == client->last_new_client) return client;
213 * It's not dead yet. Return it.
215 if ((client->created + client->lifetime) > now) return client;
218 * This really puts them onto a queue for later
221 client_delete(clients, client);
224 * Go find the enclosing network again.
226 client = client_find(clients, ipaddr, sock->proto);
231 if (!client) goto unknown;
232 if (!client->client_server) goto unknown;
235 * At this point, 'client' is the enclosing
236 * network that configures where dynamic clients
239 rad_assert(client->dynamic == 0);
241 } else if (!client->dynamic && client->rate_limit) {
243 * The IP is unknown, so we've found an enclosing
244 * network. Enable DoS protection. We only
245 * allow one new client per second. Known
246 * clients aren't subject to this restriction.
248 if (now == client->last_new_client) goto unknown;
251 client->last_new_client = now;
253 request = request_alloc();
254 if (!request) goto unknown;
256 request->listener = listener;
257 request->client = client;
258 request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
259 if (!request->packet) { /* badly formed, etc */
260 request_free(&request);
263 request->reply = rad_alloc_reply(request->packet);
264 if (!request->reply) {
265 request_free(&request);
268 gettimeofday(&request->packet->timestamp, NULL);
270 request->priority = listener->type;
271 request->server = client->client_server;
272 request->root = &mainconfig;
275 * Run a fake request through the given virtual server.
276 * Look for FreeRADIUS-Client-IP-Address
277 * FreeRADIUS-Client-Secret
280 * and create the RADCLIENT structure from that.
282 DEBUG("server %s {", request->server);
284 rcode = module_authorize(0, request);
286 DEBUG("} # server %s", request->server);
288 if (rcode != RLM_MODULE_OK) {
289 request_free(&request);
294 * If the client was updated by rlm_dynamic_clients,
295 * don't create the client from attribute-value pairs.
297 if (request->client == client) {
298 created = client_create(clients, request);
300 created = request->client;
303 * This frees the client if it isn't valid.
305 if (!client_validate(clients, client, created)) goto unknown;
308 request->server = client->server;
309 exec_trigger(request, NULL, "server.client.add", FALSE);
311 request_free(&request);
313 if (!created) goto unknown;
319 static int listen_bind(rad_listen_t *this);
323 * Process and reply to a server-status request.
324 * Like rad_authenticate and rad_accounting this should
325 * live in it's own file but it's so small we don't bother.
327 int rad_status_server(REQUEST *request)
329 int rcode = RLM_MODULE_OK;
332 switch (request->listener->type) {
334 case RAD_LISTEN_NONE:
336 case RAD_LISTEN_AUTH:
337 dval = dict_valbyname(PW_AUTZ_TYPE, 0, "Status-Server");
339 rcode = module_authorize(dval->value, request);
341 rcode = RLM_MODULE_OK;
346 case RLM_MODULE_UPDATED:
347 request->reply->code = PW_AUTHENTICATION_ACK;
350 case RLM_MODULE_FAIL:
351 case RLM_MODULE_HANDLED:
352 request->reply->code = 0; /* don't reply */
356 case RLM_MODULE_REJECT:
357 request->reply->code = PW_AUTHENTICATION_REJECT;
362 #ifdef WITH_ACCOUNTING
363 case RAD_LISTEN_ACCT:
364 dval = dict_valbyname(PW_ACCT_TYPE, 0, "Status-Server");
366 rcode = module_accounting(dval->value, request);
368 rcode = RLM_MODULE_OK;
373 case RLM_MODULE_UPDATED:
374 request->reply->code = PW_ACCOUNTING_RESPONSE;
378 request->reply->code = 0; /* don't reply */
386 * This is a vendor extension. Suggested by Glen
387 * Zorn in IETF 72, and rejected by the rest of
388 * the WG. We like it, so it goes in here.
391 dval = dict_valbyname(PW_RECV_COA_TYPE, 0, "Status-Server");
393 rcode = module_recv_coa(dval->value, request);
395 rcode = RLM_MODULE_OK;
400 case RLM_MODULE_UPDATED:
401 request->reply->code = PW_COA_ACK;
405 request->reply->code = 0; /* don't reply */
417 * Full statistics are available only on a statistics
420 if (request->listener->type == RAD_LISTEN_NONE) {
421 request_stats_reply(request);
429 static int dual_tcp_recv(rad_listen_t *listener)
432 RADIUS_PACKET *packet;
433 RAD_REQUEST_FUNP fun = NULL;
434 listen_socket_t *sock = listener->data;
435 RADCLIENT *client = sock->client;
438 * Allocate a packet for partial reads.
441 sock->packet = rad_alloc(0);
442 if (!sock->packet) return 0;
444 sock->packet->sockfd = listener->fd;
445 sock->packet->src_ipaddr = sock->other_ipaddr;
446 sock->packet->src_port = sock->other_port;
447 sock->packet->dst_ipaddr = sock->my_ipaddr;
448 sock->packet->dst_port = sock->my_port;
452 * Grab the packet currently being processed.
454 packet = sock->packet;
456 rcode = fr_tcp_read_packet(packet, 0);
459 * Still only a partial packet. Put it back, and return,
460 * so that we'll read more data when it's ready.
466 if (rcode == -1) { /* error reading packet */
469 radlog(L_ERR, "Invalid packet from %s port %d: closing socket",
470 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
474 if (rcode < 0) { /* error or connection reset */
475 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
478 * Decrement the number of connections.
480 if (sock->parent->limit.num_connections > 0) {
481 sock->parent->limit.num_connections--;
483 if (sock->client->limit.num_connections > 0) {
484 sock->client->limit.num_connections--;
488 * Tell the event handler that an FD has disappeared.
490 DEBUG("Client has closed connection");
491 event_new_fd(listener);
494 * Do NOT free the listener here. It's in use by
495 * a request, and will need to hang around until
496 * all of the requests are done.
498 * It is instead free'd in remove_from_request_hash()
504 * Some sanity checks, based on the packet code.
506 switch(packet->code) {
507 case PW_AUTHENTICATION_REQUEST:
508 if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
509 FR_STATS_INC(auth, total_requests);
510 fun = rad_authenticate;
513 #ifdef WITH_ACCOUNTING
514 case PW_ACCOUNTING_REQUEST:
515 if (listener->type != RAD_LISTEN_ACCT) goto bad_packet;
516 FR_STATS_INC(acct, total_requests);
517 fun = rad_accounting;
521 case PW_STATUS_SERVER:
522 if (!mainconfig.status_server) {
523 FR_STATS_INC(auth, total_unknown_types);
524 DEBUGW("Ignoring Status-Server request due to security configuration");
525 rad_free(&sock->packet);
528 fun = rad_status_server;
533 FR_STATS_INC(auth, total_unknown_types);
535 DEBUG("Invalid packet code %d sent from client %s port %d : IGNORED",
536 packet->code, client->shortname, packet->src_port);
537 rad_free(&sock->packet);
539 } /* switch over packet types */
541 if (!request_receive(listener, packet, client, fun)) {
542 FR_STATS_INC(auth, total_packets_dropped);
543 rad_free(&sock->packet);
547 sock->packet = NULL; /* we have no need for more partial reads */
551 static int dual_tcp_accept(rad_listen_t *listener)
556 struct sockaddr_storage src;
557 listen_socket_t *sock;
558 fr_ipaddr_t src_ipaddr;
559 RADCLIENT *client = NULL;
563 DEBUG2(" ... new connection request on TCP socket.");
565 newfd = accept(listener->fd, (struct sockaddr *) &src, &salen);
568 * Non-blocking sockets must handle this.
571 if (errno == EWOULDBLOCK) {
576 DEBUG2(" ... failed to accept connection.");
580 if (!fr_sockaddr2ipaddr(&src, salen, &src_ipaddr, &src_port)) {
582 DEBUG2(" ... unknown address family.");
587 * Enforce client IP address checks on accept, not on
590 if ((client = client_listener_find(listener,
591 &src_ipaddr, src_port)) == NULL) {
593 FR_STATS_INC(auth, total_invalid_requests);
598 * Enforce max_connections on client && listen section.
600 if ((client->limit.max_connections != 0) &&
601 (client->limit.max_connections == client->limit.num_connections)) {
603 * FIXME: Print client IP/port, and server IP/port.
605 radlog(L_INFO, "Ignoring new connection due to client max_connections (%d)", client->limit.max_connections);
610 sock = listener->data;
611 if ((sock->limit.max_connections != 0) &&
612 (sock->limit.max_connections == sock->limit.num_connections)) {
614 * FIXME: Print client IP/port, and server IP/port.
616 radlog(L_INFO, "Ignoring new connection due to socket max_connections");
620 client->limit.num_connections++;
621 sock->limit.num_connections++;
624 * Add the new listener.
626 this = listen_alloc(listener->type);
627 if (!this) return -1;
630 * Copy everything, including the pointer to the socket
634 memcpy(this->data, listener->data, sizeof(*sock));
635 memcpy(this, listener, sizeof(*this));
637 this->data = sock; /* fix it back */
639 sock->parent = listener->data;
640 sock->other_ipaddr = src_ipaddr;
641 sock->other_port = src_port;
642 sock->client = client;
643 sock->opened = sock->last_packet = time(NULL);
646 * Set the limits. The defaults are the parent limits.
647 * Client limits on max_connections are enforced dynamically.
648 * Set the MINIMUM of client/socket idle timeout or lifetime.
650 memcpy(&sock->limit, &sock->parent->limit, sizeof(sock->limit));
652 if (client->limit.idle_timeout &&
653 ((sock->limit.idle_timeout == 0) ||
654 (client->limit.idle_timeout < sock->limit.idle_timeout))) {
655 sock->limit.idle_timeout = client->limit.idle_timeout;
658 if (client->limit.lifetime &&
659 ((sock->limit.lifetime == 0) ||
660 (client->limit.lifetime < sock->limit.lifetime))) {
661 sock->limit.lifetime = client->limit.lifetime;
665 this->status = RAD_LISTEN_STATUS_INIT;
668 #ifdef WITH_COMMAND_SOCKET
669 if (this->type == RAD_LISTEN_COMMAND) {
670 this->recv = command_tcp_recv;
671 this->send = command_tcp_send;
672 command_write_magic(this->fd, sock);
677 this->recv = dual_tcp_recv;
681 this->recv = dual_tls_recv;
682 this->send = dual_tls_send;
688 * FIXME: set O_NONBLOCK on the accept'd fd.
689 * See djb's portability rants for details.
693 * Tell the event loop that we have a new FD.
694 * This can be called from a child thread...
704 * This function is stupid and complicated.
706 static int socket_print(const rad_listen_t *this, char *buffer, size_t bufsize)
709 listen_socket_t *sock = this->data;
712 switch (this->type) {
714 case RAD_LISTEN_NONE: /* what a hack... */
719 case RAD_LISTEN_AUTH:
720 name = "authentication";
723 #ifdef WITH_ACCOUNTING
724 case RAD_LISTEN_ACCT:
730 case RAD_LISTEN_PROXY:
742 case RAD_LISTEN_DHCP:
753 #ifdef WITH_COMMAND_SOCKET
754 case RAD_LISTEN_COMMAND:
764 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
765 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
769 if (sock->interface) {
770 ADDSTRING(" interface ");
771 ADDSTRING(sock->interface);
775 if (this->recv == dual_tcp_accept) {
776 ADDSTRING(" proto tcp");
782 * TCP sockets get printed a little differently, to make
783 * it clear what's going on.
786 ADDSTRING(" from client (");
787 ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
791 snprintf(buffer, bufsize, "%d", sock->other_port);
795 if ((sock->my_ipaddr.af == AF_INET) &&
796 (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
797 strlcpy(buffer, "*", bufsize);
799 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
804 snprintf(buffer, bufsize, "%d", sock->my_port);
808 ADDSTRING(", virtual-server=");
809 ADDSTRING(this->server);
819 * Maybe it's a socket that we opened to a home server.
821 if ((sock->proto == IPPROTO_TCP) &&
822 (this->type == RAD_LISTEN_PROXY)) {
824 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
828 snprintf(buffer, bufsize, "%d", sock->my_port);
830 ADDSTRING(") -> home_server (");
832 if ((sock->other_ipaddr.af == AF_INET) &&
833 (sock->other_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
834 strlcpy(buffer, "*", bufsize);
836 ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
841 snprintf(buffer, bufsize, "%d", sock->other_port);
848 #endif /* WITH_PROXY */
849 #endif /* WITH_TCP */
851 ADDSTRING(" address ");
853 if ((sock->my_ipaddr.af == AF_INET) &&
854 (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
855 strlcpy(buffer, "*", bufsize);
857 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
862 snprintf(buffer, bufsize, "%d", sock->my_port);
873 ADDSTRING(" as server ");
874 ADDSTRING(this->server);
883 extern int check_config; /* radiusd.c */
886 static CONF_PARSER limit_config[] = {
887 { "max_connections", PW_TYPE_INTEGER,
888 offsetof(listen_socket_t, limit.max_connections), NULL, "16" },
890 { "lifetime", PW_TYPE_INTEGER,
891 offsetof(listen_socket_t, limit.lifetime), NULL, "0" },
893 { "idle_timeout", PW_TYPE_INTEGER,
894 offsetof(listen_socket_t, limit.idle_timeout), NULL, "30" },
896 { NULL, -1, 0, NULL, NULL } /* end the list */
901 * Parse an authentication or accounting socket.
903 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
906 int listen_port, max_pps;
908 listen_socket_t *sock = this->data;
909 char *section_name = NULL;
910 CONF_SECTION *client_cs, *parentcs;
917 memset(&ipaddr, 0, sizeof(ipaddr));
918 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
919 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
920 &ipaddr.ipaddr.ip4addr, NULL);
921 if (rcode < 0) return -1;
923 if (rcode == 0) { /* successfully parsed IPv4 */
926 } else { /* maybe IPv6? */
927 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
928 &ipaddr.ipaddr.ip6addr, NULL);
929 if (rcode < 0) return -1;
932 cf_log_err(cf_sectiontoitem(cs),
933 "No address specified in listen section");
936 ipaddr.af = AF_INET6;
939 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
941 if (rcode < 0) return -1;
943 if ((listen_port < 0) || (listen_port > 65535)) {
944 cf_log_err(cf_sectiontoitem(cs),
945 "Invalid value for \"port\"");
949 rcode = cf_item_parse(cs, "max_pps", PW_TYPE_INTEGER,
951 if (rcode < 0) return -1;
953 if (max_pps && ((max_pps < 10) || (max_pps > 1000000))) {
954 cf_log_err(cf_sectiontoitem(cs),
955 "Invalid value for \"max_pps\"");
959 sock->proto = IPPROTO_UDP;
961 if (cf_pair_find(cs, "proto")) {
963 cf_log_err(cf_sectiontoitem(cs),
964 "System does not support the TCP protocol. Delete this line from the configuration file.");
972 rcode = cf_item_parse(cs, "proto", PW_TYPE_STRING_PTR,
974 if (rcode < 0) return -1;
976 if (strcmp(proto, "udp") == 0) {
977 sock->proto = IPPROTO_UDP;
979 } else if (strcmp(proto, "tcp") == 0) {
980 sock->proto = IPPROTO_TCP;
983 limit = cf_section_sub_find(cs, "limit");
985 rcode = cf_section_parse(limit, sock,
987 if (rcode < 0) return -1;
989 sock->limit.max_connections = 60;
990 sock->limit.idle_timeout = 30;
991 sock->limit.lifetime = 0;
994 if ((sock->limit.idle_timeout > 0) && (sock->limit.idle_timeout < 5))
995 sock->limit.idle_timeout = 5;
996 if ((sock->limit.lifetime > 0) && (sock->limit.lifetime < 5))
997 sock->limit.lifetime = 5;
998 if ((sock->limit.lifetime > 0) && (sock->limit.idle_timeout > sock->limit.lifetime))
999 sock->limit.idle_timeout = 0;
1001 cf_log_err(cf_sectiontoitem(cs),
1002 "Unknown proto name \"%s\"", proto);
1009 * TCP requires a destination IP for sockets.
1010 * UDP doesn't, so it's allowed.
1013 if ((this->type == RAD_LISTEN_PROXY) &&
1014 (sock->proto != IPPROTO_UDP)) {
1015 cf_log_err(cf_sectiontoitem(cs),
1016 "Proxy listeners can only listen on proto = udp");
1019 #endif /* WITH_PROXY */
1022 tls = cf_section_sub_find(cs, "tls");
1025 * Don't allow TLS configurations for UDP sockets.
1027 if (sock->proto != IPPROTO_TCP) {
1028 cf_log_err(cf_sectiontoitem(cs),
1029 "TLS transport is not available for UDP sockets.");
1035 * FIXME: Make this better.
1037 if (listen_port == 0) listen_port = 2083;
1039 this->tls = tls_server_conf_parse(tls);
1044 #ifdef HAVE_PTRHEAD_H
1045 if (pthread_mutex_init(&sock->mutex, NULL) < 0) {
1053 #else /* WITH_TLS */
1055 * Built without TLS. Disallow it.
1057 if (cf_section_sub_find(cs, "tls")) {
1058 cf_log_err(cf_sectiontoitem(cs),
1059 "TLS transport is not available in this executable.");
1062 #endif /* WITH_TLS */
1064 #endif /* WITH_TCP */
1067 * No "proto" field. Disallow TLS.
1069 } else if (cf_section_sub_find(cs, "tls")) {
1070 cf_log_err(cf_sectiontoitem(cs),
1071 "TLS transport is not available in this \"listen\" section.");
1075 sock->my_ipaddr = ipaddr;
1076 sock->my_port = listen_port;
1077 sock->max_rate = max_pps;
1081 if (home_server_find(&sock->my_ipaddr, sock->my_port, sock->proto)) {
1084 DEBUGE("We have been asked to listen on %s port %d, which is also listed as a home server. This can create a proxy loop.",
1085 ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1090 return 0; /* don't do anything */
1095 * If we can bind to interfaces, do so,
1098 if (cf_pair_find(cs, "interface")) {
1100 CONF_PAIR *cp = cf_pair_find(cs, "interface");
1102 rad_assert(cp != NULL);
1103 value = cf_pair_value(cp);
1105 cf_log_err(cf_sectiontoitem(cs),
1106 "No interface name given");
1109 sock->interface = value;
1114 * If we can do broadcasts..
1116 if (cf_pair_find(cs, "broadcast")) {
1117 #ifndef SO_BROADCAST
1118 cf_log_err(cf_sectiontoitem(cs),
1119 "System does not support broadcast sockets. Delete this line from the configuration file.");
1123 CONF_PAIR *cp = cf_pair_find(cs, "broadcast");
1125 if (this->type != RAD_LISTEN_DHCP) {
1126 cf_log_err(cf_pairtoitem(cp),
1127 "Broadcast can only be set for DHCP listeners. Delete this line from the configuration file.");
1131 rad_assert(cp != NULL);
1132 value = cf_pair_value(cp);
1134 cf_log_err(cf_sectiontoitem(cs),
1135 "No broadcast value given");
1140 * Hack... whatever happened to cf_section_parse?
1142 sock->broadcast = (strcmp(value, "yes") == 0);
1148 * And bind it to the port.
1150 if (listen_bind(this) < 0) {
1152 cf_log_err(cf_sectiontoitem(cs),
1153 "Error binding to port for %s port %d",
1154 ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1161 * Proxy sockets don't have clients.
1163 if (this->type == RAD_LISTEN_PROXY) return 0;
1167 * The more specific configurations are preferred to more
1171 parentcs = cf_top_section(cs);
1172 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
1173 §ion_name, NULL);
1174 if (rcode < 0) return -1; /* bad string */
1177 * Explicit list given: use it.
1179 client_cs = cf_section_sub_find_name2(parentcs,
1183 client_cs = cf_section_find(section_name);
1186 cf_log_err(cf_sectiontoitem(cs),
1187 "Failed to find clients %s {...}",
1193 } /* else there was no "clients = " entry. */
1196 CONF_SECTION *server_cs;
1198 server_cs = cf_section_sub_find_name2(parentcs,
1202 * Found a "server foo" section. If there are clients
1206 (cf_section_sub_find(server_cs, "client") != NULL)) {
1207 client_cs = server_cs;
1212 * Still nothing. Look for global clients.
1214 if (!client_cs) client_cs = parentcs;
1216 sock->clients = clients_parse_section(client_cs);
1217 if (!sock->clients) {
1218 cf_log_err(cf_sectiontoitem(cs),
1219 "Failed to load clients for this listen section");
1224 if (sock->proto == IPPROTO_TCP) {
1226 * Re-write the listener receive function to
1227 * allow us to accept the socket.
1229 this->recv = dual_tcp_accept;
1237 * Send an authentication response packet
1239 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
1241 rad_assert(request->listener == listener);
1242 rad_assert(listener->send == auth_socket_send);
1244 #ifdef WITH_UDPFROMTO
1246 * Overwrite the src ip address on the outbound packet
1247 * with the one specified by the client.
1248 * This is useful to work around broken DSR implementations
1249 * and other routing issues.
1251 if (request->client->src_ipaddr.af != AF_UNSPEC) {
1252 request->reply->src_ipaddr = request->client->src_ipaddr;
1256 if (rad_send(request->reply, request->packet,
1257 request->client->secret) < 0) {
1258 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1267 #ifdef WITH_ACCOUNTING
1269 * Send an accounting response packet (or not)
1271 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
1273 rad_assert(request->listener == listener);
1274 rad_assert(listener->send == acct_socket_send);
1277 * Accounting reject's are silently dropped.
1279 * We do it here to avoid polluting the rest of the
1280 * code with this knowledge
1282 if (request->reply->code == 0) return 0;
1284 #ifdef WITH_UDPFROMTO
1286 * Overwrite the src ip address on the outbound packet
1287 * with the one specified by the client.
1288 * This is useful to work around broken DSR implementations
1289 * and other routing issues.
1291 if (request->client->src_ipaddr.af != AF_UNSPEC) {
1292 request->reply->src_ipaddr = request->client->src_ipaddr;
1296 if (rad_send(request->reply, request->packet,
1297 request->client->secret) < 0) {
1298 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1309 * Send a packet to a home server.
1311 * FIXME: have different code for proxy auth & acct!
1313 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
1315 rad_assert(request->proxy_listener == listener);
1316 rad_assert(listener->send == proxy_socket_send);
1318 if (rad_send(request->proxy, NULL,
1319 request->home_server->secret) < 0) {
1320 radlog_request(L_ERR, 0, request, "Failed sending proxied request: %s",
1331 * Check if an incoming request is "ok"
1333 * It takes packets, not requests. It sees if the packet looks
1334 * OK. If so, it does a number of sanity checks on it.
1336 static int stats_socket_recv(rad_listen_t *listener)
1340 RADIUS_PACKET *packet;
1341 RADCLIENT *client = NULL;
1342 fr_ipaddr_t src_ipaddr;
1344 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1345 if (rcode < 0) return 0;
1347 FR_STATS_INC(auth, total_requests);
1349 if (rcode < 20) { /* AUTH_HDR_LEN */
1350 FR_STATS_INC(auth, total_malformed_requests);
1354 if ((client = client_listener_find(listener,
1355 &src_ipaddr, src_port)) == NULL) {
1356 rad_recv_discard(listener->fd);
1357 FR_STATS_INC(auth, total_invalid_requests);
1361 FR_STATS_TYPE_INC(client->auth.total_requests);
1364 * We only understand Status-Server on this socket.
1366 if (code != PW_STATUS_SERVER) {
1367 DEBUG("Ignoring packet code %d sent to Status-Server port",
1369 rad_recv_discard(listener->fd);
1370 FR_STATS_INC(auth, total_unknown_types);
1375 * Now that we've sanity checked everything, receive the
1378 packet = rad_recv(listener->fd, 1); /* require message authenticator */
1380 FR_STATS_INC(auth, total_malformed_requests);
1381 DEBUG("%s", fr_strerror());
1385 if (!request_receive(listener, packet, client, rad_status_server)) {
1386 FR_STATS_INC(auth, total_packets_dropped);
1397 * Check if an incoming request is "ok"
1399 * It takes packets, not requests. It sees if the packet looks
1400 * OK. If so, it does a number of sanity checks on it.
1402 static int auth_socket_recv(rad_listen_t *listener)
1406 RADIUS_PACKET *packet;
1407 RAD_REQUEST_FUNP fun = NULL;
1408 RADCLIENT *client = NULL;
1409 fr_ipaddr_t src_ipaddr;
1411 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1412 if (rcode < 0) return 0;
1414 FR_STATS_INC(auth, total_requests);
1416 if (rcode < 20) { /* AUTH_HDR_LEN */
1417 FR_STATS_INC(auth, total_malformed_requests);
1421 if ((client = client_listener_find(listener,
1422 &src_ipaddr, src_port)) == NULL) {
1423 rad_recv_discard(listener->fd);
1424 FR_STATS_INC(auth, total_invalid_requests);
1428 FR_STATS_TYPE_INC(client->auth.total_requests);
1431 * Some sanity checks, based on the packet code.
1434 case PW_AUTHENTICATION_REQUEST:
1435 fun = rad_authenticate;
1438 case PW_STATUS_SERVER:
1439 if (!mainconfig.status_server) {
1440 rad_recv_discard(listener->fd);
1441 FR_STATS_INC(auth, total_unknown_types);
1442 DEBUGW("Ignoring Status-Server request due to security configuration");
1445 fun = rad_status_server;
1449 rad_recv_discard(listener->fd);
1450 FR_STATS_INC(auth,total_unknown_types);
1452 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
1453 code, client->shortname, src_port);
1456 } /* switch over packet types */
1459 * Now that we've sanity checked everything, receive the
1462 packet = rad_recv(listener->fd, client->message_authenticator);
1464 FR_STATS_INC(auth, total_malformed_requests);
1465 DEBUG("%s", fr_strerror());
1469 if (!request_receive(listener, packet, client, fun)) {
1470 FR_STATS_INC(auth, total_packets_dropped);
1479 #ifdef WITH_ACCOUNTING
1481 * Receive packets from an accounting socket
1483 static int acct_socket_recv(rad_listen_t *listener)
1487 RADIUS_PACKET *packet;
1488 RAD_REQUEST_FUNP fun = NULL;
1489 RADCLIENT *client = NULL;
1490 fr_ipaddr_t src_ipaddr;
1492 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1493 if (rcode < 0) return 0;
1495 FR_STATS_INC(acct, total_requests);
1497 if (rcode < 20) { /* AUTH_HDR_LEN */
1498 FR_STATS_INC(acct, total_malformed_requests);
1502 if ((client = client_listener_find(listener,
1503 &src_ipaddr, src_port)) == NULL) {
1504 rad_recv_discard(listener->fd);
1505 FR_STATS_INC(acct, total_invalid_requests);
1509 FR_STATS_TYPE_INC(client->acct.total_requests);
1512 * Some sanity checks, based on the packet code.
1515 case PW_ACCOUNTING_REQUEST:
1516 fun = rad_accounting;
1519 case PW_STATUS_SERVER:
1520 if (!mainconfig.status_server) {
1521 rad_recv_discard(listener->fd);
1522 FR_STATS_INC(acct, total_unknown_types);
1524 DEBUGW("Ignoring Status-Server request due to security configuration");
1527 fun = rad_status_server;
1531 rad_recv_discard(listener->fd);
1532 FR_STATS_INC(acct, total_unknown_types);
1534 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1535 code, client->shortname, src_port);
1537 } /* switch over packet types */
1540 * Now that we've sanity checked everything, receive the
1543 packet = rad_recv(listener->fd, 0);
1545 FR_STATS_INC(acct, total_malformed_requests);
1546 radlog(L_ERR, "%s", fr_strerror());
1551 * There can be no duplicate accounting packets.
1553 if (!request_receive(listener, packet, client, fun)) {
1554 FR_STATS_INC(acct, total_packets_dropped);
1565 static int do_proxy(REQUEST *request)
1569 if (request->in_proxy_hash ||
1570 (request->proxy_reply && (request->proxy_reply->code != 0))) {
1574 vp = pairfind(request->config_items, PW_HOME_SERVER_POOL, 0, TAG_ANY);
1577 if (!home_pool_byname(vp->vp_strvalue, HOME_TYPE_COA)) {
1578 RDEBUG2E("Cannot proxy to unknown pool %s",
1587 * Receive a CoA packet.
1589 static int rad_coa_recv(REQUEST *request)
1591 int rcode = RLM_MODULE_OK;
1596 * Get the correct response
1598 switch (request->packet->code) {
1599 case PW_COA_REQUEST:
1604 case PW_DISCONNECT_REQUEST:
1605 ack = PW_DISCONNECT_ACK;
1606 nak = PW_DISCONNECT_NAK;
1609 default: /* shouldn't happen */
1610 return RLM_MODULE_FAIL;
1614 #define WAS_PROXIED (request->proxy)
1616 #define WAS_PROXIED (0)
1621 * RFC 5176 Section 3.3. If we have a CoA-Request
1622 * with Service-Type = Authorize-Only, it MUST
1623 * have a State attribute in it.
1625 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE, 0, TAG_ANY);
1626 if (request->packet->code == PW_COA_REQUEST) {
1627 if (vp && (vp->vp_integer == 17)) {
1628 vp = pairfind(request->packet->vps, PW_STATE, 0, TAG_ANY);
1629 if (!vp || (vp->length == 0)) {
1630 RDEBUGE("CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1631 request->reply->code = PW_COA_NAK;
1632 return RLM_MODULE_FAIL;
1637 * RFC 5176, Section 3.2.
1639 RDEBUGE("Disconnect-Request MUST NOT contain a Service-Type attribute");
1640 request->reply->code = PW_DISCONNECT_NAK;
1641 return RLM_MODULE_FAIL;
1644 rcode = module_recv_coa(0, request);
1646 case RLM_MODULE_FAIL:
1647 case RLM_MODULE_INVALID:
1648 case RLM_MODULE_REJECT:
1649 case RLM_MODULE_USERLOCK:
1651 request->reply->code = nak;
1654 case RLM_MODULE_HANDLED:
1657 case RLM_MODULE_NOOP:
1658 case RLM_MODULE_NOTFOUND:
1660 case RLM_MODULE_UPDATED:
1661 if (do_proxy(request)) return RLM_MODULE_OK;
1662 request->reply->code = ack;
1665 } else if (request->proxy_reply) {
1667 * Start the reply code with the proxy reply
1670 request->reply->code = request->proxy_reply->code;
1674 * Copy State from the request to the reply.
1675 * See RFC 5176 Section 3.3.
1677 vp = paircopy2(request->packet->vps, PW_STATE, 0, TAG_ANY);
1678 if (vp) pairadd(&request->reply->vps, vp);
1681 * We may want to over-ride the reply.
1683 if (request->reply->code) {
1684 rcode = module_send_coa(0, request);
1687 * We need to send CoA-NAK back if Service-Type
1688 * is Authorize-Only. Rely on the user's policy
1689 * to do that. We're not a real NAS, so this
1690 * restriction doesn't (ahem) apply to us.
1692 case RLM_MODULE_FAIL:
1693 case RLM_MODULE_INVALID:
1694 case RLM_MODULE_REJECT:
1695 case RLM_MODULE_USERLOCK:
1698 * Over-ride an ACK with a NAK
1700 request->reply->code = nak;
1703 case RLM_MODULE_HANDLED:
1706 case RLM_MODULE_NOOP:
1707 case RLM_MODULE_NOTFOUND:
1709 case RLM_MODULE_UPDATED:
1711 * Do NOT over-ride a previously set value.
1712 * Otherwise an "ok" here will re-write a
1715 if (request->reply->code == 0) {
1716 request->reply->code = ack;
1722 return RLM_MODULE_OK;
1727 * Check if an incoming request is "ok"
1729 * It takes packets, not requests. It sees if the packet looks
1730 * OK. If so, it does a number of sanity checks on it.
1732 static int coa_socket_recv(rad_listen_t *listener)
1736 RADIUS_PACKET *packet;
1737 RAD_REQUEST_FUNP fun = NULL;
1738 RADCLIENT *client = NULL;
1739 fr_ipaddr_t src_ipaddr;
1741 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1742 if (rcode < 0) return 0;
1744 if (rcode < 20) { /* AUTH_HDR_LEN */
1745 FR_STATS_INC(coa, total_requests);
1746 FR_STATS_INC(coa, total_malformed_requests);
1750 if ((client = client_listener_find(listener,
1751 &src_ipaddr, src_port)) == NULL) {
1752 rad_recv_discard(listener->fd);
1753 FR_STATS_INC(coa, total_requests);
1754 FR_STATS_INC(coa, total_invalid_requests);
1759 * Some sanity checks, based on the packet code.
1762 case PW_COA_REQUEST:
1763 FR_STATS_INC(coa, total_requests);
1767 case PW_DISCONNECT_REQUEST:
1768 FR_STATS_INC(dsc, total_requests);
1773 rad_recv_discard(listener->fd);
1774 FR_STATS_INC(coa, total_unknown_types);
1775 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1776 code, client->shortname, src_port);
1778 } /* switch over packet types */
1781 * Now that we've sanity checked everything, receive the
1784 packet = rad_recv(listener->fd, client->message_authenticator);
1786 FR_STATS_INC(coa, total_malformed_requests);
1787 DEBUG("%s", fr_strerror());
1791 if (!request_receive(listener, packet, client, fun)) {
1792 FR_STATS_INC(coa, total_packets_dropped);
1803 * Recieve packets from a proxy socket.
1805 static int proxy_socket_recv(rad_listen_t *listener)
1807 RADIUS_PACKET *packet;
1810 packet = rad_recv(listener->fd, 0);
1812 radlog(L_ERR, "%s", fr_strerror());
1817 * FIXME: Client MIB updates?
1819 switch(packet->code) {
1820 case PW_AUTHENTICATION_ACK:
1821 case PW_ACCESS_CHALLENGE:
1822 case PW_AUTHENTICATION_REJECT:
1825 #ifdef WITH_ACCOUNTING
1826 case PW_ACCOUNTING_RESPONSE:
1831 case PW_DISCONNECT_ACK:
1832 case PW_DISCONNECT_NAK:
1840 * FIXME: Update MIB for packet types?
1842 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1843 "from home server %s port %d - ID %d : IGNORED",
1845 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1846 packet->src_port, packet->id);
1851 if (!request_proxy_reply(packet)) {
1861 * Recieve packets from a proxy socket.
1863 static int proxy_socket_tcp_recv(rad_listen_t *listener)
1865 RADIUS_PACKET *packet;
1866 listen_socket_t *sock = listener->data;
1869 packet = fr_tcp_recv(listener->fd, 0);
1871 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
1872 event_new_fd(listener);
1877 * FIXME: Client MIB updates?
1879 switch(packet->code) {
1880 case PW_AUTHENTICATION_ACK:
1881 case PW_ACCESS_CHALLENGE:
1882 case PW_AUTHENTICATION_REJECT:
1885 #ifdef WITH_ACCOUNTING
1886 case PW_ACCOUNTING_RESPONSE:
1892 * FIXME: Update MIB for packet types?
1894 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1895 "from home server %s port %d - ID %d : IGNORED",
1897 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1898 packet->src_port, packet->id);
1903 packet->src_ipaddr = sock->other_ipaddr;
1904 packet->src_port = sock->other_port;
1905 packet->dst_ipaddr = sock->my_ipaddr;
1906 packet->dst_port = sock->my_port;
1909 * FIXME: Have it return an indication of packets that
1910 * are OK to ignore (dups, too late), versus ones that
1911 * aren't OK to ignore (unknown response, spoofed, etc.)
1913 * Close the socket on bad packets...
1915 if (!request_proxy_reply(packet)) {
1920 sock->opened = sock->last_packet = time(NULL);
1928 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1930 if (!request->reply->code) return 0;
1932 if (rad_encode(request->reply, request->packet,
1933 request->client->secret) < 0) {
1934 radlog_request(L_ERR, 0, request, "Failed encoding packet: %s",
1939 if (rad_sign(request->reply, request->packet,
1940 request->client->secret) < 0) {
1941 radlog_request(L_ERR, 0, request, "Failed signing packet: %s",
1950 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1952 if (rad_verify(request->packet, NULL,
1953 request->client->secret) < 0) {
1957 return rad_decode(request->packet, NULL,
1958 request->client->secret);
1962 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1964 if (rad_encode(request->proxy, NULL, request->home_server->secret) < 0) {
1965 radlog_request(L_ERR, 0, request, "Failed encoding proxied packet: %s",
1970 if (rad_sign(request->proxy, NULL, request->home_server->secret) < 0) {
1971 radlog_request(L_ERR, 0, request, "Failed signing proxied packet: %s",
1980 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1983 * rad_verify is run in event.c, received_proxy_response()
1986 return rad_decode(request->proxy_reply, request->proxy,
1987 request->home_server->secret);
1993 #include "command.c"
1995 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1997 { common_socket_parse, NULL,
1998 stats_socket_recv, auth_socket_send,
1999 socket_print, client_socket_encode, client_socket_decode },
2002 * This always gets defined.
2004 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
2009 { common_socket_parse, NULL,
2010 proxy_socket_recv, proxy_socket_send,
2011 socket_print, proxy_socket_encode, proxy_socket_decode },
2014 /* authentication */
2015 { common_socket_parse, NULL,
2016 auth_socket_recv, auth_socket_send,
2017 socket_print, client_socket_encode, client_socket_decode },
2019 #ifdef WITH_ACCOUNTING
2021 { common_socket_parse, NULL,
2022 acct_socket_recv, acct_socket_send,
2023 socket_print, client_socket_encode, client_socket_decode},
2028 { detail_parse, detail_free,
2029 detail_recv, detail_send,
2030 detail_print, detail_encode, detail_decode },
2034 /* vlan query protocol */
2035 { common_socket_parse, NULL,
2036 vqp_socket_recv, vqp_socket_send,
2037 socket_print, vqp_socket_encode, vqp_socket_decode },
2041 /* dhcp query protocol */
2042 { dhcp_socket_parse, NULL,
2043 dhcp_socket_recv, dhcp_socket_send,
2044 socket_print, dhcp_socket_encode, dhcp_socket_decode },
2047 #ifdef WITH_COMMAND_SOCKET
2048 /* TCP command socket */
2049 { command_socket_parse, command_socket_free,
2050 command_domain_accept, command_domain_send,
2051 command_socket_print, command_socket_encode, command_socket_decode },
2055 /* Change of Authorization */
2056 { common_socket_parse, NULL,
2057 coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
2058 socket_print, client_socket_encode, client_socket_decode },
2066 * Binds a listener to a socket.
2068 static int listen_bind(rad_listen_t *this)
2071 struct sockaddr_storage salocal;
2073 listen_socket_t *sock = this->data;
2075 #define proto_for_port "udp"
2076 #define sock_type SOCK_DGRAM
2078 const char *proto_for_port = "udp";
2079 int sock_type = SOCK_DGRAM;
2081 if (sock->proto == IPPROTO_TCP) {
2083 if (this->type == RAD_LISTEN_VQP) {
2084 radlog(L_ERR, "VQP does not support TCP transport");
2089 proto_for_port = "tcp";
2090 sock_type = SOCK_STREAM;
2095 * If the port is zero, then it means the appropriate
2096 * thing from /etc/services.
2098 if (sock->my_port == 0) {
2099 struct servent *svp;
2101 switch (this->type) {
2102 case RAD_LISTEN_AUTH:
2103 svp = getservbyname ("radius", proto_for_port);
2105 sock->my_port = ntohs(svp->s_port);
2107 sock->my_port = PW_AUTH_UDP_PORT;
2111 #ifdef WITH_ACCOUNTING
2112 case RAD_LISTEN_ACCT:
2113 svp = getservbyname ("radacct", proto_for_port);
2115 sock->my_port = ntohs(svp->s_port);
2117 sock->my_port = PW_ACCT_UDP_PORT;
2123 case RAD_LISTEN_PROXY:
2124 /* leave it at zero */
2129 case RAD_LISTEN_VQP:
2130 sock->my_port = 1589;
2134 #ifdef WITH_COMMAND_SOCKET
2135 case RAD_LISTEN_COMMAND:
2136 sock->my_port = PW_RADMIN_PORT;
2141 case RAD_LISTEN_COA:
2142 svp = getservbyname ("radius-dynauth", "udp");
2144 sock->my_port = ntohs(svp->s_port);
2146 sock->my_port = PW_COA_UDP_PORT;
2152 DEBUGW("Internal sanity check failed in binding to socket. Ignoring problem.");
2158 * Don't open sockets if we're checking the config.
2166 * Copy fr_socket() here, as we may need to bind to a device.
2168 this->fd = socket(sock->my_ipaddr.af, sock_type, 0);
2172 this->print(this, buffer, sizeof(buffer));
2174 radlog(L_ERR, "Failed opening %s: %s", buffer, strerror(errno));
2180 * We don't want child processes inheriting these
2183 rcode = fcntl(this->fd, F_GETFD);
2185 if (fcntl(this->fd, F_SETFD, rcode | FD_CLOEXEC) < 0) {
2187 radlog(L_ERR, "Failed setting close on exec: %s", strerror(errno));
2194 * Bind to a device BEFORE touching IP addresses.
2196 if (sock->interface) {
2197 #ifdef SO_BINDTODEVICE
2200 memset(&ifreq, 0, sizeof(ifreq));
2201 strlcpy(ifreq.ifr_name, sock->interface, sizeof(ifreq.ifr_name));
2204 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
2205 (char *)&ifreq, sizeof(ifreq));
2209 radlog(L_ERR, "Failed binding to interface %s: %s",
2210 sock->interface, strerror(errno));
2212 } /* else it worked. */
2214 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2215 #ifdef HAVE_NET_IF_H
2217 * Odds are that any system supporting "bind to
2218 * device" also supports IPv6, so this next bit
2219 * isn't necessary. But it's here for
2222 * If we're doing IPv6, and the scope hasn't yet
2223 * been defined, set the scope to the scope of
2226 if (sock->my_ipaddr.af == AF_INET6) {
2227 if (sock->my_ipaddr.scope == 0) {
2228 sock->my_ipaddr.scope = if_nametoindex(sock->interface);
2229 if (sock->my_ipaddr.scope == 0) {
2231 radlog(L_ERR, "Failed finding interface %s: %s",
2232 sock->interface, strerror(errno));
2235 } /* else scope was defined: we're OK. */
2240 * IPv4: no link local addresses,
2241 * and no bind to device.
2245 radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
2252 if (sock->proto == IPPROTO_TCP) {
2255 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2257 radlog(L_ERR, "Failed to reuse address: %s", strerror(errno));
2263 #if defined(WITH_TCP) && defined(WITH_UDPFROMTO)
2264 else /* UDP sockets get UDPfromto */
2267 #ifdef WITH_UDPFROMTO
2269 * Initialize udpfromto for all sockets.
2271 if (udpfromto_init(this->fd) != 0) {
2272 radlog(L_ERR, "Failed initializing udpfromto: %s",
2280 * Set up sockaddr stuff.
2282 if (!fr_ipaddr2sockaddr(&sock->my_ipaddr, sock->my_port, &salocal, &salen)) {
2287 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2288 if (sock->my_ipaddr.af == AF_INET6) {
2290 * Listening on '::' does NOT get you IPv4 to
2291 * IPv6 mapping. You've got to listen on an IPv4
2292 * address, too. This makes the rest of the server
2293 * design a little simpler.
2297 if (IN6_IS_ADDR_UNSPECIFIED(&sock->my_ipaddr.ipaddr.ip6addr)) {
2300 if (setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
2301 (char *)&on, sizeof(on)) < 0) {
2302 radlog(L_ERR, "Failed setting socket to IPv6 "
2303 "only: %s", strerror(errno));
2309 #endif /* IPV6_V6ONLY */
2311 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
2313 if (sock->my_ipaddr.af == AF_INET) {
2316 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
2318 * Disable PMTU discovery. On Linux, this
2319 * also makes sure that the "don't fragment"
2322 flag = IP_PMTUDISC_DONT;
2323 if (setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
2324 &flag, sizeof(flag)) < 0) {
2325 radlog(L_ERR, "Failed disabling PMTU discovery: %s",
2333 #if defined(IP_DONTFRAG)
2335 * Ensure that the "don't fragment" flag is zero.
2338 if (setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
2339 &flag, sizeof(flag)) < 0) {
2340 radlog(L_ERR, "Failed setting don't fragment flag: %s",
2351 if (sock->broadcast) {
2354 if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
2355 radlog(L_ERR, "Can't set broadcast option: %s",
2364 * May be binding to priviledged ports.
2366 if (sock->my_port != 0) {
2370 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2371 radlog(L_ERR, "Can't set re-use address option: %s",
2378 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
2384 this->print(this, buffer, sizeof(buffer));
2385 radlog(L_ERR, "Failed binding to %s: %s\n",
2386 buffer, strerror(errno));
2391 * FreeBSD jail issues. We bind to 0.0.0.0, but the
2392 * kernel instead binds us to a 1.2.3.4. If this
2393 * happens, notice, and remember our real IP.
2396 struct sockaddr_storage src;
2397 socklen_t sizeof_src = sizeof(src);
2399 memset(&src, 0, sizeof_src);
2400 if (getsockname(this->fd, (struct sockaddr *) &src,
2402 radlog(L_ERR, "Failed getting socket name: %s",
2407 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2408 &sock->my_ipaddr, &sock->my_port)) {
2409 radlog(L_ERR, "Socket has unsupported address family");
2416 if (sock->proto == IPPROTO_TCP) {
2417 if (listen(this->fd, 8) < 0) {
2419 radlog(L_ERR, "Failed in listen(): %s", strerror(errno));
2425 if (fr_nonblock(this->fd) < 0) {
2427 radlog(L_ERR, "Failed setting non-blocking on socket: %s",
2433 * Mostly for proxy sockets.
2435 sock->other_ipaddr.af = sock->my_ipaddr.af;
2438 * Don't screw up other people.
2440 #undef proto_for_port
2448 * Allocate & initialize a new listener.
2450 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
2454 this = rad_malloc(sizeof(*this));
2455 memset(this, 0, sizeof(*this));
2458 this->recv = master_listen[this->type].recv;
2459 this->send = master_listen[this->type].send;
2460 this->print = master_listen[this->type].print;
2461 this->encode = master_listen[this->type].encode;
2462 this->decode = master_listen[this->type].decode;
2466 case RAD_LISTEN_NONE:
2468 case RAD_LISTEN_AUTH:
2469 #ifdef WITH_ACCOUNTING
2470 case RAD_LISTEN_ACCT:
2473 case RAD_LISTEN_PROXY:
2476 case RAD_LISTEN_VQP:
2479 case RAD_LISTEN_COA:
2481 this->data = rad_malloc(sizeof(listen_socket_t));
2482 memset(this->data, 0, sizeof(listen_socket_t));
2486 case RAD_LISTEN_DHCP:
2487 this->data = rad_malloc(sizeof(dhcp_socket_t));
2488 memset(this->data, 0, sizeof(dhcp_socket_t));
2493 case RAD_LISTEN_DETAIL:
2498 #ifdef WITH_COMMAND_SOCKET
2499 case RAD_LISTEN_COMMAND:
2500 this->data = rad_malloc(sizeof(fr_command_socket_t));
2501 memset(this->data, 0, sizeof(fr_command_socket_t));
2506 rad_assert("Unsupported option!" == NULL);
2515 * Externally visible function for creating a new proxy LISTENER.
2517 * Not thread-safe, but all calls to it are protected by the
2518 * proxy mutex in event.c
2520 int proxy_new_listener(home_server *home, int src_port)
2523 listen_socket_t *sock;
2526 if (!home) return 0;
2528 if ((home->limit.max_connections > 0) &&
2529 (home->limit.num_connections >= home->limit.max_connections)) {
2530 DEBUGW("Home server has too many open connections (%d)",
2531 home->limit.max_connections);
2535 this = listen_alloc(RAD_LISTEN_PROXY);
2538 sock->other_ipaddr = home->ipaddr;
2539 sock->other_port = home->port;
2542 sock->my_ipaddr = home->src_ipaddr;
2543 sock->my_port = src_port;
2544 sock->proto = home->proto;
2546 if (debug_flag >= 2) {
2547 this->print(this, buffer, sizeof(buffer));
2548 DEBUG("Opening new %s", buffer);
2552 sock->opened = sock->last_packet = time(NULL);
2554 if (home->proto == IPPROTO_TCP) {
2555 this->recv = proxy_socket_tcp_recv;
2558 * FIXME: connect() is blocking!
2559 * We do this with the proxy mutex locked, which may
2560 * cause large delays!
2562 * http://www.developerweb.net/forum/showthread.php?p=13486
2564 this->fd = fr_tcp_client_socket(&home->src_ipaddr,
2565 &home->ipaddr, home->port);
2568 DEBUG("Trying SSL to port %d\n", home->port);
2569 sock->ssn = tls_new_client_session(home->tls, this->fd);
2575 this->recv = proxy_tls_recv;
2576 this->send = proxy_tls_send;
2581 this->fd = fr_socket(&home->src_ipaddr, src_port);
2584 this->print(this, buffer,sizeof(buffer));
2585 DEBUG("Failed opening client socket ::%s:: : %s",
2586 buffer, fr_strerror());
2592 * Figure out which port we were bound to.
2594 if (sock->my_port == 0) {
2595 struct sockaddr_storage src;
2596 socklen_t sizeof_src = sizeof(src);
2598 memset(&src, 0, sizeof_src);
2599 if (getsockname(this->fd, (struct sockaddr *) &src,
2601 radlog(L_ERR, "Failed getting socket name: %s",
2607 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2608 &sock->my_ipaddr, &sock->my_port)) {
2609 radlog(L_ERR, "Socket has unsupported address family");
2616 * Tell the event loop that we have a new FD
2618 if (!event_new_fd(this)) {
2628 static const FR_NAME_NUMBER listen_compare[] = {
2630 { "status", RAD_LISTEN_NONE },
2632 { "auth", RAD_LISTEN_AUTH },
2633 #ifdef WITH_ACCOUNTING
2634 { "acct", RAD_LISTEN_ACCT },
2637 { "detail", RAD_LISTEN_DETAIL },
2640 { "proxy", RAD_LISTEN_PROXY },
2643 { "vmps", RAD_LISTEN_VQP },
2646 { "dhcp", RAD_LISTEN_DHCP },
2648 #ifdef WITH_COMMAND_SOCKET
2649 { "control", RAD_LISTEN_COMMAND },
2652 { "coa", RAD_LISTEN_COA },
2658 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
2666 cf_log_info(cs, "listen {");
2668 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
2670 if (rcode < 0) return NULL;
2673 cf_log_err(cf_sectiontoitem(cs),
2674 "No type specified in listen section");
2678 type = fr_str2int(listen_compare, listen_type, -1);
2680 cf_log_err(cf_sectiontoitem(cs),
2681 "Invalid type \"%s\" in listen section.",
2689 * Allow listen sections in the default config to
2690 * refer to a server.
2693 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
2695 if (rcode == 1) { /* compatiblity with 2.0-pre */
2696 rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
2699 if (rcode < 0) return NULL;
2704 * We were passed a virtual server, so the caller is
2705 * defining a proxy listener inside of a virtual server.
2706 * This isn't allowed right now.
2708 else if (type == RAD_LISTEN_PROXY) {
2709 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2715 * Set up cross-type data.
2717 this = listen_alloc(type);
2718 this->server = server;
2722 * Call per-type parser.
2724 if (master_listen[type].parse(cs, this) < 0) {
2729 cf_log_info(cs, "}");
2735 static int is_loopback(const fr_ipaddr_t *ipaddr)
2738 * We shouldn't proxy on loopback.
2740 if ((ipaddr->af == AF_INET) &&
2741 (ipaddr->ipaddr.ip4addr.s_addr == htonl(INADDR_LOOPBACK))) {
2745 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2746 if ((ipaddr->af == AF_INET6) &&
2747 (IN6_IS_ADDR_LINKLOCAL(&ipaddr->ipaddr.ip6addr))) {
2757 * Generate a list of listeners. Takes an input list of
2758 * listeners, too, so we don't close sockets with waiting packets.
2760 int listen_init(CONF_SECTION *config, rad_listen_t **head, int spawn_flag)
2762 int override = FALSE;
2764 CONF_SECTION *cs = NULL;
2765 rad_listen_t **last;
2767 fr_ipaddr_t server_ipaddr;
2770 int defined_proxy = 0;
2773 spawn_flag = spawn_flag; /* -Wunused */
2777 * We shouldn't be called with a pre-existing list.
2779 rad_assert(head && (*head == NULL));
2782 server_ipaddr.af = AF_UNSPEC;
2785 * If the port is specified on the command-line,
2786 * it over-rides the configuration file.
2788 * FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
2790 if (mainconfig.port >= 0) auth_port = mainconfig.port;
2793 * If the IP address was configured on the command-line,
2794 * use that as the "bind_address"
2796 if (mainconfig.myip.af != AF_UNSPEC) {
2797 memcpy(&server_ipaddr, &mainconfig.myip,
2798 sizeof(server_ipaddr));
2804 * Else look for bind_address and/or listen sections.
2806 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
2807 rcode = cf_item_parse(config, "bind_address",
2809 &server_ipaddr.ipaddr.ip4addr, NULL);
2810 if (rcode < 0) return -1; /* error parsing it */
2812 if (rcode == 0) { /* successfully parsed IPv4 */
2813 listen_socket_t *sock;
2815 memset(&server_ipaddr, 0, sizeof(server_ipaddr));
2816 server_ipaddr.af = AF_INET;
2818 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'.");
2822 if (strcmp(progname, "vmpsd") == 0) {
2823 this = listen_alloc(RAD_LISTEN_VQP);
2824 if (!auth_port) auth_port = 1589;
2827 this = listen_alloc(RAD_LISTEN_AUTH);
2831 sock->my_ipaddr = server_ipaddr;
2832 sock->my_port = auth_port;
2834 sock->clients = clients_parse_section(config);
2835 if (!sock->clients) {
2836 cf_log_err(cf_sectiontoitem(config),
2837 "Failed to find any clients for this listen section");
2842 if (listen_bind(this) < 0) {
2844 radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->my_port);
2848 auth_port = sock->my_port; /* may have been updated in listen_bind */
2850 cs = cf_section_sub_find_name2(config, "server",
2852 if (cs) this->server = mainconfig.name;
2856 last = &(this->next);
2862 if (strcmp(progname, "vmpsd") == 0) goto add_sockets;
2865 #ifdef WITH_ACCOUNTING
2867 * Open Accounting Socket.
2869 * If we haven't already gotten acct_port from
2870 * /etc/services, then make it auth_port + 1.
2872 this = listen_alloc(RAD_LISTEN_ACCT);
2876 * Create the accounting socket.
2878 * The accounting port is always the
2879 * authentication port + 1
2881 sock->my_ipaddr = server_ipaddr;
2882 sock->my_port = auth_port + 1;
2884 sock->clients = clients_parse_section(config);
2885 if (!sock->clients) {
2886 cf_log_err(cf_sectiontoitem(config),
2887 "Failed to find any clients for this listen section");
2891 if (listen_bind(this) < 0) {
2894 radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->my_port);
2899 cs = cf_section_sub_find_name2(config, "server",
2901 if (cs) this->server = mainconfig.name;
2905 last = &(this->next);
2907 } else if (mainconfig.port > 0) { /* no bind address, but a port */
2908 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2914 * They specified an IP on the command-line, ignore
2915 * all listen sections except the one in '-n'.
2917 if (mainconfig.myip.af != AF_UNSPEC) {
2918 CONF_SECTION *subcs;
2919 const char *name2 = cf_section_name2(cs);
2921 cs = cf_section_sub_find_name2(config, "server",
2923 if (!cs) goto add_sockets;
2926 * Should really abstract this code...
2928 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2930 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2931 this = listen_parse(subcs, name2);
2938 last = &(this->next);
2939 } /* loop over "listen" directives in server <foo> */
2945 * Walk through the "listen" sections, if they exist.
2947 for (cs = cf_subsection_find_next(config, NULL, "listen");
2949 cs = cf_subsection_find_next(config, cs, "listen")) {
2950 this = listen_parse(cs, NULL);
2957 last = &(this->next);
2961 * Check virtual servers for "listen" sections, too.
2963 * FIXME: Move to virtual server init?
2965 for (cs = cf_subsection_find_next(config, NULL, "server");
2967 cs = cf_subsection_find_next(config, cs, "server")) {
2968 CONF_SECTION *subcs;
2969 const char *name2 = cf_section_name2(cs);
2971 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2973 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2974 this = listen_parse(subcs, name2);
2981 last = &(this->next);
2982 } /* loop over "listen" directives in virtual servers */
2983 } /* loop over virtual servers */
2987 * No sockets to receive packets, this is an error.
2988 * proxying is pointless.
2991 radlog(L_ERR, "The server is not configured to listen on any ports. Cannot start.");
2996 * Print out which sockets we're listening on, and
2997 * add them to the event list.
2999 for (this = *head; this != NULL; this = this->next) {
3001 if (this->type == RAD_LISTEN_PROXY) {
3008 if (!spawn_flag && this->tls) {
3009 cf_log_err(cf_sectiontoitem(this->cs), "Threading must be enabled for TLS sockets to function properly.");
3010 cf_log_err(cf_sectiontoitem(this->cs), "You probably need to do 'radiusd -fxx -l stdout' for debugging");
3014 if (!check_config) event_new_fd(this);
3018 * If we're proxying requests, open the proxy FD.
3019 * Otherwise, don't do anything.
3022 if ((mainconfig.proxy_requests == TRUE) &&
3024 (*head != NULL) && !defined_proxy) {
3025 listen_socket_t *sock = NULL;
3029 memset(&home, 0, sizeof(home));
3034 home.proto = IPPROTO_UDP;
3035 home.src_ipaddr = server_ipaddr;
3038 * Find the first authentication port,
3041 for (this = *head; this != NULL; this = this->next) {
3042 if (this->type == RAD_LISTEN_AUTH) {
3045 if (is_loopback(&sock->my_ipaddr)) continue;
3047 if (home.src_ipaddr.af == AF_UNSPEC) {
3048 home.src_ipaddr = sock->my_ipaddr;
3050 port = sock->my_port + 2;
3054 if (this->type == RAD_LISTEN_ACCT) {
3057 if (is_loopback(&sock->my_ipaddr)) continue;
3059 if (home.src_ipaddr.af == AF_UNSPEC) {
3060 home.src_ipaddr = sock->my_ipaddr;
3062 port = sock->my_port + 1;
3069 * Address is still unspecified, use IPv4.
3071 if (home.src_ipaddr.af == AF_UNSPEC) {
3072 home.src_ipaddr.af = AF_INET;
3073 /* everything else is already set to zero */
3076 home.ipaddr.af = home.src_ipaddr.af;
3077 /* everything else is already set to zero */
3079 if (!proxy_new_listener(&home, port)) {
3087 * Haven't defined any sockets. Die.
3089 if (!*head) return -1;
3091 xlat_register("listen", xlat_listen, NULL);
3097 * Free a linked list of listeners;
3099 void listen_free(rad_listen_t **head)
3103 if (!head || !*head) return;
3107 rad_listen_t *next = this->next;
3110 * Other code may have eaten the FD.
3112 if (this->fd >= 0) close(this->fd);
3114 if (master_listen[this->type].free) {
3115 master_listen[this->type].free(this);
3119 if ((this->type == RAD_LISTEN_AUTH)
3121 || (this->type == RAD_LISTEN_ACCT)
3124 || (this->type == RAD_LISTEN_PROXY)
3127 listen_socket_t *sock = this->data;
3130 if (sock->request) {
3131 pthread_mutex_destroy(&(sock->mutex));
3132 request_free(&sock->request);
3133 sock->packet = NULL;
3135 if (sock->ssn) session_free(sock->ssn);
3136 request_free(&sock->request);
3139 rad_free(&sock->packet);
3142 #endif /* WITH_TCP */
3154 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
3159 for (this = mainconfig.listen; this != NULL; this = this->next) {
3160 listen_socket_t *sock;
3162 if ((this->type != RAD_LISTEN_AUTH)
3163 #ifdef WITH_ACCOUNTING
3164 && (this->type != RAD_LISTEN_ACCT)
3170 if ((sock->my_port == port) &&
3171 (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) == 0)) {
3172 return sock->clients;
3180 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port, int proto)
3184 for (this = mainconfig.listen; this != NULL; this = this->next) {
3185 listen_socket_t *sock;
3189 if (sock->my_port != port) continue;
3190 if (sock->proto != proto) continue;
3191 if (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) != 0) continue;
3197 * Failed to find a specific one. Find INADDR_ANY
3199 for (this = mainconfig.listen; this != NULL; this = this->next) {
3200 listen_socket_t *sock;
3204 if (sock->my_port != port) continue;
3205 if (sock->proto != proto) continue;
3206 if (!fr_inaddr_any(&sock->my_ipaddr)) continue;