Exemple #1
0
static void request_stats_reply(REQUEST *request)
{
	VALUE_PAIR *flag, *vp;

	/*
	 *	Statistics are available ONLY on a "status" port.
	 */
	rad_assert(request->packet->code == PW_STATUS_SERVER);
	rad_assert(request->listener->type == RAD_LISTEN_NONE);
		
	flag = pairfind(request->packet->vps, FR2ATTR(127));
	if (!flag || (flag->vp_integer == 0)) return;

	/*
	 *	Authentication.
	 */
	if (((flag->vp_integer & 0x01) != 0) &&
	    ((flag->vp_integer & 0xc0) == 0)) {
		request_stats_addvp(request, authvp, &radius_auth_stats);
	}
		
#ifdef WITH_ACCOUNTING
	/*
	 *	Accounting
	 */
	if (((flag->vp_integer & 0x02) != 0) &&
	    ((flag->vp_integer & 0xc0) == 0)) {
		request_stats_addvp(request, acctvp, &radius_acct_stats);
	}
#endif

#ifdef WITH_PROXY
	/*
	 *	Proxied authentication requests.
	 */
	if (((flag->vp_integer & 0x04) != 0) &&
	    ((flag->vp_integer & 0x20) == 0)) {
		request_stats_addvp(request, proxy_authvp, &proxy_auth_stats);
	}

#ifdef WITH_ACCOUNTING
	/*
	 *	Proxied accounting requests.
	 */
	if (((flag->vp_integer & 0x08) != 0) &&
	    ((flag->vp_integer & 0x20) == 0)) {
		request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats);
	}
