diff --git a/src/accept.c b/src/accept.c index 6fddd31..fb3856a 100644 --- a/src/accept.c +++ b/src/accept.c @@ -1340,6 +1340,7 @@ int accept_listener_status(cJSON *listeners, cJSON *totals) cJSON_AddNumberToObject(jl, "pkts_rx", l->portaccount->rxpackets); cJSON_AddNumberToObject(jl, "pkts_tx", l->portaccount->txpackets); cJSON_AddNumberToObject(jl, "pkts_ign", l->portaccount->rxdrops); + cJSON_AddNumberToObject(jl, "pkts_dup", l->portaccount->rxdupes); json_add_rxerrs(jl, "rx_errs", l->portaccount->rxerrs); cJSON_AddItemToArray(listeners, jl); diff --git a/src/incoming.c b/src/incoming.c index 182ac72..79ebc60 100644 --- a/src/incoming.c +++ b/src/incoming.c @@ -968,7 +968,7 @@ in_drop: /* Account the one incoming packet. * Incoming bytes were already accounted earlier. */ - clientaccount_add(c, l4proto, 0, 1, 0, 0, (e < 0) ? e : 0); + clientaccount_add(c, l4proto, 0, 1, 0, 0, (e < 0) ? e : 0, 0); return 0; } diff --git a/src/outgoing.c b/src/outgoing.c index 952b522..8806203 100644 --- a/src/outgoing.c +++ b/src/outgoing.c @@ -27,9 +27,9 @@ static inline void send_single(struct worker_t *self, struct client_t *c, struct pbuf_t *pb) { if (c->udp_port && c->udpclient) - clientaccount_add( c, IPPROTO_UDP, 0, 0, 0, 1, 0); + clientaccount_add( c, IPPROTO_UDP, 0, 0, 0, 1, 0, 0); else - clientaccount_add( c, IPPROTO_TCP, 0, 0, 0, 1, 0); + clientaccount_add( c, IPPROTO_TCP, 0, 0, 0, 1, 0, 0); client_write(self, c, pb->data, pb->packet_len); } @@ -59,6 +59,17 @@ static void process_outgoing_single(struct worker_t *self, struct pbuf_t *pb) send_single(self, c, pb); } + /* Check if I have the client which sent this dupe, and + * increment it's dupe counter + */ + /* OPTIMIZE: we walk through all clients for each dupe - how to find it quickly? */ + for (c = self->clients; (c); c = c->next) { + if (c == pb->origin) { + clientaccount_add(c, -1, 0, 0, 0, 0, 0, 1); + break; + } + } + return; } diff --git a/src/web/aprsc.css b/src/web/aprsc.css index 05e9c59..643efe1 100644 --- a/src/web/aprsc.css +++ b/src/web/aprsc.css @@ -68,7 +68,7 @@ div.msg_e, div.msg_i, div.msg_s { padding: 5px; margin: 5px 25px 5px 0px; border-radius: 5px; - width: 450px; + width: 480px; } /* tooltip */ diff --git a/src/web/aprsc.js b/src/web/aprsc.js index 8604959..d82ad5a 100644 --- a/src/web/aprsc.js +++ b/src/web/aprsc.js @@ -98,12 +98,12 @@ function client_bytes_rates(c, k) function client_pkts_rx(c, k) { - if (isUndefined(c['pkts_ign'])) - return c['pkts_rx']; + //if (isUndefined(c['pkts_ign'])) + // return c['pkts_rx']; - var s = c['pkts_rx'] + '/' + c['pkts_ign']; + var s = c['pkts_rx'] + '/' + c['pkts_dup'] + '/' + c['pkts_ign']; - if (c['pkts_ign'] > 0) + if (c['pkts_ign'] > 0 || c['pkts_dup'] > 0) return '' + s + ''; @@ -386,7 +386,7 @@ function rx_err_contents(fd) if (isUndefined(er)) return 'No rx errors for client on fd ' + fd; - var s = 'Received packets dropped: ' + fd_clients[fd]['pkts_ign'] + ' out of ' + fd_clients[fd]['pkts_rx'] + '
'; + var s = 'Receive drops: ' + fd_clients[fd]['pkts_dup'] + ' dupes, ' + fd_clients[fd]['pkts_ign'] + ' errors in ' + fd_clients[fd]['pkts_rx'] + '
'; for (var i = 0; i < rx_err_codes.length; i++) { if (er[i] < 1) diff --git a/src/worker.c b/src/worker.c index adf2f5e..65be5e1 100644 --- a/src/worker.c +++ b/src/worker.c @@ -587,7 +587,7 @@ char *hexsockaddr(const struct sockaddr *sa, const int addr_len) return hstrdup(eb); } -void clientaccount_add(struct client_t *c, int l4proto, int rxbytes, int rxpackets, int txbytes, int txpackets, int rxerr) +void clientaccount_add(struct client_t *c, int l4proto, int rxbytes, int rxpackets, int txbytes, int txpackets, int rxerr, int rxdupes) { struct portaccount_t *pa = NULL; int rxdrops = 0; @@ -604,6 +604,7 @@ void clientaccount_add(struct client_t *c, int l4proto, int rxbytes, int rxpacke c->localaccount.txbytes += txbytes; c->localaccount.rxpackets += rxpackets; c->localaccount.txpackets += txpackets; + c->localaccount.rxdupes += rxdupes; if (rxdrops) { c->localaccount.rxdrops += 1; c->localaccount.rxerrs[rxerr] += 1; @@ -621,6 +622,7 @@ void clientaccount_add(struct client_t *c, int l4proto, int rxbytes, int rxpacke __sync_fetch_and_add(&pa->txbytes, txbytes); __sync_fetch_and_add(&pa->rxpackets, rxpackets); __sync_fetch_and_add(&pa->txpackets, txpackets); + __sync_fetch_and_add(&pa->rxdupes, rxdupes); if (rxdrops) { __sync_fetch_and_add(&pa->rxdrops, 1); __sync_fetch_and_add(&pa->rxerrs[rxerr], 1); @@ -631,6 +633,7 @@ void clientaccount_add(struct client_t *c, int l4proto, int rxbytes, int rxpacke pa->txbytes += txbytes; pa->rxpackets += rxpackets; pa->txpackets += txpackets; + pa->rxdupes += rxdupes; if (rxdrops) { pa->rxdrops += 1; pa->rxerrs[rxerr] += 1; @@ -848,7 +851,7 @@ int client_write(struct worker_t *self, struct client_t *c, char *p, int len) // hlog( LOG_DEBUG, "UDP from %d to client port %d, sendto rc=%d", c->udpclient->portnum, c->udp_port, i ); if (i > 0) - clientaccount_add( c, IPPROTO_UDP, 0, 0, i, 0, 0); + clientaccount_add( c, IPPROTO_UDP, 0, 0, i, 0, 0, 0); return i; } @@ -863,7 +866,7 @@ int client_write(struct worker_t *self, struct client_t *c, char *p, int len) * will be incremented only when we actually transmit a packet * instead of a keepalive. */ - clientaccount_add( c, IPPROTO_TCP, 0, 0, len, 0, 0); + clientaccount_add( c, IPPROTO_TCP, 0, 0, len, 0, 0, 0); } if (c->obuf_end + len > c->obuf_size) { @@ -1088,7 +1091,7 @@ static int handle_corepeer_readable(struct worker_t *self, struct client_t *c) hlog(LOG_DEBUG, "worker thread passing UDP packet from %s to handler: %*s", addrs, r, c->ibuf); hfree(addrs); */ - clientaccount_add( rc, IPPROTO_UDP, r, 0, 0, 0, 0); /* Account byte count. incoming_handler() will account packets. */ + clientaccount_add( rc, IPPROTO_UDP, r, 0, 0, 0, 0, 0); /* Account byte count. incoming_handler() will account packets. */ rc->last_read = tick; /* Ignore CRs and LFs in UDP input packet - the current core peer system puts 1 APRS packet in each @@ -1150,7 +1153,7 @@ static int handle_client_readable(struct worker_t *self, struct client_t *c) return -1; } - clientaccount_add(c, IPPROTO_TCP, r, 0, 0, 0, 0); /* Number of packets is now unknown, + clientaccount_add(c, IPPROTO_TCP, r, 0, 0, 0, 0, 0); /* Number of packets is now unknown, byte count is collected. The incoming_handler() will account packets. */ @@ -1931,6 +1934,7 @@ static struct cJSON *worker_client_json(struct client_t *c, int liveup_info) cJSON_AddNumberToObject(jc, "pkts_rx", c->localaccount.rxpackets); cJSON_AddNumberToObject(jc, "pkts_tx", c->localaccount.txpackets); cJSON_AddNumberToObject(jc, "pkts_ign", c->localaccount.rxdrops); + cJSON_AddNumberToObject(jc, "pkts_dup", c->localaccount.rxdupes); cJSON_AddNumberToObject(jc, "heard_count", c->client_heard_count); cJSON_AddNumberToObject(jc, "courtesy_count", c->client_courtesy_count); diff --git a/src/worker.h b/src/worker.h index 6e0b585..65312fe 100644 --- a/src/worker.h +++ b/src/worker.h @@ -210,7 +210,7 @@ struct portaccount_t { /* Port accounter tracks port usage, and traffic long long rxbytes, txbytes; long long rxpackets, txpackets; - long long rxdrops; + long long rxdrops, rxdupes; long long rxerrs[INERR_BUCKETS]; /* record usage references */ @@ -469,7 +469,7 @@ extern void port_accounter_drop(struct portaccount_t *p); extern char *strsockaddr(const struct sockaddr *sa, const int addr_len); extern char *hexsockaddr(const struct sockaddr *sa, const int addr_len); -extern void clientaccount_add(struct client_t *c, int l4proto, int rxbytes, int rxpackets, int txbytes, int txpackets, int rxerr); +extern void clientaccount_add(struct client_t *c, int l4proto, int rxbytes, int rxpackets, int txbytes, int txpackets, int rxerr, int rxdupes); extern void json_add_rxerrs(cJSON *root, const char *key, long long vals[]); extern int worker_client_list(cJSON *workers, cJSON *clients, cJSON *uplinks, cJSON *peers, cJSON *totals, cJSON *memory);