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.caReceived 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