#endif
#endif

	/*
	 *	Internal server statistics
	 */
	if ((flag->vp_integer & 0x10) != 0) {
		vp = radius_paircreate(request, &request->reply->vps,
				       FR2ATTR(176), PW_TYPE_DATE);
		if (vp) vp->vp_date = radius_start_time.tv_sec;
		vp = radius_paircreate(request, &request->reply->vps,
				       FR2ATTR(177), PW_TYPE_DATE);
		if (vp) vp->vp_date = radius_hup_time.tv_sec;
		
#ifdef HAVE_PTHREAD_H
		int i, array[RAD_LISTEN_MAX];

		thread_pool_queue_stats(array);

		for (i = 0; i <= RAD_LISTEN_DETAIL; i++) {
			vp = radius_paircreate(request, &request->reply->vps,
					       FR2ATTR(162 + i),
					       PW_TYPE_INTEGER);
			
			if (!vp) continue;
			vp->vp_integer = array[i];
		}
#endif
	}

	/*
	 *	For a particular client.
	 */
	if ((flag->vp_integer & 0x20) != 0) {
		fr_ipaddr_t ipaddr;
		VALUE_PAIR *server_ip, *server_port = NULL;
		RADCLIENT *client = NULL;
		RADCLIENT_LIST *cl = NULL;

		/*
		 *	See if we need to look up the client by server
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, FR2ATTR(170));
		if (server_ip) {
			server_port = pairfind(request->packet->vps,
					       FR2ATTR(171));

			if (server_port) {
				ipaddr.af = AF_INET;
				ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
				cl = listener_find_client_list(&ipaddr, server_port->vp_integer);
							       
				/*
				 *	Not found: don't do anything
				 */
				if (!cl) return;
			}
		}


		vp = pairfind(request->packet->vps, FR2ATTR(167));
		if (vp) {
			ipaddr.af = AF_INET;
			ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
			client = client_find(cl, &ipaddr);

			/*
			 *	Else look it up by number.
			 */
		} else if ((vp = pairfind(request->packet->vps,
					   FR2ATTR(168))) != NULL) {
			client = client_findbynumber(cl, vp->vp_integer);
		}

		if (client) {
			/*
			 *	If found, echo it back, along with
			 *	the requested statistics.
			 */
			pairadd(&request->reply->vps, paircopyvp(vp));

			/*
			 *	When retrieving client by number, also
			 *	echo back it's IP address.
			 */
			if ((vp->type == PW_TYPE_INTEGER) &&
			    (client->ipaddr.af == AF_INET)) {
				vp = radius_paircreate(request,
						       &request->reply->vps,
						       FR2ATTR(167),
						       PW_TYPE_IPADDR);
				if (vp) {
					vp->vp_ipaddr = client->ipaddr.ipaddr.ip4addr.s_addr;
				}

				if (client->prefix != 32) {
					vp = radius_paircreate(request,
							       &request->reply->vps,
							       FR2ATTR(169),
							       PW_TYPE_INTEGER);
					if (vp) {
						vp->vp_integer = client->prefix;
					}
				}
			}
			
			if (server_ip) {
				pairadd(&request->reply->vps,
					paircopyvp(server_ip));
				pairadd(&request->reply->vps,
					paircopyvp(server_port));
			}

			if (client->auth &&
			    ((flag->vp_integer & 0x01) != 0)) {
				request_stats_addvp(request, client_authvp,
						    client->auth);
			}
#ifdef WITH_ACCOUNTING
			if (client->acct &&
			    ((flag->vp_integer & 0x01) != 0)) {
				request_stats_addvp(request, client_acctvp,
						    client->acct);
			}
#endif
		} /* else client wasn't found, don't echo it back */
	}

	/*
	 *	For a particular "listen" socket.
	 */
	if (((flag->vp_integer & 0x40) != 0) &&
	    ((flag->vp_integer & 0x03) != 0)) {
		rad_listen_t *this;
		VALUE_PAIR *server_ip, *server_port;
		fr_ipaddr_t ipaddr;

		/*
		 *	See if we need to look up the server by socket
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, FR2ATTR(170));
		if (!server_ip) return;

		server_port = pairfind(request->packet->vps,
				       FR2ATTR(171));
		if (!server_port) return;
		
		ipaddr.af = AF_INET;
		ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
		this = listener_find_byipaddr(&ipaddr,
					      server_port->vp_integer);
		
		/*
		 *	Not found: don't do anything
		 */
		if (!this) return;
		
		pairadd(&request->reply->vps,
			paircopyvp(server_ip));
		pairadd(&request->reply->vps,
			paircopyvp(server_port));

		if (((flag->vp_integer & 0x01) != 0) &&
		    ((request->listener->type == RAD_LISTEN_AUTH) ||
		     (request->listener->type == RAD_LISTEN_NONE))) {
			request_stats_addvp(request, authvp, &this->stats);
		}
		
#ifdef WITH_ACCOUNTING
		if (((flag->vp_integer & 0x02) != 0) &&
		    ((request->listener->type == RAD_LISTEN_ACCT) ||
		     (request->listener->type == RAD_LISTEN_NONE))) {
			request_stats_addvp(request, acctvp, &this->stats);
		}
#endif
	}

	/*
	 *	Home servers.
	 */
	if (((flag->vp_integer & 0x80) != 0) &&
	    ((flag->vp_integer & 0x03) != 0)) {
		home_server *home;
		VALUE_PAIR *server_ip, *server_port;
		fr_ipaddr_t ipaddr;

		/*
		 *	See if we need to look up the server by socket
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, FR2ATTR(170));
		if (!server_ip) return;

		server_port = pairfind(request->packet->vps,
				       FR2ATTR(171));
		if (!server_port) return;
		
		ipaddr.af = AF_INET;
		ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
		home = home_server_find(&ipaddr, server_port->vp_integer);

		/*
		 *	Not found: don't do anything
		 */
		if (!home) return;
		
		pairadd(&request->reply->vps,
			paircopyvp(server_ip));
		pairadd(&request->reply->vps,
			paircopyvp(server_port));

		vp = radius_paircreate(request, &request->reply->vps,
				       FR2ATTR(172), PW_TYPE_INTEGER);
		if (vp) vp->vp_integer = home->currently_outstanding;

		vp = radius_paircreate(request, &request->reply->vps,
				       FR2ATTR(173), PW_TYPE_INTEGER);
		if (vp) vp->vp_integer = home->state;

		if ((home->state == HOME_STATE_ALIVE) &&
		    (home->revive_time.tv_sec != 0)) {
			vp = radius_paircreate(request, &request->reply->vps,
					       FR2ATTR(175), PW_TYPE_DATE);
			if (vp) vp->vp_date = home->revive_time.tv_sec;
		}

		if ((home->state == HOME_STATE_ALIVE) &&
		    (home->ema.window > 0)) {
				vp = radius_paircreate(request,
						       &request->reply->vps,
						       FR2ATTR(178),
						       PW_TYPE_INTEGER);
				if (vp) vp->vp_integer = home->ema.window;
				vp = radius_paircreate(request,
						       &request->reply->vps,
						       FR2ATTR(179),
						       PW_TYPE_INTEGER);
				if (vp) vp->vp_integer = home->ema.ema1 / EMA_SCALE;
				vp = radius_paircreate(request,
						       &request->reply->vps,
						       FR2ATTR(180),
						       PW_TYPE_INTEGER);
				if (vp) vp->vp_integer = home->ema.ema10 / EMA_SCALE;

		}

		if (home->state == HOME_STATE_IS_DEAD) {
			vp = radius_paircreate(request, &request->reply->vps,
					       FR2ATTR(174), PW_TYPE_DATE);
			if (vp) vp->vp_date = home->zombie_period_start.tv_sec + home->zombie_period;
		}

		if (((flag->vp_integer & 0x01) != 0) &&
		    (home->type == HOME_TYPE_AUTH)) {
			request_stats_addvp(request, proxy_authvp,
					    &home->stats);
		}

#ifdef WITH_ACCOUNTING
		if (((flag->vp_integer & 0x02) != 0) &&
		    (home->type == HOME_TYPE_ACCT)) {
			request_stats_addvp(request, proxy_acctvp,
					    &home->stats);
		}
#endif
	}
}
void request_stats_reply(REQUEST *request)
{
	VALUE_PAIR *flag, *vp;

	/*
	 *	Statistics are available ONLY on a "status" port.
	 */
	rad_assert(request->packet->code == PW_CODE_STATUS_SERVER);
	rad_assert(request->listener->type == RAD_LISTEN_NONE);

	flag = pairfind(request->packet->vps, 127, VENDORPEC_FREERADIUS, TAG_ANY);
	if (!flag || (flag->vp_integer == 0)) return;

	/*
	 *	Authentication.
	 */
	if (((flag->vp_integer & 0x01) != 0) &&
	    ((flag->vp_integer & 0xc0) == 0)) {
		request_stats_addvp(request, authvp, &radius_auth_stats);
	}

#ifdef WITH_ACCOUNTING
	/*
	 *	Accounting
	 */
	if (((flag->vp_integer & 0x02) != 0) &&
	    ((flag->vp_integer & 0xc0) == 0)) {
		request_stats_addvp(request, acctvp, &radius_acct_stats);
	}
#endif

#ifdef WITH_PROXY
	/*
	 *	Proxied authentication requests.
	 */
	if (((flag->vp_integer & 0x04) != 0) &&
	    ((flag->vp_integer & 0x20) == 0)) {
		request_stats_addvp(request, proxy_authvp, &proxy_auth_stats);
	}

#ifdef WITH_ACCOUNTING
	/*
	 *	Proxied accounting requests.
	 */
	if (((flag->vp_integer & 0x08) != 0) &&
	    ((flag->vp_integer & 0x20) == 0)) {
		request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats);
	}
