Re: squid, outgoing port depending on matched acl

From: Roger Venning <r.venning@dont-contact.us>
Date: Sun, 01 Apr 2001 21:44:50 -0400

OK,

the rvenning_tosaddracl branch now has combined support for specifying
both outgoing
TOS marking & outgoing address selection (address on proxy cache
interface). A
brief example might be:

acl normal_service_net 10.0.0.0/255.255.255.0
acl good_service_net 10.0.1.0/255.255.255.0
acl bad_service maxconn 4 # we make them pay if they connect more than
four times simulatenously
acl_map2_tos normal_service_net 0x00
acl_map2_tos good_service_net 0x20
acl_map2_outgoing normal_service_net 10.0.0.1
acl_map2_outgoing good_service_net 10.0.0.2
acl_map2_outgoing bad_service 10.0.0.3 # and shape traffic to 10.0.0.3
_right_ down....

Of course your imagination and requirements will mean that you pick
better acl
examples from all those that squid supports such as via requested
mime-type,
destination address, specific username or username regex, browser type
(! imaginge !),
time of day... etc. - the people responsible for all this support
deserve a big pat on the back

Of course 10.0.0.1,2&3 must all be valid IP addresses on your squid
proxy cache. With
recent Linux, and Alexey Kuznetsov's (now standard) ip-route2 package,
this is as simple
as assigning other IP addresses from eth0 (say) subnet.

eg. eth0 has address 10.0.0.1, subnet mask 255.255.255.0. As long as
10.0.0.3 is not used
by any other machine on the subnet, we can just do
ip addr add 10.0.0.3 dev eth0

So give the attached patch a test Marek & Joao (should apply to
2.4.0-stable, but mightn't,
will definately work against a HEAD snapshot) or grab via CVS from
squid.sourceforge.net
(follow the CVS link, use anonymous CVS). Send me feedback!

The CVS tag is rvenning_tosaddracl.

Marek: the patch I sent before was flawed. Use this new one.

Roger.

Henrik Nordstrom wrote:

> The squid-dev mailinglist is the proper location for questions like
> this. You are most welcome to try to address issues like this.
>
> To become a Squid developer please get subscribed to squid-dev (see
> <http://www.squid-cache.org/mailing-lists.html>) and create yourself a
> SourceForge account.
>
> I think the TOS support Roger Venning is working on might be something
> for you, but there might be problems with TOS not being reflected in
> return traffic.. The reason to why it is not currently on SourceForge is
> a small mishap in where it got committed and will get corrected in a few
> days. Until then the patch is in the commit and squid-dev archives.
>
> The ability to select which source ip to use is quite commonly
> requested, and an implementation of this would be very nice.
>
> /Henrik
>
>
> Marek Veber wrote:
>
>> Hi Hendric,
>> I contact you as the first person on Squid's CONTRIBUTORS list,
>> please sorry me if you are not the correct one and please help me to
>> find the correct person to solve my problem.
>>
>> Thanks for your time, asistence and reply.
>> -----------------------------------------------
>>
>> We need to separate the linux's network device band (using QoS) to
>> some part's for given customers, which use
>> 1) common Squid-proxy
>> 2) other diferent separated packet comunication
>>
>> We find that there is a need to separate on IP packets level, which
>> outgoing/incoming data to/from ISP from the Squid-proxy are used by
>> the given customer and sum it together with the rest
>> of the customer's packet traffic.
>>
>> Our idea is: equip Squid with abilty to
>> assign outgoing port/ip_addr for the request(from the given customer) depending
>> on matched acl.
>>
>> As I thing, I'm a person, which is able to do it, but only with coordination
>> with other Squid's developers.
>> Please let me know, about the common idea and latest work to do such a thing
>> in "Squid team".
>>
>> At the www page:
>> http://www.geocrawler.com/lists/3/SourceForge/1783/0/
>> in Roger Venning's comments to his commit from 03/30/2001 08:33:06
>> I have find the some idea to do the same thing, bud CVS
>> CVSROOT=':pserver:anoncvs@cvs.squid-cache.org:/squid' hasn't this update
>> build in.
>> --
>> -----------------------------------------------
>> | Marek Veber email: mara@solnet.cz |
>> | Tvorihraz 67 http://www.solnet.cz |
>> | 671 34, (CZ) private:+42 / 0602/767386 |
>> | mobil:+42 / 0603/378281 |
>> | school:+42 / 05/41512377 |
>> | ICQ UIN: 85222257 |
>> -----------------------------------------------
>

-- 
-------------------------------------------------------------
Roger Venning	\ Do not go gentle into that good night
Melbourne        \ Rage, rage against the dying of the light.
Australia <r.venning@bipond.com>                 Dylan Thomas

