X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/92db0e2617cec9b118708c722c1a9f273001f87d..ff1db279d1faf8ccbb146326d115ca5e39c3bde6:/l2tpns.c diff --git a/l2tpns.c b/l2tpns.c index 0721f5c..e3df04d 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -1463,35 +1463,63 @@ static void processipout(uint8_t *buf, int len) if(session[s].bundle != 0 && bundle[session[s].bundle].num_of_links > 1) { // Add on L2TP header + sessionidt members[MAXBUNDLESES]; bundleidt bid = session[s].bundle; bundlet *b = &bundle[bid]; + uint32_t num_of_links, nb_opened; + int i; - b->current_ses = (b->current_ses + 1) % b->num_of_links; - s = b->members[b->current_ses]; + num_of_links = b->num_of_links; + nb_opened = 0; + for (i = 0;i < num_of_links;i++) + { + s = b->members[i]; + if (session[s].ppp.lcp == Opened) + { + members[nb_opened] = s; + nb_opened++; + } + } + + if (nb_opened < 1) + { + LOG(2, s, t, "MPPP: PROCESSIPOUT ERROR, no session opened in bundle:%d\n", bid); + return; + } + + num_of_links = nb_opened; + 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: (1)Session number becomes: %d\n", s); - if(len > MINFRAGLEN) - { - // Partition the packet to "bundle[b].num_of_links" fragments - uint32_t num_of_links = b->num_of_links; - uint32_t fraglen = len / num_of_links; - fraglen = (fraglen > session[s].mru ? session[s].mru : fraglen); - uint32_t last_fraglen = fraglen + len % num_of_links; - last_fraglen = (last_fraglen > session[s].mru ? len % num_of_links : last_fraglen); + + if ((num_of_links > 1) && (len > MINFRAGLEN)) + { + 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... + // statistics update_session_out_stat(s, sp, fraglen); + remain -= fraglen; while (remain > last_fraglen) { b->current_ses = (b->current_ses + 1) % num_of_links; - s = b->members[b->current_ses]; + s = members[b->current_ses]; t = session[s].tunnel; sp = &session[s]; LOG(4, s, t, "MPPP: (2)Session number becomes: %d\n", s); @@ -1503,7 +1531,7 @@ static void processipout(uint8_t *buf, int len) } // send the last fragment b->current_ses = (b->current_ses + 1) % num_of_links; - s = b->members[b->current_ses]; + s = members[b->current_ses]; t = session[s].tunnel; sp = &session[s]; LOG(4, s, t, "MPPP: (2)Session number becomes: %d\n", s); @@ -1514,12 +1542,12 @@ static void processipout(uint8_t *buf, int len) if (remain != last_fraglen) LOG(3, s, t, "PROCESSIPOUT ERROR REMAIN != LAST_FRAGLEN, %d != %d\n", remain, last_fraglen); } - else { + else + { // Send it as one frame - uint8_t *p = makeppp(fragbuf, sizeof(fragbuf), buf, len, s, t, PPPIP, 0, bid, MP_BOTH_BITS); + 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... - LOG(4, s, t, "MPPP: packet sent as one frame\n"); update_session_out_stat(s, sp, len); } } @@ -1970,36 +1998,67 @@ void sessionshutdown(sessionidt s, char const *reason, int cdn_result, int cdn_e if (session[s].ppp.ipv6cp == Opened && session[s].ipv6prefixlen && del_routes) route6set(s, session[s].ipv6route, session[s].ipv6prefixlen, 0); - if (b) + if (b) { - // This session was part of a bundle - bundle[b].num_of_links--; - LOG(3, s, session[s].tunnel, "MPPP: Dropping member link: %d from bundle %d\n",s,b); - if(bundle[b].num_of_links == 0) + // This session was part of a bundle + bundle[b].num_of_links--; + LOG(3, s, session[s].tunnel, "MPPP: Dropping member link: %d from bundle %d\n",s,b); + if(bundle[b].num_of_links == 0) { - bundleclear(b); - LOG(3, s, session[s].tunnel, "MPPP: Kill bundle: %d (No remaing member links)\n",b); - } - else + bundleclear(b); + LOG(3, s, session[s].tunnel, "MPPP: Kill bundle: %d (No remaing member links)\n",b); + } + else { - // Adjust the members array to accomodate the new change - uint8_t mem_num = 0; - // It should be here num_of_links instead of num_of_links-1 (previous instruction "num_of_links--") - if(bundle[b].members[bundle[b].num_of_links] != s) + // Adjust the members array to accomodate the new change + uint8_t mem_num = 0; + // It should be here num_of_links instead of num_of_links-1 (previous instruction "num_of_links--") + if(bundle[b].members[bundle[b].num_of_links] != s) { - uint8_t ml; - for(ml = 0; mlcluster_iam_master) + if (!config->cluster_iam_master) { + // The fragments reconstruction is managed by the Master. master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; }