re: tcp_outgoing_address accounting.

From: Zwane Mwaikambo <zwane@dont-contact.us>
Date: Wed, 15 May 2002 13:36:16 +0200 (SAST)

On Wed, 15 May 2002, Henrik Nordstrom wrote:

> The toucher question is how to make use of it in Squid's
> tcp_outgoing_address ACL driven selection..

IANASH (I Am Not A Squid Hacker)

Heres something i tried out, mind you, it completely breaks the semantics
of tcp_outgoing_address and can only be used in this manner;

tcp_outgoing_address 10.0.0.1
tcp_outgoing_address 10.0.0.2
etc...

I'd just like comments on how this could be better done, as this is kind
of a hack. I haven't really tested the "load" estimator and i'm sure i
missed some possible code paths...

diff -ur squid-2.5-orig/src/cf.data.pre squid-2.5.PRE6-RI1/src/cf.data.pre
--- squid-2.5-orig/src/cf.data.pre Sun Apr 14 00:32:07 2002
+++ squid-2.5.PRE6-RI1/src/cf.data.pre Wed May 15 14:08:08 2002
@@ -2171,20 +2171,32 @@
         tcp_outgoing_address ipaddr [[!]aclname] ...
 
         Example where requests from 10.0.0.0/24 will be forwareded
- with source address 10.1.0.1, 10.0.2.0/24 forwarded with
- source address 10.1.0.2 and the rest will be forwarded with
- source address 10.1.0.3.
+ with source address 10.0.0.1, 10.0.1.0/24 forwarded with
+ source address 10.0.1.2 and the rest will be forwarded with
+ source address 10.0.0.3.
 
         acl normal_service_net src 10.0.0.0/255.255.255.0
         acl good_service_net src 10.0.1.0/255.255.255.0
         tcp_outgoing_address 10.0.0.1 normal_service_net
- tcp_outgoing_address 10.0.0.2 good_service_net
+ tcp_outgoing_address 10.0.1.2 good_service_net
         tcp_outgoing_address 10.0.0.3
 
         Processing proceeds in the order specified, and stops at first fully
         matching line.
 DOC_END
 
+NAME: load_high_watermark
+TYPE: int
+DEFAULT: 75
+LOC: Config.load.high_watermark
+DOC_NONE
+
+NAME: load_low_watermark
+TYPE: int
+DEFAULT: 50
+LOC: Config.load.low_watermark
+DOC_NONE
+
 NAME: reply_body_max_size
 COMMENT: bytes allow|deny acl acl...
 TYPE: body_size_t
diff -ur squid-2.5-orig/src/forward.c squid-2.5.PRE6-RI1/src/forward.c
--- squid-2.5-orig/src/forward.c Mon Apr 1 14:51:27 2002
+++ squid-2.5.PRE6-RI1/src/forward.c Wed May 15 13:47:17 2002
@@ -77,9 +77,29 @@
     memFree(fs, MEM_FWD_SERVER);
 }
 
+static int inline
+updateAddrLoad(acl_address * acl_addr, int inc)
+{
+ return acl_addr->link_count += inc;
+}
+
+static acl_address *
+addrToAclAddress(acl_address * head, struct in_addr addr)
+{
+ acl_address *l;
+
+ for (l = head; l; l = l->next) {
+ if (l->addr.s_addr == addr.s_addr)
+ return l;
+ }
+
+ return NULL;
+}
+
 static void
 fwdStateFree(FwdState * fwdState)
 {
+ acl_address *tmp;
     StoreEntry *e = fwdState->entry;
     int sfd;
     peer *p;
@@ -106,6 +126,12 @@
         assert(!EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT));
     p = fwdStateServerPeer(fwdState);
     fwdServersFree(&fwdState->servers);
+ if (fwdState->request) {
+ tmp = addrToAclAddress(Config.accessList.outgoing_address, fwdState->request->my_addr);
+ if (tmp)
+ updateAddrLoad(tmp, -1);
+ }
+
     requestUnlink(fwdState->request);
     fwdState->request = NULL;
     if (fwdState->err)
@@ -122,6 +148,7 @@
         if (p)
             p->stats.conn_open--;
     }
+
     cbdataFree(fwdState);
 }
 
@@ -266,7 +293,7 @@
     comm_close(fd);
 }
 
-static struct in_addr
+struct in_addr
 aclMapAddr(acl_address * head, aclCheck_t * ch)
 {
     acl_address *l;
@@ -290,10 +317,74 @@
     return 0;
 }
 
+static struct in_addr
+roundRobinAddr(acl_address * head)
+{
+ static acl_address *l = NULL;
+ struct in_addr ret;
+
+ if (!l)
+ l = head;
+
+ ret = l->addr;
+ updateAddrLoad(l, 1);
+ l = l->next;
+ return ret;
+}
+
+static struct in_addr
+loadBalanceAddr(acl_address * head)
+{
+ acl_address *l, *best;
+
+ for (l = best = head; l; l = l->next) {
+ if (l->link_count == 0) {
+ best = l;
+ break;
+ }
+
+ if (l->link_count < best->link_count)
+ best = l;
+ }
+
+ updateAddrLoad(best, 1);
+ return best->addr;
+}
+
+struct in_addr (*adaptivePolicy)(acl_address * head) = roundRobinAddr;
+
+static struct in_addr
+adaptiveLoadBalance(acl_address * head)
+{
+ int load = 0, low_load = 1;
+ acl_address *l;
+
+ for (l = head; l; l = l->next) {
+ load = l->link_count;
+ if (load > Config.load.high_watermark) {
+ adaptivePolicy = loadBalanceAddr;
+ low_load = 0;
+ break;
+ }
+
+ if (load > Config.load.low_watermark) {
+ low_load = 0;
+ break;
+ }
+ }
+
+ if (low_load)
+ adaptivePolicy = roundRobinAddr;
+
+ return adaptivePolicy(head);
+}
+
 struct in_addr
 getOutgoingAddr(request_t * request)
 {
     aclCheck_t ch;
+ struct in_addr addr;
+
     memset(&ch, '\0', sizeof(aclCheck_t));
     if (request) {
         ch.src_addr = request->client_addr;
@@ -301,7 +392,14 @@
         ch.my_port = request->my_port;
         ch.request = request;
     }
- return aclMapAddr(Config.accessList.outgoing_address, &ch);
+
+#if 0
+ addr = aclMapAddr(Config.accessList.outgoing_address, &ch);
+ if (addr.s_addr == INADDR_ANY)
+ return adaptiveLoadBalance(Config.accessList.outgoing_address);
+#endif
+ addr = adaptiveLoadBalance(Config.accessList.outgoing_address);
+ return addr;
 }
 
 unsigned long
diff -ur squid-2.5-orig/src/structs.h squid-2.5.PRE6-RI1/src/structs.h
--- squid-2.5-orig/src/structs.h Mon Apr 1 08:03:38 2002
+++ squid-2.5.PRE6-RI1/src/structs.h Wed May 15 12:20:19 2002
@@ -264,6 +264,7 @@
     acl_address *next;
     acl_list *acl_list;
     struct in_addr addr;
+ int link_count;
 };
 
 struct _acl_tos {
@@ -375,6 +376,10 @@
     } Swap;
     size_t memMaxSize;
     struct {
+ int low_watermark;
+ int high_watermark;
+ } load;
+ struct {
         char *relayHost;
         u_short relayPort;
         peer *peer;

-- 
http://function.linuxpower.ca
		
Received on Wed May 15 2002 - 23:02:39 MDT

This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:15:27 MST