Index: squid/src/acl.c
diff -u squid/src/acl.c:1.28 squid/src/acl.c:1.28.2.1
--- squid/src/acl.c:1.28 Fri Mar 30 14:29:38 2001
+++ squid/src/acl.c Sun Apr 1 03:34:09 2001
@@ -994,11 +994,24 @@
         debug(28, 3) ("aclParseAccessLine: looking for ACL name '%s'\n", t);
         a = aclFindByName(t);
         if (a == NULL) {
- debug(28, 0) ("%s line %d: %s\n",
- cfg_filename, config_lineno, config_input_line);
- debug(28, 0) ("aclParseAccessLine: ACL name '%s' not found.\n", t);
- memFree(L, MEM_ACL_LIST);
- continue;
+ int trailer;
+ /* maybe it is a permissible trailing integer - in which case there
+ is nothing left on the line */
+ if (!strtok(NULL, w_space) && /* OK to discard, trust me */
+ (sscanf(t, "0x%x", &trailer) || sscanf(t, "%d", &trailer) ||
+ safe_inet_addr(t, (struct in_addr *)&trailer))) {
+ /* we really do have a int on the end of the line, in 0x1234
+ or plain 1234 format */
+ A->trailer = trailer;
+ memFree(L, MEM_ACL_LIST); /* mistakenly allocated */
+ continue;
+ } else {
+ debug(28, 0) ("%s line %d: %s\n",
+ cfg_filename, config_lineno, config_input_line);
+ debug(28, 0) ("aclParseAccessLine: ACL name '%s' not found.\n", t);
+ memFree(L, MEM_ACL_LIST);
+ continue;
+ }
         }
         L->acl = a;
         *Tail = L;
@@ -1717,8 +1730,14 @@
     debug(28, 5) ("aclCheckFast: list: %p\n", A);
     while (A) {
         allow = A->allow;
- if (aclMatchAclList(A->acl_list, checklist))
- return allow == ACCESS_ALLOWED;
+ if (aclMatchAclList(A->acl_list, checklist)) {
+ if (allow == ACCESS_ALLOWED && A->trailer) {
+ return A->trailer; /* trailing int non-zero, return
+ still holds the same meaning */
+ } else {
+ return allow == ACCESS_ALLOWED;
+ }
+ }
         A = A->next;
     }
     debug(28, 5) ("aclCheckFast: no matches, returning: %d\n", allow == ACCESS_DENIED);
Index: squid/src/cf.data.pre
diff -u squid/src/cf.data.pre:1.24 squid/src/cf.data.pre:1.24.2.2
--- squid/src/cf.data.pre:1.24 Fri Mar 30 14:29:38 2001
+++ squid/src/cf.data.pre Sun Apr 1 04:11:38 2001
@@ -2072,6 +2072,48 @@
         the configure script.
 DOC_END
 
+NAME: acl_map2_tos
+TYPE: acl_access
+DEFAULT: none
+DEFAULT_IF_NONE: deny all
+LOC: Config.accessList.tosacl
+DOC_START
+ A list of ACL elements followed by a TOS byte that applies if
+ matched. For example you might like to provide different TOS
+ marking, dependant on the client network:
+
+ 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
+ acl_map2_tos normal_service_net 0x00
+ acl_map2_tos good_service_net 0x20
+
+ TOS/DSCP values really only have local significance - so you should
+ know what you're specifying. For more, see RFC 2474
+
+ The TOS/DSCP byte must be exactly that - a byte, value 0 - 255
+ Processing proceeds in the order specifies, and stops at first match.
+DOC_END
+
+NAME: acl_map2_outgoing
+TYPE: acl_access
+DEFAULT: none
+DEFAULT_IF_NONE: deny all
+LOC: Config.accessList.outgoingacl
+DOC_START
+ A list of ACL elements followed by an ip address to use as the
+ outgoing TCP address for sourcing data for this connection. Much
+ like acl_map2_tos above, but the data will _always_ come back to
+ the outgoing address, unlike TOS markings, which may dissappear
+ on the reverse path. The idea is you have another bandwidth
+ controlling box to limit bandwidth by IP address within your
+ network. Note: you're machine must have the addresses you choose
+ assigned. An example:
+
+ 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
+ acl_map2_outgoing normal_service_net 10.0.0.1
+ acl_map2_outgoing good_service_net 10.0.0.2
+DOC_END
 
 COMMENT_START
  ADMINISTRATIVE PARAMETERS
