Date:2011-06-26 05:03:56 (8 years 2 months ago)
Author:Werner Almesberger
Commit:0194dc1a058671bda28d1be973d1d34153e358f1
Message:tools/dirtpan/: added statistics collection, SIGUSR1 to dump, SIGUSR2 to reset

- dirtpan.c (stats, send_frame, send_more, send_ack, rx_pck, tx_pck,
ack_timeout, reass_timeout): gather extensive statistics
- dirtpan.c (handle_usr1, main): if running in the foreground, dump
statistics on standard error on SIGUSR1
- dirtpan.c (handle_usr2, main): if running in the foreground, reset
statistics to zero on SIGUSR2
Files: tools/dirtpan/dirtpan.c (16 diffs)

Change Details

tools/dirtpan/dirtpan.c
1919#include <string.h>
2020#include <fcntl.h>
2121#include <signal.h>
22#include <errno.h>
2223#include <assert.h>
2324#include <sys/types.h>
2425#include <sys/time.h>
...... 
6465#define T_ACK_MS 50
6566
6667
68static struct {
69    unsigned tx_pck; /* packets enqueued */
70    unsigned lost; /* packets never acked */
71    unsigned rx_pck; /* packets successfully received */
72    unsigned tx_frm; /* frames sent */
73    unsigned rx_frm; /* frames received */
74    unsigned tx_frst; /* pt_first sent */
75    unsigned rx_frst; /* pt_first received */
76    unsigned tx_nxt; /* pt_next sent */
77    unsigned rx_nxt; /* pt_next received */
78    unsigned tx_ack; /* pt_ack sent */
79    unsigned rx_ack; /* pt_ack received */
80    unsigned invalid; /* invalid packet type */
81    unsigned not_rx; /* pt_next but not receiving */
82    unsigned rx_seq; /* wrong rx sequence */
83    unsigned not_tx; /* pt_ack but not sending */
84    unsigned ack_seq; /* wrong ack sequence */
85    unsigned garbled; /* IPv4 length problem */
86    unsigned no_ack; /* no ack response (giving up) */
87    unsigned retry; /* retransmit */
88    unsigned reass; /* reassembly timeout */
89} stats;
90
6791static int tun, net;
6892static uint8_t rx_packet[MAX_PACKET], tx_packet[MAX_PACKET+1];
6993static void *rx_pos, *tx_pos;
...... 
145169}
146170
147171
172/* ----- Statistics -------------------------------------------------------- */
173
174
175static void handle_usr1(int sig)
176{
177    fprintf(stderr, "\n"
178        "tx_pck\t%6u\n" "tx_lost\t%6u\n" "rx_pck\t%6u\n"
179        "tx_frm\t%6u\n" "rx_frm\t%6u\n" "tx_frst\t%6u\n"
180        "rx_frst\t%6u\n" "tx_nxt\t%6u\n" "rx_nxt\t%6u\n"
181        "tx_ack\t%6u\n" "rx_ack\t%6u\n" "invalid\t%6u\n"
182        "not_rx\t%6u\n" "rx_seq\t%6u\n" "not_tx\t%6u\n"
183        "ack_seq\t%6u\n" "garbled\t%6u\n" "no_ack\t%6u\n"
184        "retry\t%6u\n" "reass\t%6u\n",
185        stats.tx_pck, stats.lost, stats.rx_pck,
186        stats.tx_frm, stats.rx_frm, stats.tx_frst,
187        stats.rx_frst, stats.tx_nxt, stats.rx_nxt,
188        stats.tx_ack, stats.rx_ack, stats.invalid,
189        stats.not_rx, stats.rx_seq, stats.not_tx,
190        stats.ack_seq, stats.garbled, stats.no_ack,
191        stats.retry, stats.reass);
192}
193
194
195static void handle_usr2(int sig)
196{
197    memset(&stats, 0, sizeof(stats));
198}
199
200
148201/* ----- Timers ------------------------------------------------------------ */
149202
150203
...... 
245298{
246299    debug_dirt("->", buf, size);
247300    write_buf(net, buf, size);
301    stats.tx_frm++;
248302}
249303
250304
...... 
252306{
253307    uint8_t *p = tx_pos-1;
254308
255    *p = (tx_pos == tx_packet+1 ? pt_first : pt_next) | (tx_seq ? SEQ : 0);
309    if (tx_pos == tx_packet+1) {
310        *p = pt_first;
311        stats.tx_frst++;
312    } else {
313        *p = pt_next;
314        stats.tx_nxt++;
315    }
316    *p |= tx_seq ? SEQ : 0;
256317    send_frame(p, send_size()+1);
257318    start_timer(&t_ack, T_ACK_MS);
258319}
...... 
263324    uint8_t ack = pt_ack | (seq ? SEQ : 0);
264325
265326    send_frame(&ack, 1);
327    stats.tx_ack++;
266328}
267329
268330
...... 
276338
277339    debug_dirt("-<", buf, size);
278340
279    if (size < 1)
341    stats.rx_frm++;
342    if (size < 1) {
343        stats.invalid++;
280344        return;
345    }
281346
282347    ctrl = *p;
283348    type = ctrl & PT_MASK;
...... 
285350
286351    switch (type) {
287352    case pt_first:
353        stats.rx_frst++;
288354        send_ack(seq);
289355        if (rxing) {
290356            stop_timer(&t_reass);
...... 
292358        }
293359        break;
294360    case pt_next:
361        stats.rx_nxt++;
295362        send_ack(seq);
296        if (!rxing)
363        if (!rxing) {
364            stats.not_rx++;
297365            return;
298        if (seq == rx_seq)
366        }
367        if (seq == rx_seq) {
368            stats.rx_seq++;
299369            return; /* retransmission */
370        }
300371        break;
301372    case pt_ack:
302        if (!txing)
373        stats.rx_ack++;
374        if (!txing) {
375            stats.not_tx++;
303376            return;
304        if (seq != tx_seq)
377        }
378        if (seq != tx_seq) {
379            stats.ack_seq++;
305380            return;
381        }
306382        stop_timer(&t_ack);
307383        tx_pos += send_size();
308384        tx_left -= send_size();
309385        if (!tx_left) {
386            stats.lost--;
310387            txing = 0;
311388            return;
312389        }
...... 
315392        send_more();
316393        return;
317394    default:
318        abort();
395        stats.invalid++;
396        return;
319397    }
320398
321399    if (!rxing) {
322        if (size < 5)
400        if (size < 5) {
401            stats.garbled++;
323402            return;
403        }
324404        rx_left = p[3] << 8 | p[4];
325        if (rx_left > MAX_PACKET)
405        if (rx_left > MAX_PACKET) {
406            stats.garbled++;
326407            return;
408        }
327409        start_timer(&t_reass, T_REASS_MS);
328410        rxing = 1;
329411        rx_pos = rx_packet;
330412    }
331413
332414    if (rx_left < size-1) {
415        stats.garbled++;
333416        stop_timer(&t_reass);
334417        rxing = 0;
335418        return;
...... 
344427        write_buf(tun, rx_packet, rx_pos-(void *) rx_packet);
345428        stop_timer(&t_reass);
346429        rxing = 0;
430        stats.rx_pck++;
347431    }
348432}
349433
...... 
366450    tx_seq = !tx_seq;
367451    retries = 0;
368452    send_more();
453    stats.tx_pck++;
454    stats.lost++;
369455}
370456
371457
...... 
374460    debug_timeout("ACK-TO");
375461    assert(txing);
376462    stop_timer(&t_ack);
377    if (++retries == MAX_TRIES)
463    if (++retries == MAX_TRIES) {
378464        txing = 0;
379    else
465        stats.no_ack++;
466    } else {
380467        send_more();
468        stats.retry++;
469    }
381470}
382471
383472
...... 
386475    debug_timeout("REASS-TO");
387476    assert(rxing);
388477    stop_timer(&t_reass);
478    stats.reass++;
389479    rxing = 0;
390480}
391481
...... 
413503    res = select(net > tun ? net+1 : tun+1, &rset, NULL, NULL,
414504        timer_delta(to));
415505    if (res < 0) {
416        perror("select");
506        if (errno != EINTR)
507            perror("select");
417508        return;
418509    }
419510    if (!res) {
...... 
600691    net = open_net(pan, src, dst);
601692    tun = open_tun(cmd);
602693
603    if (foreground || !daemonize())
604        while (1)
605            event();
606694
607    return 0;
695    if (foreground) {
696        signal(SIGUSR1, handle_usr1);
697        signal(SIGUSR2, handle_usr2);
698    } else {
699        if (daemonize())
700            return 0;
701    }
702
703    while (1)
704        event();
608705}

Archive Download the corresponding diff file



interactive