summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-12-21 19:39:39 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2008-12-21 19:39:39 +0100
commit7b3f57d5007dd2cf4127c2c3a9a7cd0f64d5d6e9 (patch)
treeaf5056d1a50fc62e640508c735114c3c4157ab0e /src
parentb666e6ebbd0c0ae7967ff8167790166858544297 (diff)
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 <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/main.c20
-rw-r--r--src/network.c7
-rw-r--r--src/sync-ftfw.c4
-rw-r--r--src/sync-mode.c83
4 files changed, 86 insertions, 28 deletions
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);