Index: squid/src/comm.c
diff -u squid/src/comm.c:1.11 squid/src/comm.c:1.11.2.1
--- squid/src/comm.c:1.11 Fri Mar 30 14:29:38 2001
+++ squid/src/comm.c Sun Apr 1 03:34:10 2001
@@ -145,16 +145,31 @@
 }
 
 /* Create a socket. Default is blocking, stream (TCP) socket. IO_TYPE
- * is OR of flags specified in comm.h. */
-int
+ * is OR of flags specified in comm.h. Defaults TOS */
+inline int
 comm_open(int sock_type,
     int proto,
     struct in_addr addr,
     u_short port,
     int flags,
+ const char *note) {
+ return comm_openex(sock_type, proto, addr, port, flags, 0, note);
+}
+
+
+/* Create a socket. Default is blocking, stream (TCP) socket. IO_TYPE
+ * is OR of flags specified in defines.h:COMM_* */
+int
+comm_openex(int sock_type,
+ int proto,
+ struct in_addr addr,
+ u_short port,
+ int flags,
+ unsigned char TOS,
     const char *note)
 {
     int new_socket;
+ int tos;
     fde *F = NULL;
 
     /* Create socket for accepting new connections. */
@@ -174,6 +189,15 @@
         }
         return -1;
     }
+
+ /* set TOS if needed */
+ if (TOS) {
+ tos = TOS;
+ if (setsockopt(new_socket, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(int)) < 0)
+ debug(50, 1) ("comm_open: setsockopt(IP_TOS) on FD %d: %s\n",
+ new_socket, xstrerror());
+ }
+
     /* update fdstat */
     debug(5, 5) ("comm_open: FD %d is a new socket\n", new_socket);
     fd_open(new_socket, FD_SOCKET, note);
Index: squid/src/forward.c
diff -u squid/src/forward.c:1.12 squid/src/forward.c:1.12.2.2
--- squid/src/forward.c:1.12 Fri Mar 30 14:29:38 2001
+++ squid/src/forward.c Sun Apr 1 04:11:38 2001
@@ -277,6 +277,9 @@
     const char *host;
     unsigned short port;
     time_t ctimeout;
+ aclCheck_t ch;
+ struct in_addr outgoing;
+ unsigned short tos;
     assert(fs);
     assert(fwdState->server_fd == -1);
     debug(17, 3) ("fwdConnectStart: %s\n", url);
@@ -306,11 +309,26 @@
 #if URL_CHECKSUM_DEBUG
     assert(fwdState->entry->mem_obj->chksum == url_checksum(url));
 #endif
- fd = comm_open(SOCK_STREAM,
+ /* find the desired outgoing address */
+ memset(&ch, '\0', sizeof(aclCheck_t));
+ ch.src_addr = fwdState->request->client_addr; /* is it right to */
+ ch.my_addr = fwdState->request->my_addr; /* pull out the */
+ ch.my_port = fwdState->request->my_port; /* data like this? */
+ ch.request = fwdState->request;
+ outgoing.s_addr = aclCheckFast(Config.accessList.outgoingacl, &ch);
+ if(!outgoing.s_addr)
+ outgoing = Config.Addrs.tcp_outgoing;
+
+ /* and the desired tos (for the request that sparked this connection) */
+ tos = (unsigned short)aclCheckFast(Config.accessList.tosacl, &ch);
+
+ debug(17,3) ("fwdConnectStart: got addr %s, tos %d\n", outgoing, tos);
+ fd = comm_openex(SOCK_STREAM,
         0,
- Config.Addrs.tcp_outgoing,
+ outgoing,
         0,
         COMM_NONBLOCKING,
+ tos,
         url);
     if (fd < 0) {
         debug(50, 4) ("fwdConnectStart: %s\n", xstrerror());
Index: squid/src/protos.h
diff -u squid/src/protos.h:1.23 squid/src/protos.h:1.23.2.1
--- squid/src/protos.h:1.23 Fri Mar 30 14:29:38 2001
+++ squid/src/protos.h Sun Apr 1 03:34:10 2001
@@ -149,6 +149,7 @@
 extern void comm_init(void);
 extern int comm_listen(int sock);
 extern int comm_open(int, int, struct in_addr, u_short port, int, const char *note);
+extern int comm_openex(int, int, struct in_addr, u_short, int, unsigned char TOS, const char *);
 extern u_short comm_local_port(int fd);
 
 extern void commSetSelect(int, unsigned int, PF *, void *, time_t);
Index: squid/src/structs.h
diff -u squid/src/structs.h:1.28 squid/src/structs.h:1.28.2.2
--- squid/src/structs.h:1.28 Fri Mar 30 14:29:38 2001
+++ squid/src/structs.h Sun Apr 1 04:11:38 2001
@@ -235,6 +235,7 @@
 
 struct _acl_access {
     int allow;
+ int trailer;
     acl_list *acl_list;
     char *cfgline;
     acl_access *next;
@@ -556,6 +557,8 @@
 #endif
         acl_access *redirector;
         acl_access *reply;
+ acl_access *tosacl;
+ acl_access *outgoingacl;
     } accessList;
     acl_deny_info_list *denyInfoList;
     struct _authConfig {
Received on Sun Apr 01 2001 - 05:37:00 MDT

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