#endif
#endif

	/*
	 *	Internal server statistics
	 */
	if ((flag->vp_integer & 0x10) != 0) {
		vp = radius_paircreate(request->reply, &request->reply->vps,
				       176, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_date = start_time.tv_sec;
		vp = radius_paircreate(request->reply, &request->reply->vps,
				       177, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_date = hup_time.tv_sec;

#ifdef HAVE_PTHREAD_H
		int i, array[RAD_LISTEN_MAX], pps[2];

		thread_pool_queue_stats(array, pps);

		for (i = 0; i <= 4; i++) {
			vp = radius_paircreate(request->reply, &request->reply->vps,
					       162 + i, VENDORPEC_FREERADIUS);

			if (!vp) continue;
			vp->vp_integer = array[i];
		}

		for (i = 0; i < 2; i++) {
			vp = radius_paircreate(request->reply, &request->reply->vps,
					       181 + i, VENDORPEC_FREERADIUS);

			if (!vp) continue;
			vp->vp_integer = pps[i];
		}
#endif
	}

	/*
	 *	For a particular client.
	 */
	if ((flag->vp_integer & 0x20) != 0) {
		fr_ipaddr_t ipaddr;
		VALUE_PAIR *server_ip, *server_port = NULL;
		RADCLIENT *client = NULL;
		RADCLIENT_LIST *cl = NULL;

		/*
		 *	See if we need to look up the client by server
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY);
		if (server_ip) {
			server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY);

			if (server_port) {
				ipaddr.af = AF_INET;
				ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
				cl = listener_find_client_list(&ipaddr, server_port->vp_integer, IPPROTO_UDP);

				/*
				 *	Not found: don't do anything
				 */
				if (!cl) return;
			}
		}


		vp = pairfind(request->packet->vps, 167, VENDORPEC_FREERADIUS, TAG_ANY);
		if (vp) {
			memset(&ipaddr, 0, sizeof(ipaddr));
			ipaddr.af = AF_INET;
			ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
			client = client_find(cl, &ipaddr, IPPROTO_UDP);
#ifdef WITH_TCP
			if (!client) {
				client = client_find(cl, &ipaddr, IPPROTO_TCP);
			}
#endif

			/*
			 *	Else look it up by number.
			 */
		} else if ((vp = pairfind(request->packet->vps, 168, VENDORPEC_FREERADIUS, TAG_ANY)) != NULL) {
			client = client_findbynumber(cl, vp->vp_integer);
		}

		if (client) {
			/*
			 *	If found, echo it back, along with
			 *	the requested statistics.
			 */
			pairadd(&request->reply->vps, paircopyvp(request->reply, vp));

			/*
			 *	When retrieving client by number, also
			 *	echo back it's IP address.
			 */
			if ((vp->da->type == PW_TYPE_INTEGER) &&
			    (client->ipaddr.af == AF_INET)) {
				vp = radius_paircreate(request->reply,
						       &request->reply->vps,
						       167, VENDORPEC_FREERADIUS);
				if (vp) {
					vp->vp_ipaddr = client->ipaddr.ipaddr.ip4addr.s_addr;
				}

				if (client->ipaddr.prefix != 32) {
					vp = radius_paircreate(request->reply,
							       &request->reply->vps,
							       169, VENDORPEC_FREERADIUS);
					if (vp) {
						vp->vp_integer = client->ipaddr.prefix;
					}
				}
			}

			if (server_ip) {
				pairadd(&request->reply->vps,
					paircopyvp(request->reply, server_ip));
			}
			if (server_port) {
				pairadd(&request->reply->vps,
					paircopyvp(request->reply, server_port));
			}

			if ((flag->vp_integer & 0x01) != 0) {
				request_stats_addvp(request, client_authvp,
						    &client->auth);
			}
#ifdef WITH_ACCOUNTING
			if ((flag->vp_integer & 0x01) != 0) {
				request_stats_addvp(request, client_acctvp,
						    &client->acct);
			}
#endif
		} /* else client wasn't found, don't echo it back */
	}

	/*
	 *	For a particular "listen" socket.
	 */
	if (((flag->vp_integer & 0x40) != 0) &&
	    ((flag->vp_integer & 0x03) != 0)) {
		rad_listen_t *this;
		VALUE_PAIR *server_ip, *server_port;
		fr_ipaddr_t ipaddr;

		/*
		 *	See if we need to look up the server by socket
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY);
		if (!server_ip) return;

		server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY);
		if (!server_port) return;

		ipaddr.af = AF_INET;
		ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
		this = listener_find_byipaddr(&ipaddr,
					      server_port->vp_integer,
					      IPPROTO_UDP);

		/*
		 *	Not found: don't do anything
		 */
		if (!this) return;

		pairadd(&request->reply->vps,
			paircopyvp(request->reply, server_ip));
		pairadd(&request->reply->vps,
			paircopyvp(request->reply, server_port));

		if (((flag->vp_integer & 0x01) != 0) &&
		    ((request->listener->type == RAD_LISTEN_AUTH) ||
		     (request->listener->type == RAD_LISTEN_NONE))) {
			request_stats_addvp(request, authvp, &this->stats);
		}

#ifdef WITH_ACCOUNTING
		if (((flag->vp_integer & 0x02) != 0) &&
		    ((request->listener->type == RAD_LISTEN_ACCT) ||
		     (request->listener->type == RAD_LISTEN_NONE))) {
			request_stats_addvp(request, acctvp, &this->stats);
		}
#endif
	}

