}
}
+// Uncache all IP of a session
+static void grp_uncache_ipsession(groupidt g, sessionidt s)
+{
+ int i;
+ uint8_t *a;
+ in_addr_t ip;
+ in_addr_t n_ip, j;
+ int prefixlen;
+ union iphash *h;
+
+ for (i = 0; i < grpsession[g].nbroutesgrp; i++)
+ {
+ if (grpsession[g].route[i].ip != 0)
+ {
+ prefixlen = grpsession[g].route[i].prefixlen;
+ ip = grpsession[g].route[i].ip & (0xffffffff << (32 - prefixlen)); // Force the ip to be the first one in the route.
+
+ for (j = ip; j < ip+(1<<(32-prefixlen)) ; ++j)
+ {
+ n_ip = htonl(j); // To network order
+ a = (uint8_t *) &n_ip;
+ h = ip_hash;
+
+ if (!(h = h[*a++].idx)) continue;
+ if (!(h = h[*a++].idx)) continue;
+ if (!(h = h[*a++].idx)) continue;
+
+ if (s == h[*a].sess)
+ {
+ h[*a].sess = 0;
+ //LOG(3, s, session[s].tunnel, "UnCaching ip address %s\n", fmtaddr(n_ip, 0));
+ }
+ }
+ }
+ }
+}
+
// return the next session can be used on the group
sessionidt grp_getnextsession(groupidt g, in_addr_t ip)
{
- sessionidt s = 0, s2 = 0, s3 = 0;
+ sessionidt s = 0, s2 = 0, s3 = 0, smax = 0;
int i;
- uint32_t ltime_changed = 0;
- uint32_t mintxrate = 0xFFFFFFFF;
+ uint32_t ltime_changed = 0, mintxrate = 0xFFFFFFFF, maxtxrate = 0;
+ uint32_t txrate;
if (g >= MAXGROUPE)
return 0;
- if ((s = sessionbyip(ip)))
+ if (grpsession[g].time_changed < config->grp_txrate_average_time)
{
- if ( (session[s].ppp.phase > Establish) &&
- (time_now - session[s].last_packet <= (config->echo_timeout + 2)) )
+ if ((s = sessionbyip(ip)))
{
- int recaltxrate = 0;
-
- for (i = 0; i < grpsession[g].nbsession; i++)
+ if ( (session[s].ppp.phase > Establish) &&
+ (time_now - session[s].last_packet <= (config->echo_timeout + 1)) )
+ {
+ return s;
+ }
+ s = 0;
+ }
+ }
+ else
+ {
+ // recalculation txrate
+ ltime_changed = grpsession[g].time_changed;
+ grpsession[g].time_changed = 0;
+ s = 0;
+ for (i = 0; i < grpsession[g].nbsession; i++)
+ {
+ if ((s2 = grpsession[g].sesslist[i].sid))
{
- if (s == grpsession[g].sesslist[i].sid)
+ s3 = s2;
+
+ grpsession[g].sesslist[i].tx_rate = session[s2].coutgrp_delta/ltime_changed;
+ session[s2].coutgrp_delta = 0;
+
+ //LOG(3, s2, session[s2].tunnel, "TX Rate: %d session weight: %d\n",
+ // grpsession[g].sesslist[i].tx_rate, grpsession[g].sesslist[i].weight);
+
+ txrate = grpsession[g].sesslist[i].tx_rate/grpsession[g].sesslist[i].weight;
+ if (txrate < mintxrate)
{
- if ((time_now - grpsession[g].sesslist[i].mark_time) > config->grp_txrate_average_time)
+ if ( session[s2].ppp.phase > Establish &&
+ (time_now - session[s2].last_packet <= (config->echo_timeout + 1)) )
{
- grpsession[g].sesslist[i].mark_time = time_now;
- recaltxrate = 1;
- break;
+ s = s2;
+ mintxrate = txrate;
+ }
+ }
+
+ if (txrate > maxtxrate)
+ {
+ if ( session[s2].ppp.phase > Establish &&
+ (time_now - session[s2].last_packet <= (config->echo_timeout + 1)) )
+ {
+ smax = s2;
+ maxtxrate = txrate;
}
}
}
+ }
- if (!recaltxrate)
- return s;
+ if (smax && (maxtxrate != mintxrate))
+ {
+ grp_uncache_ipsession(g, smax);
}
}
- //if (grpsession[g].time_changed > config->grp_txrate_average_time)
- if (grpsession[g].time_changed > 1)
+ if (!s)
{
- ltime_changed = grpsession[g].time_changed;
- grpsession[g].time_changed = 1;
- }
+ // random between 0 and nbsession-1
+ uint indexsess = (rand() % grpsession[g].nbsession);
- for (i = 0; i < grpsession[g].nbsession; i++)
- {
- if ((s2 = grpsession[g].sesslist[i].sid))
- {
- s3 = s2;
- if (ltime_changed)
- {
- grpsession[g].sesslist[i].tx_rate = session[s2].coutgrp_delta/ltime_changed;
- session[s2].coutgrp_delta = grpsession[g].sesslist[i].tx_rate;
- //LOG(3, s2, session[s2].tunnel, "TX Rate: %d session weight: %d\n", grpsession[g].sesslist[i].tx_rate, grpsession[g].sesslist[i].weight);
- }
+ if (indexsess >= grpsession[g].nbsession)
+ indexsess = 0; //Sanity checks.
- if ( session[s2].ppp.phase > Establish &&
- (time_now - session[s2].last_packet <= (config->echo_timeout + 2)) )
+ s2 = grpsession[g].sesslist[indexsess].sid;
+ if (s2 &&
+ (session[s2].ppp.phase > Establish) &&
+ (time_now - session[s2].last_packet <= (config->echo_timeout + 1)))
+ {
+ s = s2;
+ //LOG(3, s, session[s].tunnel, "New random session\n");
+ }
+ else
+ {
+ for (i = 0; i < grpsession[g].nbsession; i++)
{
- uint32_t txrate = grpsession[g].sesslist[i].tx_rate/grpsession[g].sesslist[i].weight;
- if (txrate < mintxrate)
+ if ((s2 = grpsession[g].sesslist[i].sid))
{
- s = s2;
- mintxrate = txrate;
+ s3 = s2;
+
+ if ( session[s2].ppp.phase > Establish &&
+ (time_now - session[s2].last_packet <= (config->echo_timeout + 1)) )
+ {
+ s = s2;
+ break;
+ }
}
}
}