Re: tcp_outgoing_address accounting.

From: Henrik Nordström <hno@dont-contact.us>
Date: Wed, 15 May 2002 15:12:29 +0200

You completely lost the ACL part here, didn't you (#if 0 segment)? The ACL
part is quite important to many people...

What would be great is if this could be done using an generic ACL mechanism
to select 1 of N in a group of things.. This way the same mechanism could
apply to

  tcp_outgoing_address
  tcp_outgoing_tos
  cache_peer_access

and any other ACL driven selection mechanims.

This would put the implementaion mainly in acl.c..

And then we have the question on persistence.. Most people would really like
each user to stick to one of the IP's to work around stupid websites using
source IP in authentication/session management..

And then there is the question on supporting secondary alternatives when the
first fails.. which makes me thing that perhaps this should be done in a two
stage process
a) Collect possible the alternatives by ACL driven processing
b) Load distribution, by "Select 1 of N", or by "Reorder alternatives
according to load".

Obviously some brain work needed here to find the correct approach.

Regards
Henrik

Zwane Mwaikambo wrote:
> 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;
Received on Wed May 15 2002 - 07:13:00 MDT

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