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/radius_snmp.h>
29 #include <freeradius-devel/modules.h>
30 #include <freeradius-devel/rad_assert.h>
31 #include <freeradius-devel/vqp.h>
33 #include <sys/resource.h>
39 #ifdef HAVE_SYS_STAT_H
45 #define USEC (1000000)
48 * We'll use this below.
50 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
51 typedef void (*rad_listen_free_t)(rad_listen_t *);
53 typedef struct rad_listen_master_t {
54 rad_listen_parse_t parse;
55 rad_listen_free_t free;
56 rad_listen_recv_t recv;
57 rad_listen_send_t send;
58 rad_listen_print_t print;
59 rad_listen_encode_t encode;
60 rad_listen_decode_t decode;
61 } rad_listen_master_t;
63 typedef struct listen_socket_t {
69 RADCLIENT_LIST *clients;
72 typedef struct listen_detail_t {
78 lrad_ipaddr_t client_ip;
79 int load_factor; /* 1..100 */
85 struct timeval last_packet;
90 * Find a per-socket client.
92 static RADCLIENT *client_listener_find(const rad_listen_t *listener,
93 const lrad_ipaddr_t *ipaddr)
95 const RADCLIENT_LIST *clients;
97 rad_assert(listener != NULL);
98 rad_assert(ipaddr != NULL);
100 rad_assert((listener->type == RAD_LISTEN_AUTH) ||
101 (listener->type == RAD_LISTEN_ACCT) ||
102 (listener->type == RAD_LISTEN_VQP));
104 clients = ((listen_socket_t *)listener->data)->clients;
105 if (!clients) clients = mainconfig.clients;
107 rad_assert(clients != NULL);
109 return client_find(clients, ipaddr);
112 static int listen_bind(rad_listen_t *this);
115 * Process and reply to a server-status request.
116 * Like rad_authenticate and rad_accounting this should
117 * live in it's own file but it's so small we don't bother.
119 static int rad_status_server(REQUEST *request)
121 int rcode = RLM_MODULE_OK;
124 switch (request->listener->type) {
125 case RAD_LISTEN_AUTH:
126 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
128 rcode = module_authorize(dval->value, request);
130 rcode = RLM_MODULE_OK;
135 case RLM_MODULE_UPDATED:
136 request->reply->code = PW_AUTHENTICATION_ACK;
139 case RLM_MODULE_FAIL:
140 case RLM_MODULE_HANDLED:
141 request->reply->code = 0; /* don't reply */
145 case RLM_MODULE_REJECT:
146 request->reply->code = PW_AUTHENTICATION_REJECT;
151 case RAD_LISTEN_ACCT:
152 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
154 rcode = module_accounting(dval->value, request);
156 rcode = RLM_MODULE_OK;
161 case RLM_MODULE_UPDATED:
162 request->reply->code = PW_ACCOUNTING_RESPONSE;
166 request->reply->code = 0; /* don't reply */
179 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
182 listen_socket_t *sock = this->data;
184 if ((sock->ipaddr.af == AF_INET) &&
185 (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
188 ip_ntoh(&sock->ipaddr, buffer, bufsize);
191 len = strlen(buffer);
194 return len + snprintf(buffer + len, bufsize - len, " port %d",
198 return len + snprintf(buffer + len, bufsize - len, " port %d as server %s",
199 sock->port, this->server);
204 * Parse an authentication or accounting socket.
206 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
210 lrad_ipaddr_t ipaddr;
211 listen_socket_t *sock = this->data;
212 const char *section_name = NULL;
213 CONF_SECTION *client_cs;
218 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
219 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
220 &ipaddr.ipaddr.ip4addr, NULL);
221 if (rcode < 0) return -1;
223 if (rcode == 0) { /* successfully parsed IPv4 */
226 } else { /* maybe IPv6? */
227 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
228 &ipaddr.ipaddr.ip6addr, NULL);
229 if (rcode < 0) return -1;
232 radlog(L_ERR, "%s[%d]: No address specified in listen section",
233 cf_section_filename(cs), cf_section_lineno(cs));
236 ipaddr.af = AF_INET6;
239 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
241 if (rcode < 0) return -1;
243 sock->ipaddr = ipaddr;
244 sock->port = listen_port;
247 * And bind it to the port.
249 if (listen_bind(this) < 0) {
251 radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s port %d",
252 cf_section_filename(cs), cf_section_lineno(cs),
253 ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
259 * If we can bind to interfaces, do so,
262 if (cf_pair_find(cs, "interface")) {
263 #ifndef SO_BINDTODEVICE
264 radlog(L_CONS|L_ERR, "%s[%d]: System does not support binding to interfaces, delete this line from the configuration file.",
265 cf_section_filename(cs), cf_section_lineno(cs));
269 CONF_PAIR *cp = cf_pair_find(cs, "interface");
272 rad_assert(cp != NULL);
273 value = cf_pair_value(cp);
274 rad_assert(value != NULL);
276 strcpy(ifreq.ifr_name, value);
278 if (setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
279 (char *)&ifreq, sizeof(ifreq)) < 0) {
280 radlog(L_CONS|L_ERR, "%s[%d]: Failed binding to interface %s: %s",
281 cf_section_filename(cs), cf_section_lineno(cs),
282 value, strerror(errno));
284 } /* else it worked. */
289 * Look for the name of a section that holds a list
292 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
293 §ion_name, NULL);
294 if (rcode < 0) return -1; /* bad string */
297 * Explicit list given: use it.
299 client_cs = cf_section_find(section_name);
302 radlog(L_CONS|L_ERR, "%s[%d]: Failed to find client section %s",
303 cf_section_filename(cs), cf_section_lineno(cs), section_name);
307 } else if (this->server) {
309 * Else base it off of the server.
311 client_cs = cf_section_sub_find_name2(mainconfig.config,
315 (cf_section_sub_find(client_cs, "client") == NULL)) {
316 client_cs = mainconfig.config;
320 client_cs = mainconfig.config;
323 sock->clients = clients_parse_section(client_cs);
324 if (!sock->clients) {
332 * Send an authentication response packet
334 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
336 rad_assert(request->listener == listener);
337 rad_assert(listener->send == auth_socket_send);
339 return rad_send(request->reply, request->packet,
340 request->client->secret);
345 * Send an accounting response packet (or not)
347 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
349 rad_assert(request->listener == listener);
350 rad_assert(listener->send == acct_socket_send);
353 * Accounting reject's are silently dropped.
355 * We do it here to avoid polluting the rest of the
356 * code with this knowledge
358 if (request->reply->code == 0) return 0;
360 return rad_send(request->reply, request->packet,
361 request->client->secret);
366 * Send a packet to a home server.
368 * FIXME: have different code for proxy auth & acct!
370 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
372 listen_socket_t *sock = listener->data;
374 rad_assert(request->proxy_listener == listener);
375 rad_assert(listener->send == proxy_socket_send);
377 request->proxy->src_ipaddr = sock->ipaddr;
378 request->proxy->src_port = sock->port;
380 return rad_send(request->proxy, request->packet,
381 request->home_server->secret);
386 * Check if an incoming request is "ok"
388 * It takes packets, not requests. It sees if the packet looks
389 * OK. If so, it does a number of sanity checks on it.
391 static int auth_socket_recv(rad_listen_t *listener,
392 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
396 RADIUS_PACKET *packet;
397 RAD_REQUEST_FUNP fun = NULL;
400 lrad_ipaddr_t src_ipaddr;
402 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
403 if (rcode < 0) return 0;
405 RAD_SNMP_TYPE_INC(listener, total_requests);
407 if (rcode < 20) { /* AUTH_HDR_LEN */
408 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
412 if ((client = client_listener_find(listener,
413 &src_ipaddr)) == NULL) {
414 rad_recv_discard(listener->fd);
415 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
418 * This is debugging rather than logging, so that
419 * DoS attacks don't affect us.
421 DEBUG("Ignoring request from unknown client %s port %d",
422 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
423 buffer, sizeof(buffer)), src_port);
428 * Some sanity checks, based on the packet code.
431 case PW_AUTHENTICATION_REQUEST:
432 RAD_SNMP_CLIENT_INC(listener, client, requests);
433 fun = rad_authenticate;
436 case PW_STATUS_SERVER:
437 if (!mainconfig.status_server) {
438 rad_recv_discard(listener->fd);
439 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
440 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
441 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
444 fun = rad_status_server;
448 rad_recv_discard(listener->fd);
449 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
450 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
452 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
453 code, client->shortname, src_port);
456 } /* switch over packet types */
459 * Now that we've sanity checked everything, receive the
462 packet = rad_recv(listener->fd);
464 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
465 radlog(L_ERR, "%s", librad_errstr);
469 if (!received_request(listener, packet, prequest, client)) {
470 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
471 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
482 * Receive packets from an accounting socket
484 static int acct_socket_recv(rad_listen_t *listener,
485 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
489 RADIUS_PACKET *packet;
490 RAD_REQUEST_FUNP fun = NULL;
493 lrad_ipaddr_t src_ipaddr;
495 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
496 if (rcode < 0) return 0;
498 RAD_SNMP_TYPE_INC(listener, total_requests);
500 if (rcode < 20) { /* AUTH_HDR_LEN */
501 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
505 if ((client = client_listener_find(listener,
506 &src_ipaddr)) == NULL) {
507 rad_recv_discard(listener->fd);
508 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
511 * This is debugging rather than logging, so that
512 * DoS attacks don't affect us.
514 DEBUG("Ignoring request from unknown client %s port %d",
515 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
516 buffer, sizeof(buffer)), src_port);
521 * Some sanity checks, based on the packet code.
524 case PW_ACCOUNTING_REQUEST:
525 RAD_SNMP_CLIENT_INC(listener, client, requests);
526 fun = rad_accounting;
529 case PW_STATUS_SERVER:
530 if (!mainconfig.status_server) {
531 rad_recv_discard(listener->fd);
532 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
533 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
535 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
538 fun = rad_status_server;
542 rad_recv_discard(listener->fd);
543 RAD_SNMP_TYPE_INC(listener, total_unknown_types);
544 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
546 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
547 code, client->shortname, src_port);
549 } /* switch over packet types */
552 * Now that we've sanity checked everything, receive the
555 packet = rad_recv(listener->fd);
557 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
558 radlog(L_ERR, "%s", librad_errstr);
563 * There can be no duplicate accounting packets.
565 if (!received_request(listener, packet, prequest, client)) {
566 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
567 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
578 * Recieve packets from a proxy socket.
580 static int proxy_socket_recv(rad_listen_t *listener,
581 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
584 RADIUS_PACKET *packet;
585 RAD_REQUEST_FUNP fun = NULL;
588 packet = rad_recv(listener->fd);
590 radlog(L_ERR, "%s", librad_errstr);
595 * FIXME: Client MIB updates?
597 switch(packet->code) {
598 case PW_AUTHENTICATION_ACK:
599 case PW_ACCESS_CHALLENGE:
600 case PW_AUTHENTICATION_REJECT:
601 fun = rad_authenticate;
604 case PW_ACCOUNTING_RESPONSE:
605 fun = rad_accounting;
610 * FIXME: Update MIB for packet types?
612 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
613 "from home server %s port %d - ID %d : IGNORED",
615 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
616 packet->src_port, packet->id);
621 request = received_proxy_response(packet);
626 rad_assert(fun != NULL);
634 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
636 if (!request->reply->code) return 0;
638 rad_encode(request->reply, request->packet,
639 request->client->secret);
640 rad_sign(request->reply, request->packet,
641 request->client->secret);
647 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
649 if (rad_verify(request->packet, NULL,
650 request->client->secret) < 0) {
654 return rad_decode(request->packet, NULL,
655 request->client->secret);
658 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
660 rad_encode(request->proxy, NULL, request->home_server->secret);
661 rad_sign(request->proxy, NULL, request->home_server->secret);
667 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
669 if (rad_verify(request->proxy_reply, request->proxy,
670 request->home_server->secret) < 0) {
674 return rad_decode(request->proxy_reply, request->proxy,
675 request->home_server->secret);
679 #define STATE_UNOPENED (0)
680 #define STATE_UNLOCKED (1)
681 #define STATE_HEADER (2)
682 #define STATE_READING (3)
683 #define STATE_QUEUED (4)
684 #define STATE_RUNNING (5)
685 #define STATE_NO_REPLY (6)
686 #define STATE_REPLIED (7)
689 * If we're limiting outstanding packets, then mark the response
692 static int detail_send(rad_listen_t *listener, REQUEST *request)
696 listen_detail_t *data = listener->data;
698 rad_assert(request->listener == listener);
699 rad_assert(listener->send == detail_send);
702 * This request timed out. Remember that, and tell the
703 * caller it's OK to read more "detail" file stuff.
705 if (request->reply->code == 0) {
706 radius_signal_self(RADIUS_SIGNAL_SELF_DETAIL);
707 data->state = STATE_NO_REPLY;
712 * We call gettimeofday a lot. But here it should be OK,
713 * because there's nothing else to do.
715 gettimeofday(&now, NULL);
718 * If we haven't sent a packet in the last second, reset
722 if (timercmp(&data->last_packet, &now, <)) {
723 data->has_rtt = FALSE;
728 * Only one detail packet may be outstanding at a time,
729 * so it's safe to update some entries in the detail
732 * We keep smoothed round trip time (SRTT), but not round
733 * trip timeout (RTO). We use SRTT to calculate a rough
736 rtt = now.tv_sec - request->received.tv_sec;
739 rtt -= request->received.tv_usec;
742 * If we're proxying, the RTT is our processing time,
743 * plus the network delay there and back, plus the time
744 * on the other end to process the packet. Ideally, we
745 * should remove the network delays from the RTT, but we
746 * don't know what they are.
748 * So, to be safe, we over-estimate the total cost of
749 * processing the packet.
751 if (!data->has_rtt) {
752 data->has_rtt = TRUE;
754 data->rttvar = rtt / 2;
757 data->rttvar -= data->rttvar >> 2;
758 data->rttvar += (data->srtt - rtt);
759 data->srtt -= data->srtt >> 3;
760 data->srtt += rtt >> 3;
764 * Calculate the time we wait before sending the next
767 * rtt / (rtt + delay) = load_factor / 100
769 data->delay_time = (data->srtt * (100 - data->load_factor)) / (data->load_factor);
772 * FIXME: Push this delay to the event handler!
774 DEBUG2("RTT %d\tdelay %d", data->srtt, data->delay_time);
776 usleep(data->delay_time);
777 data->last_packet = now;
778 data->state = STATE_REPLIED;
785 * Open the detail file..
787 * FIXME: create it, if it's not already there, so that the main
788 * server select() will wake us up if there's anything to read.
790 static int detail_open(rad_listen_t *this)
794 listen_detail_t *data = this->data;
796 rad_assert(data->state == STATE_UNOPENED);
797 snprintf(buffer, sizeof(buffer), "%s.work", data->filename);
800 * Open detail.work first, so we don't lose
801 * accounting packets. It's probably better to
802 * duplicate them than to lose them.
804 * Note that we're not writing to the file, but
805 * we've got to open it for writing in order to
806 * establish the lock, to prevent rlm_detail from
809 this->fd = open(buffer, O_RDWR);
812 * Try reading the detail file. If it
813 * doesn't exist, we can't do anything.
815 * Doing the stat will tell us if the file
816 * exists, even if we don't have permissions
819 if (stat(data->filename, &st) < 0) {
824 * Open it BEFORE we rename it, just to
827 this->fd = open(data->filename, O_RDWR);
829 radlog(L_ERR, "Failed to open %s: %s",
830 data->filename, strerror(errno));
835 * Rename detail to detail.work
837 if (rename(data->filename, buffer) < 0) {
842 } /* else detail.work existed, and we opened it */
844 rad_assert(data->vps == NULL);
846 rad_assert(data->fp == NULL);
847 data->fp = fdopen(this->fd, "r");
849 radlog(L_ERR, "Failed to re-open %s: %s",
850 data->filename, strerror(errno));
854 data->state = STATE_UNLOCKED;
856 data->client_ip.af = AF_UNSPEC;
863 * FIXME: this should be dynamically allocated.
865 static const RADCLIENT detail_client = {
884 * FIXME: add a configuration "exit when done" so that the detail
885 * file reader can be used as a one-off tool to update stuff.
887 * The time sequence for reading from the detail file is:
889 * t_0 signalled that the server is idle, and we
890 * can read from the detail file.
892 * t_rtt the packet has been processed successfully,
893 * wait for t_delay to enforce load factor.
895 * t_rtt + t_delay wait for signal that the server is idle.
898 static int detail_recv(rad_listen_t *listener,
899 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
901 char key[256], value[1024];
902 VALUE_PAIR *vp, **tail;
903 RADIUS_PACKET *packet;
905 listen_detail_t *data = listener->data;
907 switch (data->state) {
909 rad_assert(listener->fd < 0);
912 * FIXME: If the file doesn't exist, then
913 * return "sleep for 1s", to avoid busy
916 if (!detail_open(listener)) return 0;
918 rad_assert(data->state == STATE_UNLOCKED);
919 rad_assert(listener->fd >= 0);
924 * Try to lock fd. If we can't, return.
925 * If we can, continue. This means that
926 * the server doesn't block while waiting
927 * for the lock to open...
931 * Note that we do NOT block waiting for
932 * the lock. We've re-named the file
933 * above, so we've already guaranteed
934 * that any *new* detail writer will not
935 * be opening this file. The only
936 * purpose of the lock is to catch a race
937 * condition where the execution
938 * "ping-pongs" between radiusd &
941 if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
945 * Look for the header
947 data->state = STATE_HEADER;
955 * End of file. Delete it, and re-set
958 if (feof(data->fp)) {
960 snprintf(buffer, sizeof(buffer),
961 "%s.work", data->filename);
963 fclose(data->fp); /* closes listener->fd */
966 data->state = STATE_UNOPENED;
967 rad_assert(data->vps == NULL);
972 * Else go read something.
977 * Read more value-pair's, unless we're
978 * at EOF. In that case, queue whatever
982 if (!feof(data->fp)) break;
983 data->state = STATE_QUEUED;
991 * We still have an outstanding packet.
992 * Don't read any more.
998 * If there's no reply, keep
999 * retransmitting the current packet
1002 case STATE_NO_REPLY:
1003 data->state = STATE_QUEUED;
1007 * We have a reply. Clean up the old
1008 * request, and go read another one.
1011 pairfree(&data->vps);
1012 data->state = STATE_HEADER;
1017 while (*tail) tail = &(*tail)->next;
1020 * Read a header, OR a value-pair.
1022 while (fgets(buffer, sizeof(buffer), data->fp)) {
1024 * Badly formatted file: delete it.
1026 * FIXME: Maybe flag an error?
1028 if (!strchr(buffer, '\n')) {
1029 pairfree(&data->vps);
1034 * We're reading VP's, and got a blank line.
1037 if ((data->state == STATE_READING) &&
1038 (buffer[0] == '\n')) {
1039 data->state = STATE_QUEUED;
1044 * Look for date/time header, and read VP's if
1045 * found. If not, keep reading lines until we
1048 if (data->state == STATE_HEADER) {
1051 if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
1052 data->state = STATE_READING;
1058 * We have a full "attribute = value" line.
1059 * If it doesn't look reasonable, skip it.
1061 * FIXME: print an error for badly formatted attributes?
1063 if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
1068 * Skip non-protocol attributes.
1070 if (!strcasecmp(key, "Request-Authenticator")) continue;
1073 * Set the original client IP address, based on
1074 * what's in the detail file.
1076 * Hmm... we don't set the server IP address.
1079 if (!strcasecmp(key, "Client-IP-Address")) {
1080 data->client_ip.af = AF_INET;
1081 ip_hton(value, AF_INET, &data->client_ip);
1086 * The original time at which we received the
1087 * packet. We need this to properly calculate
1090 if (!strcasecmp(key, "Timestamp")) {
1091 data->timestamp = atoi(value);
1098 * FIXME: do we want to check for non-protocol
1099 * attributes like radsqlrelay does?
1102 if ((userparse(buffer, &vp) > 0) &&
1110 * Some kind of error.
1112 * FIXME: Leave the file in-place, and warn the
1115 if (ferror(data->fp)) goto cleanup;
1118 * Process the packet.
1121 rad_assert(data->state == STATE_QUEUED);
1124 * We're done reading the file, but we didn't read
1125 * anything. Clean up, and don't return anything.
1128 data->state = STATE_HEADER;
1133 * Allocate the packet. If we fail, it's a serious
1136 packet = rad_alloc(1);
1138 data->state = STATE_NO_REPLY; /* try again later */
1139 return 0; /* maybe memory will magically free up... */
1142 memset(packet, 0, sizeof(*packet));
1143 packet->sockfd = -1;
1144 packet->src_ipaddr.af = AF_INET;
1145 packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1146 packet->code = PW_ACCOUNTING_REQUEST;
1147 packet->timestamp = time(NULL);
1150 * Remember where it came from, so that we don't
1151 * proxy it to the place it came from...
1153 if (data->client_ip.af != AF_UNSPEC) {
1154 packet->src_ipaddr = data->client_ip;
1157 vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);
1159 packet->src_ipaddr.af = AF_INET;
1160 packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1162 vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);
1164 packet->src_ipaddr.af = AF_INET6;
1165 memcpy(&packet->src_ipaddr.ipaddr.ip6addr,
1166 &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1170 vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);
1172 packet->dst_ipaddr.af = AF_INET;
1173 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1175 vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);
1177 packet->dst_ipaddr.af = AF_INET6;
1178 memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,
1179 &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1184 * We've got to give SOME value for Id & ports, so that
1185 * the packets can be added to the request queue.
1186 * However, we don't want to keep track of used/unused
1187 * id's and ports, as that's a lot of work. This hack
1188 * ensures that (if we have real random numbers), that
1189 * there will be a collision on every 2^(16+15+15+24 - 1)
1190 * packets, on average. That means we can read 2^37
1191 * packets before having a collision, which means it's
1192 * effectively impossible.
1194 packet->id = lrad_rand() & 0xffff;
1195 packet->src_port = 1024 + (lrad_rand() & 0x7fff);
1196 packet->dst_port = 1024 + (lrad_rand() & 0x7fff);
1198 packet->dst_ipaddr.af = AF_INET;
1199 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
1202 * If everything's OK, this is a waste of memory.
1203 * Otherwise, it lets us re-send the original packet
1204 * contents, unmolested.
1206 packet->vps = paircopy(data->vps);
1209 * Look for Acct-Delay-Time, and update
1210 * based on Acct-Delay-Time += (time(NULL) - timestamp)
1212 vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
1214 vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1215 rad_assert(vp != NULL);
1216 pairadd(&packet->vps, vp);
1218 if (data->timestamp != 0) {
1219 vp->vp_integer += time(NULL) - data->timestamp;
1222 *pfun = rad_accounting;
1225 printf("detail_recv: Read packet from %s\n", data->filename);
1226 for (vp = packet->vps; vp; vp = vp->next) {
1228 vp_print(stdout, vp);
1234 * FIXME: many of these checks may not be necessary when
1235 * reading from the detail file.
1237 * Try again later...
1239 if (!received_request(listener, packet, prequest, &detail_client)) {
1241 data->state = STATE_NO_REPLY; /* try again later */
1245 data->state = STATE_RUNNING;
1252 * Free detail-specific stuff.
1254 static void detail_free(rad_listen_t *this)
1256 listen_detail_t *data = this->data;
1258 free(data->filename);
1259 pairfree(&data->vps);
1261 if (data->fp != NULL) fclose(data->fp);
1265 static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
1267 if (!this->server) {
1268 return snprintf(buffer, bufsize, "%s",
1269 ((listen_detail_t *)(this->data))->filename);
1272 return snprintf(buffer, bufsize, "%s as server %s",
1273 ((listen_detail_t *)(this->data))->filename,
1277 static int detail_encode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
1280 * We never encode responses "sent to" the detail file.
1285 static int detail_decode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
1288 * We never decode responses read from the detail file.
1294 static const CONF_PARSER detail_config[] = {
1295 { "filename", PW_TYPE_STRING_PTR,
1296 offsetof(listen_detail_t, filename), NULL, NULL },
1297 { "load_factor", PW_TYPE_INTEGER,
1298 offsetof(listen_detail_t, load_factor), NULL, Stringify(10)},
1300 { NULL, -1, 0, NULL, NULL } /* end the list */
1305 * Parse a detail section.
1307 static int detail_parse(CONF_SECTION *cs, rad_listen_t *this)
1310 listen_detail_t *data;
1314 rcode = cf_section_parse(cs, data, detail_config);
1316 radlog(L_ERR, "%s[%d]: Failed parsing listen section",
1317 cf_section_filename(cs), cf_section_lineno(cs));
1321 if (!data->filename) {
1322 radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
1323 cf_section_filename(cs), cf_section_lineno(cs));
1327 if ((data->load_factor < 1) || (data->load_factor > 100)) {
1328 radlog(L_ERR, "%s[%d]: Load factor must be between 1 and 100",
1329 cf_section_filename(cs), cf_section_lineno(cs));
1335 data->state = STATE_UNOPENED;
1343 static int radius_snmp_recv(rad_listen_t *listener,
1344 UNUSED RAD_REQUEST_FUNP *pfun,
1345 UNUSED REQUEST **prequest)
1347 if (!mainconfig.do_snmp) return 0;
1349 if ((rad_snmp.smux_fd >= 0) &&
1350 (rad_snmp.smux_event == SMUX_READ)) {
1355 * If we've got to re-connect, then do so now,
1356 * before calling select again.
1358 if (rad_snmp.smux_event == SMUX_CONNECT) {
1363 * Reset this every time, as the smux connect may have
1364 * opened a new socket.
1366 listener->fd = rad_snmp.smux_fd;
1372 static int radius_snmp_print(UNUSED rad_listen_t *this, char *buffer, size_t bufsize)
1374 return snprintf(buffer, bufsize, "SMUX with OID .1.3.6.1.4.1.11344.1.1.1");
1381 * Check if an incoming request is "ok"
1383 * It takes packets, not requests. It sees if the packet looks
1384 * OK. If so, it does a number of sanity checks on it.
1386 static int vqp_socket_recv(rad_listen_t *listener,
1387 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1389 RADIUS_PACKET *packet;
1390 RAD_REQUEST_FUNP fun = NULL;
1394 packet = vqp_recv(listener->fd);
1396 radlog(L_ERR, "%s", librad_errstr);
1400 if ((client = client_listener_find(listener,
1401 &packet->src_ipaddr)) == NULL) {
1402 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
1404 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
1405 inet_ntop(packet->src_ipaddr.af,
1406 &packet->src_ipaddr.ipaddr,
1407 buffer, sizeof(buffer)),
1418 if (!received_request(listener, packet, prequest, client)) {
1430 * Send an authentication response packet
1432 static int vqp_socket_send(rad_listen_t *listener, REQUEST *request)
1434 rad_assert(request->listener == listener);
1435 rad_assert(listener->send == vqp_socket_send);
1437 if (vqp_encode(request->reply, request->packet) < 0) {
1438 DEBUG2("Failed encoding packet: %s\n", librad_errstr);
1442 return vqp_send(request->reply);
1446 static int vqp_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1448 return vqp_encode(request->reply, request->packet);
1452 static int vqp_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1454 return vqp_decode(request->packet);
1456 #endif /* WITH_VMPS */
1459 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1460 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
1464 proxy_socket_recv, proxy_socket_send,
1465 socket_print, proxy_socket_encode, proxy_socket_decode },
1467 /* authentication */
1468 { common_socket_parse, NULL,
1469 auth_socket_recv, auth_socket_send,
1470 socket_print, client_socket_encode, client_socket_decode },
1473 { common_socket_parse, NULL,
1474 acct_socket_recv, acct_socket_send,
1475 socket_print, client_socket_encode, client_socket_decode},
1478 { detail_parse, detail_free,
1479 detail_recv, detail_send,
1480 detail_print, detail_encode, detail_decode },
1483 /* vlan query protocol */
1484 { common_socket_parse, NULL,
1485 vqp_socket_recv, vqp_socket_send,
1486 socket_print, vqp_socket_encode, vqp_socket_decode },
1488 { NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1491 { NULL, NULL, NULL, NULL, NULL, NULL, NULL} /* RAD_LISTEN_SNMP */
1497 * Binds a listener to a socket.
1499 static int listen_bind(rad_listen_t *this)
1501 rad_listen_t **last;
1502 listen_socket_t *sock = this->data;
1505 * If the port is zero, then it means the appropriate
1506 * thing from /etc/services.
1508 if (sock->port == 0) {
1509 struct servent *svp;
1511 switch (this->type) {
1512 case RAD_LISTEN_AUTH:
1513 svp = getservbyname ("radius", "udp");
1515 sock->port = ntohs(svp->s_port);
1517 sock->port = PW_AUTH_UDP_PORT;
1521 case RAD_LISTEN_ACCT:
1522 svp = getservbyname ("radacct", "udp");
1524 sock->port = ntohs(svp->s_port);
1526 sock->port = PW_ACCT_UDP_PORT;
1531 radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
1537 * Find it in the old list, AFTER updating the port. If
1538 * it's there, use that, rather than creating a new
1539 * socket. This allows HUP's to re-use the old sockets,
1540 * which means that packets waiting in the socket queue
1543 for (last = &mainconfig.listen;
1545 last = &((*last)->next)) {
1546 listen_socket_t *other;
1548 if (this->type != (*last)->type) continue;
1550 if ((this->type == RAD_LISTEN_DETAIL) ||
1551 (this->type == RAD_LISTEN_SNMP)) continue;
1553 other = (listen_socket_t *)((*last)->data);
1555 if ((sock->port == other->port) &&
1556 (sock->ipaddr.af == other->ipaddr.af) &&
1557 (lrad_ipaddr_cmp(&sock->ipaddr, &other->ipaddr) == 0)) {
1558 this->fd = (*last)->fd;
1564 this->fd = lrad_socket(&sock->ipaddr, sock->port);
1566 radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
1573 if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0) {
1574 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
1578 flags |= O_NONBLOCK;
1579 if( fcntl(this->fd, F_SETFL, flags) < 0) {
1580 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
1591 * Allocate & initialize a new listener.
1593 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1597 this = rad_malloc(sizeof(*this));
1598 memset(this, 0, sizeof(*this));
1601 this->recv = master_listen[this->type].recv;
1602 this->send = master_listen[this->type].send;
1603 this->print = master_listen[this->type].print;
1604 this->encode = master_listen[this->type].encode;
1605 this->decode = master_listen[this->type].decode;
1608 case RAD_LISTEN_AUTH:
1609 case RAD_LISTEN_ACCT:
1610 case RAD_LISTEN_PROXY:
1611 case RAD_LISTEN_VQP:
1612 this->data = rad_malloc(sizeof(listen_socket_t));
1613 memset(this->data, 0, sizeof(listen_socket_t));
1616 case RAD_LISTEN_DETAIL:
1617 this->data = rad_malloc(sizeof(listen_detail_t));
1618 memset(this->data, 0, sizeof(listen_detail_t));
1621 rad_assert("Unsupported option!" == NULL);
1630 * Externally visible function for creating a new proxy LISTENER.
1632 * For now, don't take ipaddr or port.
1634 * Not thread-safe, but all calls to it are protected by the
1635 * proxy mutex in request_list.c
1637 rad_listen_t *proxy_new_listener()
1639 int last_proxy_port, port;
1640 rad_listen_t *this, *tmp, **last;
1641 listen_socket_t *sock, *old;
1643 this = listen_alloc(RAD_LISTEN_PROXY);
1646 * Find an existing proxy socket to copy.
1648 * FIXME: Make it per-realm, or per-home server!
1650 last_proxy_port = 0;
1652 last = &mainconfig.listen;
1653 for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1654 if (tmp->type == RAD_LISTEN_PROXY) {
1656 if (sock->port > last_proxy_port) {
1657 last_proxy_port = sock->port + 1;
1659 if (!old) old = sock;
1662 last = &(tmp->next);
1665 if (!old) return NULL; /* This is a serious error. */
1668 * FIXME: find a new IP address to listen on?
1670 * This could likely be done in the "home server"
1671 * configuration, to have per-home-server source IP's.
1674 memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1677 * Keep going until we find an unused port.
1679 for (port = last_proxy_port; port < 64000; port++) {
1681 if (listen_bind(this) == 0) {
1683 * Add the new listener to the list of
1695 static const LRAD_NAME_NUMBER listen_compare[] = {
1696 { "auth", RAD_LISTEN_AUTH },
1697 { "acct", RAD_LISTEN_ACCT },
1698 { "detail", RAD_LISTEN_DETAIL },
1700 { "vmps", RAD_LISTEN_VQP },
1706 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
1714 DEBUG2(" listen {");
1716 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1718 if (rcode < 0) return NULL;
1721 radlog(L_ERR, "%s[%d]: No type specified in listen section",
1722 cf_section_filename(cs), cf_section_lineno(cs));
1726 type = lrad_str2int(listen_compare, listen_type,
1729 if (type == RAD_LISTEN_NONE) {
1730 radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
1731 cf_section_filename(cs), cf_section_lineno(cs));
1736 * Allow listen sections in the default config to
1737 * refer to a server.
1740 rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
1742 if (rcode < 0) return NULL;
1746 * Set up cross-type data.
1748 this = listen_alloc(type);
1749 this->server = server;
1753 * Call per-type parser.
1755 if (master_listen[type].parse(cs, this) < 0) {
1766 * Generate a list of listeners. Takes an input list of
1767 * listeners, too, so we don't close sockets with waiting packets.
1769 int listen_init(const char *filename, rad_listen_t **head)
1773 rad_listen_t **last;
1775 lrad_ipaddr_t server_ipaddr;
1779 * We shouldn't be called with a pre-existing list.
1781 rad_assert(head && (*head == NULL));
1784 server_ipaddr.af = AF_UNSPEC;
1787 * If the port is specified on the command-line,
1788 * it over-rides the configuration file.
1790 * FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
1792 if (mainconfig.port >= 0) auth_port = mainconfig.port;
1795 * If the IP address was configured on the command-line,
1796 * use that as the "bind_address"
1798 if (mainconfig.myip.af != AF_UNSPEC) {
1799 memcpy(&server_ipaddr, &mainconfig.myip,
1800 sizeof(server_ipaddr));
1805 * Else look for bind_address and/or listen sections.
1807 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1808 rcode = cf_item_parse(mainconfig.config, "bind_address",
1810 &server_ipaddr.ipaddr.ip4addr, NULL);
1811 if (rcode < 0) return -1; /* error parsing it */
1813 if (rcode == 0) { /* successfully parsed IPv4 */
1814 listen_socket_t *sock;
1815 server_ipaddr.af = AF_INET;
1817 radlog(L_INFO, "WARNING: The directive 'bind_adress' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1821 if (strcmp(progname, "vmpsd") == 0) {
1822 this = listen_alloc(RAD_LISTEN_VQP);
1823 if (!auth_port) auth_port = 1589;
1826 this = listen_alloc(RAD_LISTEN_AUTH);
1830 sock->ipaddr = server_ipaddr;
1831 sock->port = auth_port;
1833 if (listen_bind(this) < 0) {
1836 radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1839 auth_port = sock->port; /* may have been updated in listen_bind */
1841 last = &(this->next);
1847 if (strcmp(progname, "vmpsd") == 0) goto do_proxy;
1851 * Open Accounting Socket.
1853 * If we haven't already gotten acct_port from
1854 * /etc/services, then make it auth_port + 1.
1856 this = listen_alloc(RAD_LISTEN_ACCT);
1860 * Create the accounting socket.
1862 * The accounting port is always the
1863 * authentication port + 1
1865 sock->ipaddr = server_ipaddr;
1866 sock->port = auth_port + 1;
1868 if (listen_bind(this) < 0) {
1871 radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1876 last = &(this->next);
1878 } else if (mainconfig.port > 0) { /* no bind address, but a port */
1879 radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1885 * They specified an IP on the command-line, ignore
1886 * all listen sections.
1888 if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
1891 * Walk through the "listen" sections, if they exist.
1893 for (cs = cf_subsection_find_next(mainconfig.config, NULL, "listen");
1895 cs = cf_subsection_find_next(mainconfig.config, cs, "listen")) {
1896 this = listen_parse(cs, NULL);
1903 last = &(this->next);
1907 * Check virtual servers for "listen" sections, too.
1909 * FIXME: Move to virtual server init?
1911 for (cs = cf_subsection_find_next(mainconfig.config, NULL, "server");
1913 cs = cf_subsection_find_next(mainconfig.config, cs, "server")) {
1914 CONF_SECTION *subcs;
1915 const char *name2 = cf_section_name2(cs);
1918 radlog(L_ERR, "%s[%d]: \"server\" sections require a server name",
1919 filename, cf_section_lineno(cs));
1924 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
1926 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
1927 this = listen_parse(subcs, name2);
1934 last = &(this->next);
1935 } /* loop over "listen" directives in virtual servers */
1936 } /* loop over virtual servers */
1939 * If we're proxying requests, open the proxy FD.
1940 * Otherwise, don't do anything.
1943 if (mainconfig.proxy_requests == TRUE) {
1945 listen_socket_t *sock = NULL;
1948 * No sockets to receive packets, therefore
1949 * proxying is pointless.
1951 if (!*head) return -1;
1954 * If we previously had proxy sockets, copy them
1955 * to the new config.
1957 if (mainconfig.listen != NULL) {
1958 rad_listen_t *old, *next, **tail;
1960 tail = &mainconfig.listen;
1961 for (old = mainconfig.listen;
1966 if (old->type != RAD_LISTEN_PROXY) {
1967 tail = &((*tail)->next);
1974 last = &(old->next);
1981 * Find the first authentication port,
1984 for (this = *head; this != NULL; this = this->next) {
1985 if (this->type == RAD_LISTEN_AUTH) {
1987 if (server_ipaddr.af == AF_UNSPEC) {
1988 server_ipaddr = sock->ipaddr;
1990 port = sock->port + 2; /* skip acct port */
1993 if (this->type == RAD_LISTEN_VQP) {
1995 if (server_ipaddr.af == AF_UNSPEC) {
1996 server_ipaddr = sock->ipaddr;
1998 port = sock->port + 1;
2003 if (port < 0) port = 1024 + (lrad_rand() & 0x1ff);
2006 * Address is still unspecified, use IPv4.
2008 if (server_ipaddr.af == AF_UNSPEC) {
2009 server_ipaddr.af = AF_INET;
2010 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
2013 this = listen_alloc(RAD_LISTEN_PROXY);
2017 * Create the first proxy socket.
2019 sock->ipaddr = server_ipaddr;
2022 * Try to find a proxy port (value doesn't matter)
2024 for (sock->port = port;
2027 if (listen_bind(this) == 0) {
2029 last = &(this->next); /* just in case */
2034 if (sock->port >= 64000) {
2037 radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
2044 if (mainconfig.do_snmp) {
2048 * Forget about the old one.
2050 for (this = mainconfig.listen;
2052 this = this->next) {
2053 if (this->type != RAD_LISTEN_SNMP) continue;
2057 this = rad_malloc(sizeof(*this));
2058 memset(this, 0, sizeof(*this));
2060 this->type = RAD_LISTEN_SNMP;
2061 this->fd = rad_snmp.smux_fd;
2063 this->recv = radius_snmp_recv;
2064 this->print = radius_snmp_print;
2067 last = &(this->next);
2075 * Free a linked list of listeners;
2077 void listen_free(rad_listen_t **head)
2081 if (!head || !*head) return;
2085 rad_listen_t *next = this->next;
2090 * Other code may have eaten the FD.
2092 if (this->fd >= 0) close(this->fd);
2094 if (master_listen[this->type].free) {
2095 master_listen[this->type].free(this);