From 7a613d8e35a71a981668bd39ab9cff3080f6d45f Mon Sep 17 00:00:00 2001 From: aland Date: Fri, 20 Jun 2008 07:26:10 +0000 Subject: [PATCH] Thread queue stats && per-client stats --- share/dictionary.freeradius | 22 +++++++- src/main/stats.c | 130 +++++++++++++++++++++++++++++++++++++++++--- src/main/threads.c | 15 +++++ 3 files changed, 156 insertions(+), 11 deletions(-) diff --git a/share/dictionary.freeradius b/share/dictionary.freeradius index d0f0980..cde3023 100644 --- a/share/dictionary.freeradius +++ b/share/dictionary.freeradius @@ -25,10 +25,13 @@ VALUE FreeRADIUS-Statistics-Type Authentication 1 VALUE FreeRADIUS-Statistics-Type Accounting 2 VALUE FreeRADIUS-Statistics-Type Proxy-Authentication 4 VALUE FreeRADIUS-Statistics-Type Proxy-Accounting 8 +VALUE FreeRADIUS-Statistics-Type Request-Queue 0x10 +VALUE FreeRADIUS-Statistics-Type Client 0x20 -VALUE FreeRADIUS-Statistics-Type Auth-Acct 3 -VALUE FreeRADIUS-Statistics-Type Proxy-Auth-Acct 12 -VALUE FreeRADIUS-Statistics-Type All 15 +VALUE FreeRADIUS-Statistics-Type Auth-Acct 0x03 +VALUE FreeRADIUS-Statistics-Type Proxy-Auth-Acct 0x0c + +VALUE FreeRADIUS-Statistics-Type All 0x1f # # Note that these statistics are available ONLY for packets @@ -85,4 +88,17 @@ ATTRIBUTE FreeRADIUS-Total-Proxy-Acct-Invalid-Requests 159 integer ATTRIBUTE FreeRADIUS-Total-Proxy-Acct-Dropped-Requests 160 integer ATTRIBUTE FreeRADIUS-Total-Proxy-Acct-Unknown-Types 161 integer +# +# Internal queues. Different packet types are put into different queues. +# +ATTRIBUTE FreeRADIUS-Queue-Len-Internal 162 integer +ATTRIBUTE FreeRADIUS-Queue-Len-Proxy 163 integer +ATTRIBUTE FreeRADIUS-Queue-Len-Auth 164 integer +ATTRIBUTE FreeRADIUS-Queue-Len-Acct 165 integer +ATTRIBUTE FreeRADIUS-Queue-Len-Detail 166 integer + +ATTRIBUTE FreeRADIUS-Stats-Client-IP-Address 167 ipaddr +ATTRIBUTE FreeRADIUS-Stats-Client-Number 168 integer +ATTRIBUTE FreeRADIUS-Stats-Client-Netmask 169 integer + END-VENDOR FreeRADIUS diff --git a/src/main/stats.c b/src/main/stats.c index 44e9080..2a97357 100644 --- a/src/main/stats.c +++ b/src/main/stats.c @@ -232,11 +232,37 @@ static fr_stats2vp proxy_acctvp[] = { #endif #endif +static fr_stats2vp client_authvp[] = { + { 128, offsetof(fr_client_stats_t, requests) }, + { 129, offsetof(fr_client_stats_t, accepts) }, + { 130, offsetof(fr_client_stats_t, rejects) }, + { 131, offsetof(fr_client_stats_t, challenges) }, + { 132, offsetof(fr_client_stats_t, responses) }, + { 133, offsetof(fr_client_stats_t, dup_requests) }, + { 134, offsetof(fr_client_stats_t, malformed_requests) }, + { 135, offsetof(fr_client_stats_t, bad_authenticators) }, + { 136, offsetof(fr_client_stats_t, packets_dropped) }, + { 137, offsetof(fr_client_stats_t, unknown_types) }, + { 0, 0 } +}; + +#ifdef WITH_ACCOUNTING +static fr_stats2vp client_acctvp[] = { + { 155, offsetof(fr_client_stats_t, requests) }, + { 156, offsetof(fr_client_stats_t, responses) }, + { 157, offsetof(fr_client_stats_t, dup_requests) }, + { 158, offsetof(fr_client_stats_t, malformed_requests) }, + { 159, offsetof(fr_client_stats_t, bad_authenticators) }, + { 160, offsetof(fr_client_stats_t, packets_dropped) }, + { 161, offsetof(fr_client_stats_t, unknown_types) }, + { 0, 0 } +}; +#endif #define FR2ATTR(x) ((11344 << 16) | (x)) static void request_stats_addvp(REQUEST *request, - fr_stats2vp *table, fr_stats_t *stats) + fr_stats2vp *table, void *stats) { int i; VALUE_PAIR *vp; @@ -254,38 +280,126 @@ static void request_stats_addvp(REQUEST *request, void request_stats_reply(REQUEST *request) { - VALUE_PAIR *vp; + VALUE_PAIR *flag, *vp; if (request->packet->code != PW_STATUS_SERVER) return; if ((request->packet->src_ipaddr.af != AF_INET) || (request->packet->src_ipaddr.ipaddr.ip4addr.s_addr != htonl(INADDR_LOOPBACK))) return; - vp = pairfind(request->packet->vps, FR2ATTR(127)); - if (!vp || (vp->vp_integer == 0)) return; + flag = pairfind(request->packet->vps, FR2ATTR(127)); + if (!flag || (flag->vp_integer == 0)) return; - if (vp->vp_integer & 0x01) { + if (((flag->vp_integer & 0x01) != 0) && + ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, authvp, &radius_auth_stats); } #ifdef WITH_ACCOUNTING - if (vp->vp_integer & 0x02) { + if (((flag->vp_integer & 0x02) != 0) && + ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, acctvp, &radius_acct_stats); } #endif #ifdef WITH_PROXY - if (vp->vp_integer & 0x04) { + if (((flag->vp_integer & 0x04) != 0) && + ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_authvp, &proxy_auth_stats); } #ifdef WITH_ACCOUNTING - if (vp->vp_integer & 0x08) { + if (((flag->vp_integer & 0x08) != 0) && + ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats); } #endif #endif + +#ifdef HAVE_PTHREAD_H + if ((flag->vp_integer & 0x10) != 0) { + 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 + + if ((flag->vp_integer & 0x20) != 0) { + fr_ipaddr_t ipaddr; + RADCLIENT *client = NULL; + RADCLIENT_LIST *cl = NULL; + + 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 (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 */ + } + } #endif /* WITH_STATS */ diff --git a/src/main/threads.c b/src/main/threads.c index 90dd33a..b572bc1 100644 --- a/src/main/threads.c +++ b/src/main/threads.c @@ -1111,4 +1111,19 @@ void thread_pool_unlock(void) { pthread_mutex_unlock(&thread_pool.queue_mutex); } + +void thread_pool_queue_stats(int *array) +{ + int i; + + if (pool_initialized) { + for (i = 0; i < RAD_LISTEN_MAX; i++) { + array[i] = fr_fifo_num_elements(thread_pool.fifo[i]); + } + } else { + for (i = 0; i < RAD_LISTEN_MAX; i++) { + array[i] = 0; + } + } +} #endif /* HAVE_PTHREAD_H */ -- 2.1.4