diff --git a/daemon/call.h b/daemon/call.h index fe9308fe5..2c946f062 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -11,7 +11,7 @@ #include #include #include "compat.h" - +#include "control_ng.h" enum termination_reason { UNKNOWN=0, @@ -412,6 +412,7 @@ struct callmaster { struct stats stats; /* copied from statsps once a second */ struct totalstats totalstats; struct totalstats totalstats_interval; + struct control_ng_stats* control_ng_stats; struct poller *poller; pcre *info_re; diff --git a/daemon/cli.c b/daemon/cli.c index fb32996bb..f7547914b 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -49,6 +49,35 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m ADJUSTLEN(printlen,outbufend,replybuffer); printlen = snprintf(replybuffer,(outbufend-replybuffer), " Average call duration :%ld.%06ld\n\n",m->totalstats.total_average_call_dur.tv_sec,m->totalstats.total_average_call_dur.tv_usec); ADJUSTLEN(printlen,outbufend,replybuffer); + printlen = snprintf(replybuffer,(outbufend-replybuffer), "Control statistics:\n\n"); + ADJUSTLEN(printlen,outbufend,replybuffer); + printlen = snprintf(replybuffer,(outbufend-replybuffer), " %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n", + "Proxy", "Offer", "Answer", "Delete", "Ping", "List", "Query", "Errors"); + ADJUSTLEN(printlen,outbufend,replybuffer); + struct control_ng_stats* cur = m->control_ng_stats; + + if (!cur) { + printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n No proxies have yet tried to send data."); + ADJUSTLEN(printlen,outbufend,replybuffer); + } + while (cur) { + char buf[128]; memset(&buf,0,128); + smart_ntop_p(buf, &(cur->proxy.sin6_addr), sizeof(buf)); + + printlen = snprintf(replybuffer,(outbufend-replybuffer), " %10s | %10u | %10u | %10u | %10u | %10u | %10u | %10u \n", + buf, + cur->offer, + cur->answer, + cur->delete, + cur->ping, + cur->list, + cur->query, + cur->errors); + ADJUSTLEN(printlen,outbufend,replybuffer); + cur = cur->next; + } + printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n\n"); + ADJUSTLEN(printlen,outbufend,replybuffer); } static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { diff --git a/daemon/control_ng.c b/daemon/control_ng.c index d568520b0..ca42fc534 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -56,6 +56,44 @@ static void pretty_print(bencode_item_t *el, GString *s) { } } +struct control_ng_stats* get_control_ng_stats(struct control_ng* c, struct sockaddr_in6* sin) { + + // seems to be the first address + if (!c->callmaster->control_ng_stats) { + c->callmaster->control_ng_stats = malloc(sizeof(struct control_ng_stats)); + memset(c->callmaster->control_ng_stats,0,sizeof(struct control_ng_stats)); + memcpy(&(c->callmaster->control_ng_stats->proxy),sin,sizeof(struct sockaddr_in6)); + char buf[128]; memset(&buf,0,128); + smart_ntop_p(buf, &sin->sin6_addr, sizeof(buf)); + ilog(LOG_INFO,"Adding a first proxy for control ng stats:%s\n",buf); + return c->callmaster->control_ng_stats; + } + + struct control_ng_stats* cur = c->callmaster->control_ng_stats; + struct control_ng_stats* last; + + while (cur) { + last = cur; + if (memcmp((const void*)(&(cur->proxy.sin6_addr)),(const void*)(&(sin->sin6_addr)),sizeof(struct in6_addr))==0) { + ilog(LOG_DEBUG,"Already found proxy for control ng stats.\n"); + return cur; + } + cur = cur->next; + } + + // add a new one + char buf[128]; memset(&buf,0,128); + smart_ntop_p(buf, &sin->sin6_addr, sizeof(buf)); + ilog(LOG_INFO,"Adding a new proxy for control ng stats:%s\n",buf); + + cur = malloc(sizeof(struct control_ng_stats)); + memset(cur,0,sizeof(struct control_ng_stats)); + memcpy(cur,sin,sizeof(struct sockaddr_in6)); + last->next = cur; + + return cur; +} + static void control_ng_incoming(struct obj *obj, str *buf, struct sockaddr_in6 *sin, char *addr) { struct control_ng *c = (void *) obj; bencode_buffer_t bencbuf; @@ -66,6 +104,8 @@ static void control_ng_incoming(struct obj *obj, str *buf, struct sockaddr_in6 * struct iovec iov[3]; GString *log_str; + struct control_ng_stats* cur = get_control_ng_stats(c,sin); + str_chr_str(&data, buf, ' '); if (!data.s || data.s == buf->s) { ilog(LOG_WARNING, "Received invalid data on NG port (no cookie) from %s: "STR_FORMAT, addr, STR_FMT(buf)); @@ -108,19 +148,31 @@ static void control_ng_incoming(struct obj *obj, str *buf, struct sockaddr_in6 * g_string_free(log_str, TRUE); errstr = NULL; - if (!str_cmp(&cmd, "ping")) + if (!str_cmp(&cmd, "ping")) { bencode_dictionary_add_string(resp, "result", "pong"); - else if (!str_cmp(&cmd, "offer")) + cur->ping++; + } + else if (!str_cmp(&cmd, "offer")) { errstr = call_offer_ng(dict, c->callmaster, resp, addr, sin); - else if (!str_cmp(&cmd, "answer")) + cur->offer++; + } + else if (!str_cmp(&cmd, "answer")) { errstr = call_answer_ng(dict, c->callmaster, resp); - else if (!str_cmp(&cmd, "delete")) + cur->answer++; + } + else if (!str_cmp(&cmd, "delete")) { errstr = call_delete_ng(dict, c->callmaster, resp); - else if (!str_cmp(&cmd, "query")) + cur->delete++; + } + else if (!str_cmp(&cmd, "query")) { errstr = call_query_ng(dict, c->callmaster, resp); + cur->query++; + } #if GLIB_CHECK_VERSION(2,16,0) - else if (!str_cmp(&cmd, "list")) + else if (!str_cmp(&cmd, "list")) { errstr = call_list_ng(dict, c->callmaster, resp); + cur->list++; + } #endif else errstr = "Unrecognized command"; @@ -134,6 +186,7 @@ err_send: ilog(LOG_WARNING, "Protocol error in packet from %s: %s ["STR_FORMAT"]", addr, errstr, STR_FMT(&data)); bencode_dictionary_add_string(resp, "result", "error"); bencode_dictionary_add_string(resp, "error-reason", errstr); + cur->errors++; goto send_resp; send_resp: diff --git a/daemon/control_ng.h b/daemon/control_ng.h index e332f64b2..9851ac48a 100644 --- a/daemon/control_ng.h +++ b/daemon/control_ng.h @@ -9,6 +9,18 @@ struct poller; struct callmaster; +struct control_ng_stats { + struct sockaddr_in6 proxy; + u_int32_t ping; + u_int32_t offer; + u_int32_t answer; + u_int32_t delete; + u_int32_t query; + u_int32_t list; + u_int32_t errors; + struct control_ng_stats* next; +}; + struct control_ng { struct obj obj; struct callmaster *callmaster; diff --git a/daemon/main.c b/daemon/main.c index 429fb8430..560615ee2 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -624,6 +624,8 @@ no_kernel: if (redis_restore(ctx->m, mc.redis)) die("Refusing to continue without working Redis database"); + + ZERO(ctx->m->control_ng_stats); } static void timer_loop(void *d) {