From 81ca38323a409a68ef80c46283c555d20d553e2d Mon Sep 17 00:00:00 2001 From: Fernando Alves Date: Wed, 15 Feb 2012 14:23:12 +0100 Subject: [PATCH] Fix: Sends small packets in the MPPPP frame (for reorder). Fix: Calculates jitter and jitter traces for analysis. --- debian/changelog | 7 ++++ l2tpns.c | 96 ++++++++++++++++++++++++++++-------------------- l2tpns.h | 6 +++ ppp.c | 41 ++++++++++++++------- 4 files changed, 96 insertions(+), 54 deletions(-) diff --git a/debian/changelog b/debian/changelog index 9f66fd1..b2a890f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +l2tpns (2.2.1-2fdn1.3) unstable; urgency=low + + * Fix: Sends small packets in the MPPPP frame (for reorder). + * Fix: Calculates jitter and jitter traces for analysis. + + -- Fernando Alves Wed, 15 Feb 2012 14:15:59 +0100 + l2tpns (2.2.1-2fdn1.2) unstable; urgency=low * Fix: MLPPP improvments. diff --git a/l2tpns.c b/l2tpns.c index e3df04d..d8bedee 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -102,6 +102,7 @@ uint32_t eth_tx = 0; static uint32_t ip_pool_size = 1; // Size of the pool of addresses used for dynamic address allocation. time_t time_now = 0; // Current time in seconds since epoch. +uint64_t time_now_ms = 0; // Current time in milliseconds since epoch. static char time_now_string[64] = {0}; // Current time as a string. static int time_changed = 0; // time_now changed char main_quit = 0; // True if we're in the process of exiting. @@ -240,6 +241,10 @@ static clockt now(double *f) time_now = t.tv_sec; time_changed++; } + + // Time in milliseconds + time_now_ms = (t.tv_sec * 1000) + (t.tv_usec/1000); + return (t.tv_sec - basetime) * 10 + t.tv_usec / 100000 + 1; } @@ -1492,59 +1497,70 @@ static void processipout(uint8_t *buf, int len) s = members[b->current_ses]; t = session[s].tunnel; sp = &session[s]; - - if ((num_of_links > 1) && (len > MINFRAGLEN)) + LOG(4, s, t, "MPPP: (1)Session number becomes: %d\n", s); + + if (num_of_links > 1) { - LOG(4, s, t, "MPPP: (1)Session number becomes: %d\n", s); - - //for rotate traffic among the member links - uint32_t divisor = num_of_links; - if (divisor > 2) - divisor = divisor/2 + (divisor & 1); - - // Partition the packet to "num_of_links" fragments - uint32_t fraglen = len / divisor; - uint32_t last_fraglen = fraglen + len % divisor; - uint32_t remain = len; - - // send the first packet - uint8_t *p = makeppp(fragbuf, sizeof(fragbuf), buf, fraglen, s, t, PPPIP, 0, bid, MP_BEGIN); - if (!p) return; - tunnelsend(fragbuf, fraglen + (p-fragbuf), t); // send it... + if(len > MINFRAGLEN) + { + //for rotate traffic among the member links + uint32_t divisor = num_of_links; + if (divisor > 2) + divisor = divisor/2 + (divisor & 1); + + // Partition the packet to "num_of_links" fragments + uint32_t fraglen = len / divisor; + uint32_t last_fraglen = fraglen + len % divisor; + uint32_t remain = len; + + // send the first packet + uint8_t *p = makeppp(fragbuf, sizeof(fragbuf), buf, fraglen, s, t, PPPIP, 0, bid, MP_BEGIN); + if (!p) return; + tunnelsend(fragbuf, fraglen + (p-fragbuf), t); // send it... - // statistics - update_session_out_stat(s, sp, fraglen); + // statistics + update_session_out_stat(s, sp, fraglen); - remain -= fraglen; - while (remain > last_fraglen) - { + remain -= fraglen; + while (remain > last_fraglen) + { + b->current_ses = (b->current_ses + 1) % num_of_links; + s = members[b->current_ses]; + t = session[s].tunnel; + sp = &session[s]; + LOG(4, s, t, "MPPP: (2)Session number becomes: %d\n", s); + p = makeppp(fragbuf, sizeof(fragbuf), buf+(len - remain), fraglen, s, t, PPPIP, 0, bid, 0); + if (!p) return; + tunnelsend(fragbuf, fraglen + (p-fragbuf), t); // send it... + update_session_out_stat(s, sp, fraglen); + remain -= fraglen; + } + // send the last fragment b->current_ses = (b->current_ses + 1) % num_of_links; s = members[b->current_ses]; t = session[s].tunnel; sp = &session[s]; LOG(4, s, t, "MPPP: (2)Session number becomes: %d\n", s); - p = makeppp(fragbuf, sizeof(fragbuf), buf+(len - remain), fraglen, s, t, PPPIP, 0, bid, 0); + p = makeppp(fragbuf, sizeof(fragbuf), buf+(len - remain), remain, s, t, PPPIP, 0, bid, MP_END); if (!p) return; - tunnelsend(fragbuf, fraglen + (p-fragbuf), t); // send it... - update_session_out_stat(s, sp, fraglen); - remain -= fraglen; + tunnelsend(fragbuf, remain + (p-fragbuf), t); // send it... + update_session_out_stat(s, sp, remain); + if (remain != last_fraglen) + LOG(3, s, t, "PROCESSIPOUT ERROR REMAIN != LAST_FRAGLEN, %d != %d\n", remain, last_fraglen); + } + else + { + // Send it as one frame + uint8_t *p = makeppp(fragbuf, sizeof(fragbuf), buf, len, s, t, PPPIP, 0, bid, MP_BOTH_BITS); + if (!p) return; + tunnelsend(fragbuf, len + (p-fragbuf), t); // send it... + LOG(4, s, t, "MPPP: packet sent as one frame\n"); + update_session_out_stat(s, sp, len); } - // send the last fragment - b->current_ses = (b->current_ses + 1) % num_of_links; - s = members[b->current_ses]; - t = session[s].tunnel; - sp = &session[s]; - LOG(4, s, t, "MPPP: (2)Session number becomes: %d\n", s); - p = makeppp(fragbuf, sizeof(fragbuf), buf+(len - remain), remain, s, t, PPPIP, 0, bid, MP_END); - if (!p) return; - tunnelsend(fragbuf, remain + (p-fragbuf), t); // send it... - update_session_out_stat(s, sp, remain); - if (remain != last_fraglen) - LOG(3, s, t, "PROCESSIPOUT ERROR REMAIN != LAST_FRAGLEN, %d != %d\n", remain, last_fraglen); } else { - // Send it as one frame + // Send it as one frame (NO MPPP Frame) uint8_t *p = makeppp(fragbuf, sizeof(fragbuf), buf, len, s, t, PPPIP, 0, 0, 0); if (!p) return; tunnelsend(fragbuf, len + (p-fragbuf), t); // send it... diff --git a/l2tpns.h b/l2tpns.h index 953c058..285e643 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -261,6 +261,7 @@ typedef struct { tunnelidt tid; // Fragment originating tunnel uint8_t flags; // MP frame flags uint32_t seq; // fragment seq num + uint32_t jitteravg; uint16_t length; // Fragment length uint8_t data[MAXFRAGLEN]; // Fragment data } fragmentt; @@ -408,6 +409,11 @@ typedef struct // Last Multilink frame sequence number received uint32_t last_seq; + + // jitter average of the session + uint32_t jitteravg; + // time in milliseconds of the last fragment. + uint64_t prev_time; } sessionlocalt; // session flags diff --git a/ppp.c b/ppp.c index 2343ad3..7251e94 100644 --- a/ppp.c +++ b/ppp.c @@ -21,6 +21,7 @@ extern int tunfd; extern char hostname[]; extern uint32_t eth_tx; extern time_t time_now; +extern uint64_t time_now_ms; extern configt *config; static int add_lcp_auth(uint8_t *b, int size, int authtype); @@ -1876,6 +1877,11 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) sess_local[s].last_seq = seq_num; + // calculate the jitter average + uint32_t ljitter = time_now_ms - sess_local[s].prev_time; + sess_local[s].jitteravg = (sess_local[s].jitteravg + ljitter)>>1; + sess_local[s].prev_time = time_now_ms; + uint32_t Mmin; if (seq_num < this_fragmentation->M) @@ -1902,7 +1908,7 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { // There have a long break of the link !!!!!!!! // M_offset is bigger that the fragmentation buffer size - LOG(3, s, t, "MPPP: M_offset out of range, min:%d, begin_seq:%d\n", Mmin, this_fragmentation->start_seq); + LOG(3, s, t, "MPPP: M_offset out of range, min:%d, begin_seq:%d, jitteravg:%d\n", Mmin, this_fragmentation->start_seq, sess_local[s].jitteravg); // Calculate the new start index, the previous frag are lost begin_index = (M_offset + this_fragmentation->start_index) & MAXFRAGNUM_MASK; @@ -1927,7 +1933,7 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) if (frag_offset >= MAXFRAGNUM) { // frag_offset is bigger that the fragmentation buffer size - LOG(3, s, t, "MPPP: Index out of range, seq:%d, begin_seq:%d, size frag:%d\n", seq_num, this_fragmentation->start_seq, l); + LOG(3, s, t, "MPPP: Index out of range, seq:%d, begin_seq:%d, jitteravg:%d\n", seq_num, this_fragmentation->start_seq, sess_local[s].jitteravg); return; } @@ -1939,13 +1945,15 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) if (this_frag->length > 0) // This fragment is lost, It was around the buffer and it was never completed the packet. - LOG(3, this_frag->sid, this_frag->tid, "MPPP: (INSERT) seq_num:%d frag_index:%d flags:%d is LOST\n", - this_frag->seq, frag_index, this_frag->flags); + LOG(3, this_frag->sid, this_frag->tid, "MPPP: (INSERT) seq_num:%d frag_index:%d flags:%d jitteravg:%d is LOST\n", + this_frag->seq, frag_index, this_frag->flags, this_frag->jitteravg); this_frag->length = l; this_frag->sid = s; + this_frag->tid = t; this_frag->flags = flags; this_frag->seq = seq_num; + this_frag->jitteravg = sess_local[s].jitteravg; memcpy(this_frag->data, p, l); LOG(4, s, t, "MPPP: seq_num:%d frag_index:%d INSERTED flags: %02X\n", seq_num, frag_index, flags); @@ -1967,8 +1975,9 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { // This fragment is lost, It was around the buffer and it was never completed the packet. LOG(3, this_fragmentation->fragment[frag_index_next].sid, this_fragmentation->fragment[frag_index_next].tid, - "MPPP: (NEXT) seq_num:%d frag_index:%d flags:%d is LOST\n", - this_fragmentation->fragment[frag_index_next].seq, frag_index_next, this_fragmentation->fragment[frag_index_next].flags); + "MPPP: (NEXT) seq_num:%d frag_index:%d flags:%d jitteravg:%d is LOST\n", + this_fragmentation->fragment[frag_index_next].seq, frag_index_next, + this_fragmentation->fragment[frag_index_next].flags, this_fragmentation->fragment[frag_index_next].jitteravg); // this frag is lost this_fragmentation->fragment[frag_index_next].length = 0; this_fragmentation->fragment[frag_index_next].flags = 0; @@ -1985,8 +1994,9 @@ void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { // This fragment is lost, It was around the buffer and it was never completed the packet. LOG(3, this_fragmentation->fragment[frag_index_prev].sid, this_fragmentation->fragment[frag_index_prev].tid, - "MPPP: (PREV) seq_num:%d frag_index:%d flags:%d is LOST\n", - this_fragmentation->fragment[frag_index_prev].seq, frag_index_prev, this_fragmentation->fragment[frag_index_prev].flags); + "MPPP: (PREV) seq_num:%d frag_index:%d flags:%d jitteravg:%d is LOST\n", + this_fragmentation->fragment[frag_index_prev].seq, frag_index_prev, + this_fragmentation->fragment[frag_index_prev].flags, this_fragmentation->fragment[frag_index_prev].jitteravg); this_fragmentation->fragment[frag_index_prev].length = 0; this_fragmentation->fragment[frag_index_prev].flags = 0; @@ -2030,8 +2040,9 @@ find_frame: { // This fragment is lost, it was never completed the packet. LOG(3, this_fragmentation->fragment[end_index].sid, this_fragmentation->fragment[end_index].tid, - "MPPP: (FIND END) seq_num:%d frag_index:%d flags:%d is LOST\n", - this_fragmentation->fragment[end_index].seq, begin_index, this_fragmentation->fragment[end_index].flags); + "MPPP: (FIND END) seq_num:%d frag_index:%d flags:%d jitteravg:%d is LOST\n", + this_fragmentation->fragment[end_index].seq, begin_index, + this_fragmentation->fragment[end_index].flags, this_fragmentation->fragment[end_index].jitteravg); // this frag is lost this_fragmentation->fragment[end_index].length = 0; this_fragmentation->fragment[end_index].flags = 0; @@ -2060,8 +2071,9 @@ find_frame: { // This fragment is lost, it was never completed the packet. LOG(3, this_fragmentation->fragment[begin_index].sid, this_fragmentation->fragment[begin_index].tid, - "MPPP: (FIND BEGIN) seq_num:%d frag_index:%d flags:%d is LOST\n", - this_fragmentation->fragment[begin_index].seq, begin_index, this_fragmentation->fragment[begin_index].flags); + "MPPP: (FIND BEGIN) seq_num:%d frag_index:%d flags:%d jitteravg:%d is LOST\n", + this_fragmentation->fragment[begin_index].seq, begin_index, + this_fragmentation->fragment[begin_index].flags, this_fragmentation->fragment[begin_index].jitteravg); // this frag is lost this_fragmentation->fragment[begin_index].length = 0; this_fragmentation->fragment[begin_index].flags = 0; @@ -2157,8 +2169,9 @@ assembling_frame: (this_fragmentation->fragment[begin_index].seq != this_fragmentation->start_seq)) { LOG(3, this_fragmentation->fragment[begin_index].sid, this_fragmentation->fragment[begin_index].tid, - "MPPP: (START) seq_num:%d frag_index:%d flags:%d is LOST\n", - this_fragmentation->fragment[begin_index].seq, begin_index, this_fragmentation->fragment[begin_index].flags); + "MPPP: (START) seq_num:%d frag_index:%d flags:%d jitteravg:%d is LOST\n", + this_fragmentation->fragment[begin_index].seq, begin_index, + this_fragmentation->fragment[begin_index].flags, this_fragmentation->fragment[begin_index].jitteravg); this_fragmentation->fragment[begin_index].length = 0; this_fragmentation->fragment[begin_index].flags = 0; } -- 2.20.1