From bb40243c71b99c8bbb08deb95c68b7af9b7bb0d4 Mon Sep 17 00:00:00 2001 From: fendo Date: Fri, 2 Aug 2013 11:36:56 +0200 Subject: [PATCH] improved load balancing algorithm. --- debian/changelog | 6 ++++++ grpsess.c | 34 +++++++++++++++++++++++++++++++++- l2tpns.c | 5 +++-- l2tpns.h | 2 +- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 4a37290..07531e8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +l2tpns (2.2.1-2sames3.11) unstable; urgency=low + + * improved load balancing algorithm. + + -- Fernando Alves Fri, 02 Aug 2013 11:32:49 +0200 + l2tpns (2.2.1-2sames3.10) unstable; urgency=low * Fix: authentication success was sent 2 times. diff --git a/grpsess.c b/grpsess.c index e710709..f38ab1a 100644 --- a/grpsess.c +++ b/grpsess.c @@ -42,6 +42,14 @@ static groupidt grp_lookup_ipmap(in_addr_t ip) return h[*a].grp; } +typedef struct +{ + sessionidt sid_loaddist[0x10000]; +} +local_group; + +local_group *grp_local = NULL; // Array of local_group structures. + // // Take an IP address in HOST byte order and // add it to the grouid by IP cache. @@ -447,6 +455,14 @@ void grp_initdata() { grpsession[i].state = GROUPEUNDEF; } + + if (!(grp_local = shared_malloc(sizeof(local_group) * MAXGROUPE))) + { + LOG(0, 0, 0, "Error doing malloc for grp_local: %s\n", strerror(errno)); + exit(1); + } + memset(grp_local, 0, sizeof(grp_local[0]) * MAXGROUPE); + } // Update time_changed of the group @@ -498,7 +514,7 @@ static void grp_uncache_ipsession(groupidt g, sessionidt s) } // return the next session can be used on the group -sessionidt grp_getnextsession(groupidt g, in_addr_t ip) +sessionidt grp_getnextsession(groupidt g, in_addr_t ip, in_addr_t ip_src) { sessionidt s = 0, s2 = 0, s3 = 0; int i; @@ -551,15 +567,30 @@ sessionidt grp_getnextsession(groupidt g, in_addr_t ip) if ((s = sessionbyip(ip))) { + uint8_t *as = (uint8_t *) &ip_src; + uint8_t *ad = (uint8_t *) &ip; + uint16_t ai = ad[3]; + ai <<= 8; + ai &= as[3]; + + s = grp_local[g].sid_loaddist[ai]; + if (!s) + { + s = grpsession[g].smin; + grp_local[g].sid_loaddist[ai] = s; + } + if (g != grp_groupbysession(s)) { // This session does not belong to this group LOG(2, s, session[s].tunnel, "Warning, the session does not belong to group %d\n", g); s = 0; + grp_local[g].sid_loaddist[ai] = 0; } else if (s == grpsession[g].smax) { s = grpsession[g].smin; + grp_local[g].sid_loaddist[ai] = s; grpsession[g].smax = 0; } else if ( (session[s].ppp.phase > Establish) && @@ -570,6 +601,7 @@ sessionidt grp_getnextsession(groupidt g, in_addr_t ip) else { s = 0; + grp_local[g].sid_loaddist[ai] = 0; } } diff --git a/l2tpns.c b/l2tpns.c index 9ac6bfd..9861e88 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -1413,7 +1413,7 @@ void processipout(uint8_t *buf, int len) groupidt g; sessiont *sp; tunnelidt t; - in_addr_t ip; + in_addr_t ip, ip_src; uint8_t *data = buf; // Keep a copy of the originals. int size = len; @@ -1446,10 +1446,11 @@ void processipout(uint8_t *buf, int len) return; } + ip_src = *(uint32_t *)(buf + 12); ip = *(uint32_t *)(buf + 16); if ((g = grp_groupbyip(ip))) { - s = grp_getnextsession(g, ip); + s = grp_getnextsession(g, ip, ip_src); if (!s) { // Is this a packet for a session that doesn't exist? diff --git a/l2tpns.h b/l2tpns.h index 1ce46a3..5dd854f 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1005,7 +1005,7 @@ void lac_send_ICRQ(tunnelidt t, sessionidt s); void lac_tunnelshutdown(tunnelidt t, char *reason, int result, int error, char *msg); // grpsess.c -sessionidt grp_getnextsession(groupidt g, in_addr_t ip); +sessionidt grp_getnextsession(groupidt g, in_addr_t ip, in_addr_t ip_src); void grp_initdata(void); void grp_processvendorspecific(sessionidt s, uint8_t *pvs); groupidt grp_groupbysession(sessionidt s); -- 2.20.1