#ifdef WITH_PROXY
	/*
	 *	Home servers.
	 */
	if (((flag->vp_integer & 0x80) != 0) &&
	    ((flag->vp_integer & 0x03) != 0)) {
		home_server_t *home;
		VALUE_PAIR *server_ip, *server_port;
		fr_ipaddr_t ipaddr;

		/*
		 *	See if we need to look up the server by socket
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY);
		if (!server_ip) return;

		server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY);
		if (!server_port) return;

#ifndef NDEBUG
		memset(&ipaddr, 0, sizeof(ipaddr));
#endif
		ipaddr.af = AF_INET;
		ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
		home = home_server_find(&ipaddr, server_port->vp_integer,
					IPPROTO_UDP);

		/*
		 *	Not found: don't do anything
		 */
		if (!home) return;

		pairadd(&request->reply->vps,
			paircopyvp(request->reply, server_ip));
		pairadd(&request->reply->vps,
			paircopyvp(request->reply, server_port));

		vp = radius_paircreate(request->reply, &request->reply->vps,
				       172, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_integer = home->currently_outstanding;

		vp = radius_paircreate(request->reply, &request->reply->vps,
				       173, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_integer = home->state;

		if ((home->state == HOME_STATE_ALIVE) &&
		    (home->revive_time.tv_sec != 0)) {
			vp = radius_paircreate(request->reply, &request->reply->vps,
					       175, VENDORPEC_FREERADIUS);
			if (vp) vp->vp_date = home->revive_time.tv_sec;
		}

		if ((home->state == HOME_STATE_ALIVE) &&
		    (home->ema.window > 0)) {
				vp = radius_paircreate(request->reply,
						       &request->reply->vps,
						       178, VENDORPEC_FREERADIUS);
				if (vp) vp->vp_integer = home->ema.window;
				vp = radius_paircreate(request->reply,
						       &request->reply->vps,
						       179, VENDORPEC_FREERADIUS);
				if (vp) vp->vp_integer = home->ema.ema1 / EMA_SCALE;
				vp = radius_paircreate(request->reply,
						       &request->reply->vps,
						       180, VENDORPEC_FREERADIUS);
				if (vp) vp->vp_integer = home->ema.ema10 / EMA_SCALE;

		}

		if (home->state == HOME_STATE_IS_DEAD) {
			vp = radius_paircreate(request->reply, &request->reply->vps,
					       174, VENDORPEC_FREERADIUS);
			if (vp) vp->vp_date = home->zombie_period_start.tv_sec + home->zombie_period;
		}

		/*
		 *	Show more information...
		 *
		 *	FIXME: do this for clients, too!
		 */
		vp = radius_paircreate(request->reply, &request->reply->vps,
				       184, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_date = home->last_packet_recv;

		vp = radius_paircreate(request->reply, &request->reply->vps,
				       185, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_date = home->last_packet_sent;

		if (((flag->vp_integer & 0x01) != 0) &&
		    (home->type == HOME_TYPE_AUTH)) {
			request_stats_addvp(request, proxy_authvp,
					    &home->stats);
		}

#ifdef WITH_ACCOUNTING
		if (((flag->vp_integer & 0x02) != 0) &&
		    (home->type == HOME_TYPE_ACCT)) {
			request_stats_addvp(request, proxy_acctvp,
					    &home->stats);
		}
#endif
	}
#endif	/* WITH_PROXY */
}