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>
32 #include <sys/resource.h>
38 #ifdef HAVE_SYS_STAT_H
44 #define USEC (1000000)
47 * We'll use this below.
49 typedef int (*rad_listen_parse_t)(const char *, int, const CONF_SECTION *, rad_listen_t *);
50 typedef void (*rad_listen_free_t)(rad_listen_t *);
52 typedef struct rad_listen_master_t {
53 rad_listen_parse_t parse;
54 rad_listen_free_t free;
55 rad_listen_recv_t recv;
56 rad_listen_send_t send;
57 rad_listen_print_t print;
58 rad_listen_encode_t encode;
59 rad_listen_decode_t decode;
60 } rad_listen_master_t;
62 typedef struct listen_socket_t {
68 RADCLIENT_LIST *clients;
71 typedef struct listen_detail_t {
77 lrad_ipaddr_t client_ip;
78 REQUEST *request; /* can only be one at a time! */
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));
103 clients = ((listen_socket_t *)listener->data)->clients;
104 if (!clients) clients = mainconfig.clients;
106 rad_assert(clients != NULL);
108 return client_find(clients, ipaddr);
111 static int listen_bind(rad_listen_t *this);
114 * Process and reply to a server-status request.
115 * Like rad_authenticate and rad_accounting this should
116 * live in it's own file but it's so small we don't bother.
118 static int rad_status_server(REQUEST *request)
120 int rcode = RLM_MODULE_OK;
123 switch (request->listener->type) {
124 case RAD_LISTEN_AUTH:
125 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
127 rcode = module_authorize(dval->value, request);
129 rcode = RLM_MODULE_OK;
134 case RLM_MODULE_UPDATED:
135 request->reply->code = PW_AUTHENTICATION_ACK;
138 case RLM_MODULE_FAIL:
139 case RLM_MODULE_HANDLED:
140 request->reply->code = 0; /* don't reply */
144 case RLM_MODULE_REJECT:
145 request->reply->code = PW_AUTHENTICATION_REJECT;
150 case RAD_LISTEN_ACCT:
151 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
153 rcode = module_accounting(dval->value, request);
155 rcode = RLM_MODULE_OK;
160 case RLM_MODULE_UPDATED:
161 request->reply->code = PW_ACCOUNTING_RESPONSE;
165 request->reply->code = 0; /* don't reply */
178 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
181 listen_socket_t *sock = this->data;
183 if ((sock->ipaddr.af == AF_INET) &&
184 (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
187 ip_ntoh(&sock->ipaddr, buffer, bufsize);
190 len = strlen(buffer);
192 return len + snprintf(buffer + len, bufsize - len, " port %d",
198 * Parse an authentication or accounting socket.
200 static int common_socket_parse(const char *filename, int lineno,
201 const CONF_SECTION *cs, rad_listen_t *this)
205 lrad_ipaddr_t ipaddr;
206 listen_socket_t *sock = this->data;
207 const char *section_name = NULL;
208 CONF_SECTION *client_cs;
213 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
214 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
215 &ipaddr.ipaddr.ip4addr, NULL);
216 if (rcode < 0) return -1;
218 if (rcode == 0) { /* successfully parsed IPv4 */
221 } else { /* maybe IPv6? */
222 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
223 &ipaddr.ipaddr.ip6addr, NULL);
224 if (rcode < 0) return -1;
227 radlog(L_ERR, "%s[%d]: No address specified in listen section",
231 ipaddr.af = AF_INET6;
234 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
236 if (rcode < 0) return -1;
238 sock->ipaddr = ipaddr;
239 sock->port = listen_port;
242 * And bind it to the port.
244 if (listen_bind(this) < 0) {
246 radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s port %d",
247 filename, cf_section_lineno(cs),
248 ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
254 * If we can bind to interfaces, do so,
257 if (cf_pair_find(cs, "interface")) {
258 #ifndef SO_BINDTODEVICE
259 radlog(L_CONS|L_ERR, "%s[%d]: System does not support binding to interfaces, delete this line from the configuration file.",
260 filename, cf_section_lineno(cs));
264 const CONF_PAIR *cp = cf_pair_find(cs, "interface");
267 rad_assert(cp != NULL);
268 value = cf_pair_value(cp);
269 rad_assert(value != NULL);
271 strcpy(ifreq.ifr_name, value);
273 if (setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
274 (char *)&ifreq, sizeof(ifreq)) < 0) {
275 radlog(L_CONS|L_ERR, "%s[%d]: Failed binding to interface %s: %s",
276 filename, cf_section_lineno(cs),
277 value, strerror(errno));
279 } /* else it worked. */
284 * Look for the name of a section that holds a list
287 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
288 §ion_name, NULL);
289 if (rcode < 0) return -1; /* bad string */
290 if (rcode > 0) return 0; /* non-existent is OK. */
292 client_cs = cf_section_find(section_name);
295 radlog(L_CONS|L_ERR, "%s[%d]: Failed to find client section %s",
296 filename, cf_section_lineno(cs), section_name);
300 sock->clients = clients_parse_section(filename, client_cs);
301 if (!sock->clients) {
309 * Send an authentication response packet
311 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
313 rad_assert(request->listener == listener);
314 rad_assert(listener->send == auth_socket_send);
316 return rad_send(request->reply, request->packet,
317 request->client->secret);
322 * Send an accounting response packet (or not)
324 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
326 rad_assert(request->listener == listener);
327 rad_assert(listener->send == acct_socket_send);
330 * Accounting reject's are silently dropped.
332 * We do it here to avoid polluting the rest of the
333 * code with this knowledge
335 if (request->reply->code == 0) return 0;
337 return rad_send(request->reply, request->packet,
338 request->client->secret);
343 * Send a packet to a home server.
345 * FIXME: have different code for proxy auth & acct!
347 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
349 listen_socket_t *sock = listener->data;
351 rad_assert(request->proxy_listener == listener);
352 rad_assert(listener->send == proxy_socket_send);
354 request->proxy->src_ipaddr = sock->ipaddr;
355 request->proxy->src_port = sock->port;
357 return rad_send(request->proxy, request->packet,
358 request->home_server->secret);
363 * Check if an incoming request is "ok"
365 * It takes packets, not requests. It sees if the packet looks
366 * OK. If so, it does a number of sanity checks on it.
368 static int auth_socket_recv(rad_listen_t *listener,
369 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
373 RADIUS_PACKET *packet;
374 RAD_REQUEST_FUNP fun = NULL;
377 lrad_ipaddr_t src_ipaddr;
379 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
380 if (rcode < 0) return 0;
382 RAD_SNMP_TYPE_INC(listener, total_requests);
384 if (rcode < 20) { /* AUTH_HDR_LEN */
385 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
389 if ((client = client_listener_find(listener,
390 &src_ipaddr)) == NULL) {
391 rad_recv_discard(listener->fd);
392 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
395 * This is debugging rather than logging, so that
396 * DoS attacks don't affect us.
398 DEBUG("Ignoring request from unknown client %s port %d",
399 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
400 buffer, sizeof(buffer)), src_port);
405 * Some sanity checks, based on the packet code.
408 case PW_AUTHENTICATION_REQUEST:
409 RAD_SNMP_CLIENT_INC(listener, client, requests);
410 fun = rad_authenticate;
413 case PW_STATUS_SERVER:
414 if (!mainconfig.status_server) {
415 rad_recv_discard(listener->fd);
416 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
417 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
418 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
421 fun = rad_status_server;
425 rad_recv_discard(listener->fd);
426 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
427 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
429 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
430 code, client->shortname, src_port);
433 } /* switch over packet types */
436 * Now that we've sanity checked everything, receive the
439 packet = rad_recv(listener->fd);
441 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
442 radlog(L_ERR, "%s", librad_errstr);
446 if (!received_request(listener, packet, prequest, client)) {
447 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
448 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
459 * Receive packets from an accounting socket
461 static int acct_socket_recv(rad_listen_t *listener,
462 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
466 RADIUS_PACKET *packet;
467 RAD_REQUEST_FUNP fun = NULL;
470 lrad_ipaddr_t src_ipaddr;
472 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
473 if (rcode < 0) return 0;
475 RAD_SNMP_TYPE_INC(listener, total_requests);
477 if (rcode < 20) { /* AUTH_HDR_LEN */
478 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
482 if ((client = client_listener_find(listener,
483 &src_ipaddr)) == NULL) {
484 rad_recv_discard(listener->fd);
485 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
488 * This is debugging rather than logging, so that
489 * DoS attacks don't affect us.
491 DEBUG("Ignoring request from unknown client %s port %d",
492 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
493 buffer, sizeof(buffer)), src_port);
498 * Some sanity checks, based on the packet code.
501 case PW_ACCOUNTING_REQUEST:
502 RAD_SNMP_CLIENT_INC(listener, client, requests);
503 fun = rad_accounting;
506 case PW_STATUS_SERVER:
507 if (!mainconfig.status_server) {
508 rad_recv_discard(listener->fd);
509 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
510 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
512 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
515 fun = rad_status_server;
519 rad_recv_discard(listener->fd);
520 RAD_SNMP_TYPE_INC(listener, total_unknown_types);
521 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
523 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
524 code, client->shortname, src_port);
526 } /* switch over packet types */
529 * Now that we've sanity checked everything, receive the
532 packet = rad_recv(listener->fd);
534 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
535 radlog(L_ERR, "%s", librad_errstr);
540 * There can be no duplicate accounting packets.
542 if (!received_request(listener, packet, prequest, client)) {
543 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
544 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
555 * Recieve packets from a proxy socket.
557 static int proxy_socket_recv(rad_listen_t *listener,
558 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
561 RADIUS_PACKET *packet;
562 RAD_REQUEST_FUNP fun = NULL;
565 packet = rad_recv(listener->fd);
567 radlog(L_ERR, "%s", librad_errstr);
572 * FIXME: Client MIB updates?
574 switch(packet->code) {
575 case PW_AUTHENTICATION_ACK:
576 case PW_ACCESS_CHALLENGE:
577 case PW_AUTHENTICATION_REJECT:
578 fun = rad_authenticate;
581 case PW_ACCOUNTING_RESPONSE:
582 fun = rad_accounting;
587 * FIXME: Update MIB for packet types?
589 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
590 "from home server %s port %d - ID %d : IGNORED",
592 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
593 packet->src_port, packet->id);
598 request = received_proxy_response(packet);
603 rad_assert(fun != NULL);
611 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
613 if (!request->reply->code) return 0;
615 rad_encode(request->reply, request->packet,
616 request->client->secret);
617 rad_sign(request->reply, request->packet,
618 request->client->secret);
624 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
626 if (rad_verify(request->packet, NULL,
627 request->client->secret) < 0) {
631 return rad_decode(request->packet, NULL,
632 request->client->secret);
635 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
637 rad_encode(request->proxy, NULL, request->home_server->secret);
638 rad_sign(request->proxy, NULL, request->home_server->secret);
644 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
646 if (rad_verify(request->proxy_reply, request->proxy,
647 request->home_server->secret) < 0) {
651 return rad_decode(request->proxy_reply, request->proxy,
652 request->home_server->secret);
656 #define STATE_UNOPENED (0)
657 #define STATE_UNLOCKED (1)
658 #define STATE_HEADER (2)
659 #define STATE_READING (3)
660 #define STATE_DONE (4)
661 #define STATE_WAITING (5)
664 * If we're limiting outstanding packets, then mark the response
667 static int detail_send(rad_listen_t *listener, REQUEST *request)
671 listen_detail_t *data = listener->data;
673 rad_assert(request->listener == listener);
674 rad_assert(listener->send == detail_send);
677 * This request timed out. We should probably re-send it
680 if (request->reply->code == 0) {
682 * FIXME: do something sane!
687 * We call gettimeofday a lot. But here it should be OK,
688 * because there's nothing else to do.
690 gettimeofday(&now, NULL);
693 * If we haven't sent a packet in the last second, reset
697 if (timercmp(&data->last_packet, &now, <)) {
698 data->has_rtt = FALSE;
703 * Only one detail packet may be outstanding at a time,
704 * so it's safe to update some entries in the detail
707 * We keep smoothed round trip time (SRTT), but not round
708 * trip timeout (RTO). We use SRTT to calculate a rough
711 rtt = now.tv_sec - request->received.tv_sec;
714 rtt -= request->received.tv_usec;
717 * If we're proxying, the RTT is our processing time,
718 * plus the network delay there and back, plus the time
719 * on the other end to process the packet. Ideally, we
720 * should remove the network delays from the RTT, but we
721 * don't know what they are.
723 * So, to be safe, we over-estimate the total cost of
724 * processing the packet.
726 if (!data->has_rtt) {
727 data->has_rtt = TRUE;
729 data->rttvar = rtt / 2;
732 data->rttvar -= data->rttvar >> 2;
733 data->rttvar += (data->srtt - rtt);
734 data->srtt -= data->srtt >> 3;
735 data->srtt += rtt >> 3;
739 * Calculate the time we wait before sending the next
742 * rtt / (rtt + delay) = load_factor / 100
744 data->delay_time = (data->srtt * (100 - data->load_factor)) / (data->load_factor);
747 * FIXME: Push this delay to the event handler!
749 DEBUG2("RTT %d\tdelay %d", data->srtt, data->delay_time);
751 usleep(data->delay_time);
753 data->last_packet = now;
756 * FIXME: Cache the LAST offset in the file where we
757 * successfully read a packet, and got a response. Then
758 * when we re-open the file (say after a restart), we
759 * start reading from that offset, rather than from the
760 * beginning of the file again.
762 * OR, put the offset into a comment in the first line of
765 data->request = NULL;
768 * Code in threads.c will take care performing self
769 * signalling that we can read from the detail file.
771 * Even though this request is now done, there may be
772 * auth/acct requests pending that mean we shouldn't read
781 * Open the detail file..
783 * FIXME: create it, if it's not already there, so that the main
784 * server select() will wake us up if there's anything to read.
786 static int detail_open(rad_listen_t *this)
790 listen_detail_t *data = this->data;
792 rad_assert(data->state == STATE_UNOPENED);
793 snprintf(buffer, sizeof(buffer), "%s.work", data->filename);
796 * Open detail.work first, so we don't lose
797 * accounting packets. It's probably better to
798 * duplicate them than to lose them.
800 * Note that we're not writing to the file, but
801 * we've got to open it for writing in order to
802 * establish the lock, to prevent rlm_detail from
805 this->fd = open(buffer, O_RDWR);
808 * Try reading the detail file. If it
809 * doesn't exist, we can't do anything.
811 * Doing the stat will tell us if the file
812 * exists, even if we don't have permissions
815 if (stat(data->filename, &st) < 0) {
820 * Open it BEFORE we rename it, just to
823 this->fd = open(data->filename, O_RDWR);
825 radlog(L_ERR, "Failed to open %s: %s",
826 data->filename, strerror(errno));
831 * Rename detail to detail.work
833 if (rename(data->filename, buffer) < 0) {
838 } /* else detail.work existed, and we opened it */
840 rad_assert(data->vps == NULL);
842 rad_assert(data->fp == NULL);
843 data->fp = fdopen(this->fd, "r");
845 radlog(L_ERR, "Failed to re-open %s: %s",
846 data->filename, strerror(errno));
850 data->state = STATE_UNLOCKED;
852 data->client_ip.af = AF_UNSPEC;
859 * FIXME: this should be dynamically allocated.
861 static const RADCLIENT detail_client = {
880 * FIXME: add a configuration "exit when done" so that the detail
881 * file reader can be used as a one-off tool to update stuff.
884 static int detail_recv(rad_listen_t *listener,
885 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
888 char key[256], value[1024];
889 VALUE_PAIR *vp, **tail;
890 RADIUS_PACKET *packet;
892 listen_detail_t *data = listener->data;
893 REQUEST *old_request;
895 if (data->state == STATE_UNOPENED) {
896 rad_assert(listener->fd < 0);
899 * FIXME: If the file doesn't exist, then return
900 * "sleep for 1s", to avoid busy looping.
902 if (!detail_open(listener)) return 0;
904 rad_assert(listener->fd >= 0);
907 * Try to lock fd. If we can't, return. If we can,
908 * continue. This means that the server doesn't block
909 * while waiting for the lock to open...
911 if (data->state == STATE_UNLOCKED) {
913 * Note that we do NOT block waiting for the
914 * lock. We've re-named the file above, so we've
915 * already guaranteed that any *new* detail
916 * writer will not be opening this file. The
917 * only purpose of the lock is to catch a race
918 * condition where the execution "ping-pongs"
919 * between radiusd & radrelay.
921 if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
925 * Look for the header
927 data->state = STATE_HEADER;
932 * Catch an out of memory condition which will most likely
935 if (data->state == STATE_DONE) goto alloc_packet;
938 * We still have an outstanding packet. Don't read any
941 old_request = data->request; /* threading issues */
942 if (old_request && old_request->reply->code == 0) {
944 * FIXME: return "don't do anything until the
945 * request is done, AND we receive another signal
946 * saying it's OK to read the detail file.
952 * We read the last packet, and returned it for
953 * processing. We later come back here to shut
954 * everything down, and unlink the file.
956 if (feof(data->fp)) {
957 if (data->state == STATE_READING) {
958 data->state = STATE_DONE;
963 * If there's a pending request, don't delete the
967 data->state = STATE_WAITING;
972 rad_assert(data->vps == NULL);
974 snprintf(buffer, sizeof(buffer), "%s.work", data->filename);
976 fclose(data->fp); /* closes listener->fd */
979 data->state = STATE_UNOPENED;
982 * Try to open "detail" again. If we're on a
983 * busy RADIUS server, odds are that it will
986 detail_open(listener);
995 while (fgets(buffer, sizeof(buffer), data->fp)) {
999 if (!strchr(buffer, '\n')) {
1000 pairfree(&data->vps);
1005 * We've read a header, possibly packet contents,
1006 * and are now at the end of the packet.
1008 if ((data->state == STATE_READING) &&
1009 (buffer[0] == '\n')) {
1010 data->state = STATE_DONE;
1015 * Look for date/time header, and read VP's if
1016 * found. If not, keep reading lines until we
1019 if (data->state == STATE_HEADER) {
1022 if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
1023 data->state = STATE_READING;
1029 * We have a full "attribute = value" line.
1030 * If it doesn't look reasonable, skip it.
1032 if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
1037 * Skip non-protocol attributes.
1039 if (!strcasecmp(key, "Request-Authenticator")) continue;
1042 * Set the original client IP address, based on
1043 * what's in the detail file.
1045 * Hmm... we don't set the server IP address.
1048 if (!strcasecmp(key, "Client-IP-Address")) {
1049 data->client_ip.af = AF_INET;
1050 ip_hton(value, AF_INET, &data->client_ip);
1055 * The original time at which we received the
1056 * packet. We need this to properly calculate
1059 if (!strcasecmp(key, "Timestamp")) {
1060 data->timestamp = atoi(value);
1067 * FIXME: do we want to check for non-protocol
1068 * attributes like radsqlrelay does?
1071 if ((userparse(buffer, &vp) > 0) &&
1079 * We got to EOF, If we're in STATE_HEADER, it's OK.
1080 * Otherwise it's a problem. In any case, nuke the file
1081 * and start over from scratch,
1083 if (feof(data->fp)) {
1087 if (data->state == STATE_READING) goto alloc_packet;
1088 pairfree(&data->vps);
1093 * If we're not done, then there's a problem. The checks
1096 rad_assert(data->state == STATE_DONE);
1099 * The packet we read was empty, re-set the state to look
1100 * for a header, and don't return anything.
1103 data->state = STATE_HEADER;
1108 * Allocate the packet. If we fail, it's a serious
1112 rad_assert(data->request == NULL);
1114 packet = rad_alloc(1);
1116 return 0; /* maybe memory will magically free up... */
1119 memset(packet, 0, sizeof(*packet));
1120 packet->sockfd = -1;
1121 packet->src_ipaddr.af = AF_INET;
1122 packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1123 packet->code = PW_ACCOUNTING_REQUEST;
1124 packet->timestamp = time(NULL);
1127 * Remember where it came from, so that we don't
1128 * proxy it to the place it came from...
1130 if (data->client_ip.af != AF_UNSPEC) {
1131 packet->src_ipaddr = data->client_ip;
1134 vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);
1136 packet->src_ipaddr.af = AF_INET;
1137 packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1139 vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);
1141 packet->src_ipaddr.af = AF_INET6;
1142 memcpy(&packet->src_ipaddr.ipaddr.ip6addr,
1143 &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1147 vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);
1149 packet->dst_ipaddr.af = AF_INET;
1150 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1152 vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);
1154 packet->dst_ipaddr.af = AF_INET6;
1155 memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,
1156 &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1161 * We've got to give SOME value for Id & ports, so that
1162 * the packets can be added to the request queue.
1163 * However, we don't want to keep track of used/unused
1164 * id's and ports, as that's a lot of work. This hack
1165 * ensures that (if we have real random numbers), that
1166 * there will be a collision on every 2^(16+15+15+24 - 1)
1167 * packets, on average. That means we can read 2^37
1168 * packets before having a collision, which means it's
1169 * effectively impossible.
1171 packet->id = lrad_rand() & 0xffff;
1172 packet->src_port = 1024 + (lrad_rand() & 0x7fff);
1173 packet->dst_port = 1024 + (lrad_rand() & 0x7fff);
1175 packet->dst_ipaddr.af = AF_INET;
1176 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
1178 packet->vps = data->vps;
1184 data->state = STATE_HEADER;
1187 * Look for Acct-Delay-Time, and update
1188 * based on Acct-Delay-Time += (time(NULL) - timestamp)
1190 vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
1192 vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1193 rad_assert(vp != NULL);
1194 pairadd(&packet->vps, vp);
1196 if (data->timestamp != 0) {
1197 vp->vp_integer += time(NULL) - data->timestamp;
1200 *pfun = rad_accounting;
1203 printf("detail_recv: Read packet from %s\n", data->filename);
1204 for (vp = packet->vps; vp; vp = vp->next) {
1206 vp_print(stdout, vp);
1212 * FIXME: many of these checks may not be necessary when
1213 * reading from the detail file.
1215 if (!received_request(listener, packet, prequest, &detail_client)) {
1225 * Free detail-specific stuff.
1227 static void detail_free(rad_listen_t *this)
1229 listen_detail_t *data = this->data;
1231 free(data->filename);
1232 pairfree(&data->vps);
1234 if (data->fp != NULL) fclose(data->fp);
1238 static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
1240 return snprintf(buffer, bufsize, "%s",
1241 ((listen_detail_t *)(this->data))->filename);
1244 static int detail_encode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
1247 * We never encode responses "sent to" the detail file.
1252 static int detail_decode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
1255 * We never decode responses read from the detail file.
1261 static const CONF_PARSER detail_config[] = {
1262 { "filename", PW_TYPE_STRING_PTR,
1263 offsetof(listen_detail_t, filename), NULL, NULL },
1264 { "load_factor", PW_TYPE_INTEGER,
1265 offsetof(listen_detail_t, load_factor), NULL, Stringify(10)},
1267 { NULL, -1, 0, NULL, NULL } /* end the list */
1272 * Parse a detail section.
1274 static int detail_parse(const char *filename, int lineno,
1275 const CONF_SECTION *cs, rad_listen_t *this)
1278 listen_detail_t *data;
1282 rcode = cf_section_parse(cs, data, detail_config);
1284 radlog(L_ERR, "%s[%d]: Failed parsing listen section",
1289 if (!data->filename) {
1290 radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
1295 if ((data->load_factor < 1) || (data->load_factor > 100)) {
1296 radlog(L_ERR, "%s[%d]: Load factor must be between 1 and 100",
1303 data->state = STATE_UNOPENED;
1311 static int radius_snmp_recv(rad_listen_t *listener,
1312 UNUSED RAD_REQUEST_FUNP *pfun,
1313 UNUSED REQUEST **prequest)
1315 if (!mainconfig.do_snmp) return 0;
1317 if ((rad_snmp.smux_fd >= 0) &&
1318 (rad_snmp.smux_event == SMUX_READ)) {
1323 * If we've got to re-connect, then do so now,
1324 * before calling select again.
1326 if (rad_snmp.smux_event == SMUX_CONNECT) {
1331 * Reset this every time, as the smux connect may have
1332 * opened a new socket.
1334 listener->fd = rad_snmp.smux_fd;
1340 static int radius_snmp_print(rad_listen_t *this, char *buffer, size_t bufsize)
1342 return snprintf(buffer, bufsize, "SMUX with OID .1.3.6.1.4.1.11344.1.1.1");
1347 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1348 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
1352 proxy_socket_recv, proxy_socket_send,
1353 socket_print, proxy_socket_encode, proxy_socket_decode },
1355 /* authentication */
1356 { common_socket_parse, NULL,
1357 auth_socket_recv, auth_socket_send,
1358 socket_print, client_socket_encode, client_socket_decode },
1361 { common_socket_parse, NULL,
1362 acct_socket_recv, acct_socket_send,
1363 socket_print, client_socket_encode, client_socket_decode},
1366 { detail_parse, detail_free,
1367 detail_recv, detail_send,
1368 detail_print, detail_encode, detail_decode },
1370 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_SNMP */
1376 * Binds a listener to a socket.
1378 static int listen_bind(rad_listen_t *this)
1380 rad_listen_t **last;
1381 listen_socket_t *sock = this->data;
1384 * If the port is zero, then it means the appropriate
1385 * thing from /etc/services.
1387 if (sock->port == 0) {
1388 struct servent *svp;
1390 switch (this->type) {
1391 case RAD_LISTEN_AUTH:
1392 svp = getservbyname ("radius", "udp");
1394 sock->port = ntohs(svp->s_port);
1396 sock->port = PW_AUTH_UDP_PORT;
1400 case RAD_LISTEN_ACCT:
1401 svp = getservbyname ("radacct", "udp");
1403 sock->port = ntohs(svp->s_port);
1405 sock->port = PW_ACCT_UDP_PORT;
1410 radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
1416 * Find it in the old list, AFTER updating the port. If
1417 * it's there, use that, rather than creating a new
1418 * socket. This allows HUP's to re-use the old sockets,
1419 * which means that packets waiting in the socket queue
1422 for (last = &mainconfig.listen;
1424 last = &((*last)->next)) {
1425 listen_socket_t *other;
1427 if (this->type != (*last)->type) continue;
1429 if ((this->type == RAD_LISTEN_DETAIL) ||
1430 (this->type == RAD_LISTEN_SNMP)) continue;
1432 other = (listen_socket_t *)((*last)->data);
1434 if ((sock->port == other->port) &&
1435 (sock->ipaddr.af == other->ipaddr.af) &&
1436 (lrad_ipaddr_cmp(&sock->ipaddr, &other->ipaddr) == 0)) {
1437 this->fd = (*last)->fd;
1443 this->fd = lrad_socket(&sock->ipaddr, sock->port);
1445 radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
1452 if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0) {
1453 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
1457 flags |= O_NONBLOCK;
1458 if( fcntl(this->fd, F_SETFL, flags) < 0) {
1459 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
1470 * Allocate & initialize a new listener.
1472 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1476 this = rad_malloc(sizeof(*this));
1477 memset(this, 0, sizeof(*this));
1480 this->recv = master_listen[this->type].recv;
1481 this->send = master_listen[this->type].send;
1482 this->print = master_listen[this->type].print;
1483 this->encode = master_listen[this->type].encode;
1484 this->decode = master_listen[this->type].decode;
1487 case RAD_LISTEN_AUTH:
1488 case RAD_LISTEN_ACCT:
1489 case RAD_LISTEN_PROXY:
1490 this->data = rad_malloc(sizeof(listen_socket_t));
1491 memset(this->data, 0, sizeof(listen_socket_t));
1494 case RAD_LISTEN_DETAIL:
1495 this->data = rad_malloc(sizeof(listen_detail_t));
1496 memset(this->data, 0, sizeof(listen_detail_t));
1507 * Externally visible function for creating a new proxy LISTENER.
1509 * For now, don't take ipaddr or port.
1511 * Not thread-safe, but all calls to it are protected by the
1512 * proxy mutex in request_list.c
1514 rad_listen_t *proxy_new_listener()
1516 int last_proxy_port, port;
1517 rad_listen_t *this, *tmp, **last;
1518 listen_socket_t *sock, *old;
1520 this = listen_alloc(RAD_LISTEN_PROXY);
1523 * Find an existing proxy socket to copy.
1525 * FIXME: Make it per-realm, or per-home server!
1527 last_proxy_port = 0;
1529 last = &mainconfig.listen;
1530 for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1531 if (tmp->type == RAD_LISTEN_PROXY) {
1533 if (sock->port > last_proxy_port) {
1534 last_proxy_port = sock->port + 1;
1536 if (!old) old = sock;
1539 last = &(tmp->next);
1542 if (!old) return NULL; /* This is a serious error. */
1545 * FIXME: find a new IP address to listen on?
1547 * This could likely be done in the "home server"
1548 * configuration, to have per-home-server source IP's.
1551 memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1554 * Keep going until we find an unused port.
1556 for (port = last_proxy_port; port < 64000; port++) {
1558 if (listen_bind(this) == 0) {
1560 * Add the new listener to the list of
1572 static const LRAD_NAME_NUMBER listen_compare[] = {
1573 { "auth", RAD_LISTEN_AUTH },
1574 { "acct", RAD_LISTEN_ACCT },
1575 { "detail", RAD_LISTEN_DETAIL },
1581 * Generate a list of listeners. Takes an input list of
1582 * listeners, too, so we don't close sockets with waiting packets.
1584 int listen_init(const char *filename, rad_listen_t **head)
1588 rad_listen_t **last;
1590 lrad_ipaddr_t server_ipaddr;
1594 * We shouldn't be called with a pre-existing list.
1596 rad_assert(head && (*head == NULL));
1599 server_ipaddr.af = AF_UNSPEC;
1602 * If the port is specified on the command-line,
1603 * it over-rides the configuration file.
1605 if (mainconfig.port >= 0) {
1606 auth_port = mainconfig.port;
1608 rcode = cf_item_parse(mainconfig.config, "port",
1609 PW_TYPE_INTEGER, &auth_port,
1610 Stringify(PW_AUTH_UDP_PORT));
1611 if (rcode < 0) return -1; /* error parsing it */
1614 radlog(L_INFO, "WARNING: The directive 'port' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1618 * If the IP address was configured on the command-line,
1619 * use that as the "bind_address"
1621 if (mainconfig.myip.af != AF_UNSPEC) {
1622 memcpy(&server_ipaddr, &mainconfig.myip,
1623 sizeof(server_ipaddr));
1628 * Else look for bind_address and/or listen sections.
1630 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1631 rcode = cf_item_parse(mainconfig.config, "bind_address",
1633 &server_ipaddr.ipaddr.ip4addr, NULL);
1634 if (rcode < 0) return -1; /* error parsing it */
1636 if (rcode == 0) { /* successfully parsed IPv4 */
1637 listen_socket_t *sock;
1638 server_ipaddr.af = AF_INET;
1640 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'.");
1643 this = listen_alloc(RAD_LISTEN_AUTH);
1646 sock->ipaddr = server_ipaddr;
1647 sock->port = auth_port;
1649 if (listen_bind(this) < 0) {
1652 radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1655 auth_port = sock->port; /* may have been updated in listen_bind */
1657 last = &(this->next);
1660 * Open Accounting Socket.
1662 * If we haven't already gotten acct_port from
1663 * /etc/services, then make it auth_port + 1.
1665 this = listen_alloc(RAD_LISTEN_ACCT);
1669 * Create the accounting socket.
1671 * The accounting port is always the
1672 * authentication port + 1
1674 sock->ipaddr = server_ipaddr;
1675 sock->port = auth_port + 1;
1677 if (listen_bind(this) < 0) {
1680 radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1685 last = &(this->next);
1687 } else if (mainconfig.port > 0) { /* no bind address, but a port */
1688 radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1694 * They specified an IP on the command-line, ignore
1695 * all listen sections.
1697 if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
1700 * Walk through the "listen" sections, if they exist.
1702 for (cs = cf_subsection_find_next(mainconfig.config, NULL, "listen");
1704 cs = cf_subsection_find_next(mainconfig.config, cs, "listen")) {
1706 char *listen_type, *identity;
1707 int lineno = cf_section_lineno(cs);
1709 listen_type = identity = NULL;
1711 DEBUG2(" listen {");
1713 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1715 if (rcode < 0) return -1;
1719 radlog(L_ERR, "%s[%d]: No type specified in listen section",
1725 * See if there's an identity.
1727 rcode = cf_item_parse(cs, "identity", PW_TYPE_STRING_PTR,
1735 type = lrad_str2int(listen_compare, listen_type,
1738 if (type == RAD_LISTEN_NONE) {
1740 radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
1746 * Set up cross-type data.
1748 this = listen_alloc(type);
1749 this->identity = identity;
1753 * Call per-type parser.
1755 if (master_listen[type].parse(filename, lineno,
1765 last = &(this->next);
1769 * If we're proxying requests, open the proxy FD.
1770 * Otherwise, don't do anything.
1773 if (mainconfig.proxy_requests == TRUE) {
1775 listen_socket_t *sock = NULL;
1778 * No sockets to receive packets, therefore
1779 * proxying is pointless.
1781 if (!*head) return -1;
1784 * If we previously had proxy sockets, copy them
1785 * to the new config.
1787 if (mainconfig.listen != NULL) {
1788 rad_listen_t *old, *next, **tail;
1790 tail = &mainconfig.listen;
1791 for (old = mainconfig.listen;
1796 if (old->type != RAD_LISTEN_PROXY) {
1797 tail = &((*tail)->next);
1804 last = &(old->next);
1811 * Find the first authentication port,
1814 for (this = *head; this != NULL; this = this->next) {
1815 if (this->type == RAD_LISTEN_AUTH) {
1817 if (server_ipaddr.af == AF_UNSPEC) {
1818 server_ipaddr = sock->ipaddr;
1820 port = sock->port + 2; /* skip acct port */
1825 if (port < 0) port = 1024 + (lrad_rand() & 0x1ff);
1828 * Address is still unspecified, use IPv4.
1830 if (server_ipaddr.af == AF_UNSPEC) {
1831 server_ipaddr.af = AF_INET;
1832 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
1835 this = listen_alloc(RAD_LISTEN_PROXY);
1839 * Create the first proxy socket.
1841 sock->ipaddr = server_ipaddr;
1844 * Try to find a proxy port (value doesn't matter)
1846 for (sock->port = port;
1849 if (listen_bind(this) == 0) {
1851 last = &(this->next); /* just in case */
1856 if (sock->port >= 64000) {
1859 radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
1866 if (mainconfig.do_snmp) {
1870 * Forget about the old one.
1872 for (this = mainconfig.listen;
1874 this = this->next) {
1875 if (this->type != RAD_LISTEN_SNMP) continue;
1879 this = rad_malloc(sizeof(*this));
1880 memset(this, 0, sizeof(*this));
1882 this->type = RAD_LISTEN_SNMP;
1883 this->fd = rad_snmp.smux_fd;
1885 this->recv = radius_snmp_recv;
1886 this->print = radius_snmp_print;
1889 last = &(this->next);
1898 * Free a linked list of listeners;
1900 void listen_free(rad_listen_t **head)
1904 if (!head || !*head) return;
1908 rad_listen_t *next = this->next;
1910 free(this->identity);
1913 * Other code may have eaten the FD.
1915 if (this->fd >= 0) close(this->fd);
1917 if (master_listen[this->type].free) {
1918 master_listen[this->type].free(this);