From 7b3f57d5007dd2cf4127c2c3a9a7cd0f64d5d6e9 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 21 Dec 2008 19:39:39 +0100 Subject: src: add network statistics via `-s network' This patch adds networks statistics that you can check via `conntrackd -s network'. This information is useful for trouble-shooting. This patch replaces several log messages that can be triggered in runtime. The idea behind this patch is to avoid log message flooding under errors. Signed-off-by: Pablo Neira Ayuso --- src/main.c | 20 ++++++++++++-- src/network.c | 7 +++-- src/sync-ftfw.c | 4 +-- src/sync-mode.c | 83 ++++++++++++++++++++++++++++++++++++++++++--------------- 4 files changed, 86 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index f811acf..022915d 100644 --- a/src/main.c +++ b/src/main.c @@ -43,7 +43,7 @@ static const char usage_client_commands[] = " -i, display content of the internal cache\n" " -e, display the content of the external cache\n" " -k, kill conntrack daemon\n" - " -s, dump statistics\n" + " -s [|network], dump statistics\n" " -R, resync with kernel conntrack table\n" " -n, request resync with other node (only FT-FW and NOTRACK modes)\n" " -x, dump cache in XML format (requires -i or -e)" @@ -155,7 +155,23 @@ int main(int argc, char *argv[]) break; case 's': set_operation_mode(&type, REQUEST, argv); - action = STATS; + /* we've got a parameter */ + if (i+1 < argc && argv[i+1][0] != '-') { + if (strncmp(argv[i+1], "network", + strlen(argv[i+1])) == 0) { + action = STATS_NETWORK; + i++; + } else { + fprintf(stderr, "ERROR: unknown " + "parameter `%s' for " + "option `-s'\n", + argv[i+1]); + exit(EXIT_FAILURE); + } + } else { + /* default to general statistics */ + action = STATS; + } break; case 'S': fprintf(stderr, "WARNING: -S option is obsolete. " diff --git a/src/network.c b/src/network.c index 090dec8..598195f 100644 --- a/src/network.c +++ b/src/network.c @@ -147,14 +147,17 @@ int mcast_track_seq(uint32_t seq, uint32_t *exp_seq) /* out of sequence: some messages got lost */ if (after(seq, STATE_SYNC(last_seq_recv)+1)) { - STATE_SYNC(packets_lost) += seq-STATE_SYNC(last_seq_recv)+1; + STATE_SYNC(error).msg_rcv_lost += + seq - STATE_SYNC(last_seq_recv) + 1; ret = SEQ_AFTER; goto out; } /* out of sequence: replayed/delayed packet? */ - if (before(seq, STATE_SYNC(last_seq_recv)+1)) + if (before(seq, STATE_SYNC(last_seq_recv)+1)) { + STATE_SYNC(error).msg_rcv_before++; ret = SEQ_BEFORE; + } out: *exp_seq = STATE_SYNC(last_seq_recv)+1; diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 4758710..44e8f2f 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -441,8 +441,6 @@ static int ftfw_recv(const struct nethdr *net) case SEQ_BEFORE: /* we don't accept delayed packets */ - dlog(LOG_WARNING, "Received seq=%u before expected seq=%u", - net->seq, exp_seq); ret = MSG_DROP; break; @@ -521,7 +519,7 @@ static int tx_queue_xmit(void *data1, const void *data2) } else if (IS_ALIVE(net)) { nethdr_set_ctl(net); } else { - dlog(LOG_ERR, "sending unknown control message?"); + STATE_SYNC(error).msg_snd_malformed++; return 0; } HDR_HOST2NETWORK(net); diff --git a/src/sync-mode.c b/src/sync-mode.c index 6aad8f7..e7b9359 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -41,8 +41,8 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain) struct us_conntrack *u; if (net->version != CONNTRACKD_PROTOCOL_VERSION) { - STATE(malformed)++; - dlog(LOG_WARNING, "wrong protocol version `%u'", net->version); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_version++; return; } @@ -53,22 +53,23 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain) case MSG_CTL: return; case MSG_BAD: - STATE(malformed)++; + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_header++; return; default: break; } if (net->type > NET_T_STATE_MAX) { - STATE(malformed)++; - dlog(LOG_ERR, "bad state message type"); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_type++; return; } memset(ct, 0, sizeof(__ct)); if (parse_payload(ct, net, remain) == -1) { - STATE(malformed)++; - dlog(LOG_ERR, "parsing failed: malformed message"); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_payload++; return; } @@ -103,8 +104,8 @@ retry: debug_ct(ct, "can't destroy"); break; default: - STATE(malformed)++; - dlog(LOG_ERR, "mcast unknown query %d\n", net->type); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_type++; break; } } @@ -125,31 +126,31 @@ static void mcast_handler(void) struct nethdr *net = (struct nethdr *) ptr; if (remain < NETHDR_SIZ) { - STATE(malformed)++; - dlog(LOG_WARNING, "no room for header"); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_truncated++; break; } if (ntohs(net->len) > remain) { - STATE(malformed)++; - dlog(LOG_WARNING, "fragmented message"); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_size++; break; } if (IS_ACK(net) || IS_NACK(net) || IS_RESYNC(net)) { if (remain < NETHDR_ACK_SIZ) { - STATE(malformed)++; - dlog(LOG_WARNING, "no room for ctl message"); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_truncated++; } if (ntohs(net->len) < NETHDR_ACK_SIZ) { - STATE(malformed)++; - dlog(LOG_WARNING, "ctl header too small"); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_size++; } } else { if (ntohs(net->len) < NETHDR_SIZ) { - STATE(malformed)++; - dlog(LOG_WARNING, "header too small"); + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_size++; } } @@ -304,8 +305,43 @@ static void dump_stats_sync(int fd) size = sprintf(buf, "multicast sequence tracking:\n" "%20llu Pckts mfrm " "%20llu Pckts lost\n\n", - (unsigned long long)STATE(malformed), - (unsigned long long)STATE_SYNC(packets_lost)); + (unsigned long long)STATE_SYNC(error).msg_rcv_malformed, + (unsigned long long)STATE_SYNC(error).msg_rcv_lost); + + send(fd, buf, size, 0); +} + +static void dump_stats_sync_extended(int fd) +{ + char buf[512]; + int size; + + size = snprintf(buf, sizeof(buf), + "network statistics:\n" + "\trecv:\n" + "\t\tMalformed messages:\t%20llu\n" + "\t\tWrong protocol version:\t%20u\n" + "\t\tMalformed header:\t%20u\n" + "\t\tMalformed payload:\t%20u\n" + "\t\tBad message type:\t%20u\n" + "\t\tTruncated message:\t%20u\n" + "\t\tBad message size:\t%20u\n" + "\tsend:\n" + "\t\tMalformed messages:\t%20u\n\n" + "sequence tracking statistics:\n" + "\trecv:\n" + "\t\tPackets lost:\t\t%20llu\n" + "\t\tPackets before:\t\t%20llu\n\n", + (unsigned long long)STATE_SYNC(error).msg_rcv_malformed, + STATE_SYNC(error).msg_rcv_bad_version, + STATE_SYNC(error).msg_rcv_bad_header, + STATE_SYNC(error).msg_rcv_bad_payload, + STATE_SYNC(error).msg_rcv_bad_type, + STATE_SYNC(error).msg_rcv_truncated, + STATE_SYNC(error).msg_rcv_bad_size, + STATE_SYNC(error).msg_snd_malformed, + (unsigned long long)STATE_SYNC(error).msg_rcv_lost, + (unsigned long long)STATE_SYNC(error).msg_rcv_before); send(fd, buf, size, 0); } @@ -377,6 +413,11 @@ static int local_handler_sync(int fd, int type, void *data) STATE_SYNC(mcast_server)); dump_stats_sync(fd); break; + case STATS_NETWORK: + dump_stats_sync_extended(fd); + mcast_dump_stats(fd, STATE_SYNC(mcast_client), + STATE_SYNC(mcast_server)); + break; default: if (STATE_SYNC(sync)->local) ret = STATE_SYNC(sync)->local(fd, type, data); -- cgit v1.2.3