Re: feature question

From: Roger Venning <r.venning@dont-contact.us>
Date: Sat, 31 Mar 2001 03:20:42 -0500

Joao,

I've put together something that implements (2). The problem with this
is that although
squid can set the TOS/DSCP byte on outbound packets, I think that you
really want to
control in bound bandwidth according to class of service afforded to the
internal destination,
yes? Because remote systems are unlikely to mirror the TOS bits as they
respond,
this is probably not much help to you.

As things stand, with the addition I have made to the acl
infrastructure, it will be a small
step to add the mechanism in (1).

You can drag it out of sourceforge (squid.sourceforge.net) cvs, or use
the attached patch.

Index: acl.c
===================================================================
RCS file: /cvsroot/squid/squid/src/acl.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- acl.c 2001/03/21 23:43:32 1.26
+++ acl.c 2001/03/30 16:33:02 1.27
@@ -994,11 +994,23 @@
         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))) {
+ /* 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,14 +1729,22 @@
     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);
     return allow == ACCESS_DENIED;
 }
 
 static void
 aclCheck(aclCheck_t * checklist)
 {

Index: cf.data.pre
===================================================================
RCS file: /cvsroot/squid/squid/src/cf.data.pre,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- cf.data.pre 2001/02/21 00:10:13 1.22
+++ cf.data.pre 2001/03/30 16:33:02 1.23
@@ -2072,6 +2072,27 @@
         the configure script.
 DOC_END
 
+NAME: acl_map2_tos
+TYPE: acl_access
+DEFAULT: none
+DEFAULT_IF_NONE: deny all 0x00
+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
 
 COMMENT_START
  ADMINISTRATIVE PARAMETERS

Index: comm.c
===================================================================
RCS file: /cvsroot/squid/squid/src/comm.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- comm.c 2001/03/03 10:44:32 1.9
+++ comm.c 2001/03/30 16:33:03 1.10
@@ -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: forward.c
===================================================================
RCS file: /cvsroot/squid/squid/src/forward.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- forward.c 2001/03/03 10:44:32 1.10
+++ forward.c 2001/03/30 16:33:03 1.11
@@ -277,6 +277,8 @@
     const char *host;
     unsigned short port;
     time_t ctimeout;
+ aclCheck_t ch;
+ unsigned short tos;
     assert(fs);
     assert(fwdState->server_fd == -1);
     debug(17, 3) ("fwdConnectStart: %s\n", url);
@@ -306,11 +308,22 @@
 #if URL_CHECKSUM_DEBUG
     assert(fwdState->entry->mem_obj->chksum == url_checksum(url));
 #endif
- fd = comm_open(SOCK_STREAM,
+ /* find the desired tos (for the request that sparked this connection */
+ memset(&ch, '\0', sizeof(aclCheck_t));
+ ch.src_addr = fwdState->request->client_addr; /* is it right to */
+ debug(17,1) ("fwdConnectStart: src addr %s\n", inet_ntoa(ch.src_addr));
+ ch.my_addr = fwdState->request->my_addr; /* pull out the */
+ debug(17,1) ("fwdConnectStart: my addr %s\n", inet_ntoa(ch.my_addr));
+ ch.my_port = fwdState->request->my_port; /* data like this? */
+ ch.request = fwdState->request;
+ tos = (unsigned short)aclCheckFast(Config.accessList.tosacl, &ch);
+ debug(17,1) ("fwdConnectStart: got tos %d\n", tos);
+ fd = comm_openex(SOCK_STREAM,
         0,
         Config.Addrs.tcp_outgoing,
         0,
         COMM_NONBLOCKING,
+ tos,
         url);
     if (fd < 0) {
         debug(50, 4) ("fwdConnectStart: %s\n", xstrerror());

Index: protos.h
===================================================================
RCS file: /cvsroot/squid/squid/src/protos.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- protos.h 2001/03/20 01:16:29 1.21
+++ protos.h 2001/03/30 16:33:03 1.22
@@ -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: structs.h
===================================================================
RCS file: /cvsroot/squid/squid/src/structs.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- structs.h 2001/02/21 00:10:13 1.26
+++ structs.h 2001/03/30 16:33:03 1.27
@@ -235,6 +235,7 @@
 
 struct _acl_access {
     int allow;
+ int trailer;
     acl_list *acl_list;
     char *cfgline;
     acl_access *next;
@@ -556,6 +557,7 @@
 #endif
         acl_access *redirector;
         acl_access *reply;
+ acl_access *tosacl;
     } accessList;
     acl_deny_info_list *denyInfoList;
     struct _authConfig {

 

Joao Carvalho wrote:

> well here is what i need to do.
> i have a proxy running that is used by diferent subnetworks.
> each subnetwork can use it or exit directly to the net.
> if they exit directly they are controled by a packeteer.
> if they use the proxy they escape the control .
> Of course i could control rate limit at the proxy , but what i really want
> is one of the following features :
>
> 1 - the machine running the proxy has several ips on the same network
> i would like to control some acl to tell them if you belong to the following
> acl than use the following source ip to obtain the file requested
> that way i could include those ip in the packeteer and administer bandwidth
> in one single place.
>
> 2 - use the same method but instead of having ips using the TOS field.
>
> is there something like this in squid or are ther any plans to include one of
> these features in an future release ?
>
> thank you
>
> Joao Carvalho

-- 
-------------------------------------------------------------
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
Received on Fri Mar 30 2001 - 10:13:03 MST

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