]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Commit Roger Venning's TOS/source address ACL selection work.
authoradrian <>
Wed, 10 Oct 2001 21:17:37 +0000 (21:17 +0000)
committeradrian <>
Wed, 10 Oct 2001 21:17:37 +0000 (21:17 +0000)
This code allows the user to set ToS bits or the source address
of an ACL by defining an ACL and then using that ACL in
(mutiple instances of the) tcp_outgoing_address statement.

13 files changed:
ChangeLog
src/acl.cc
src/cache_cf.cc
src/cf.data.pre
src/comm.cc
src/forward.cc
src/ftp.cc
src/neighbors.cc
src/protos.h
src/ssl.cc
src/structs.h
src/tunnel.cc
src/typedefs.h

index 18061517e3c7e37bb8d99ec9d895df37172ecf83..e160fdd9b96a437547fa7b8c2f8611d3db222600 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -28,6 +28,11 @@ Changes to squid-2.5
          as the dist-all and distcheck targets for developers which respectively
          build a tar.gz and a tar.bz2 distribution, and check that what will be
          distributed builds.
+       - Added TOS and source address selection based on ACLs,
+         written by Roger Venning. This allows administrators to set
+         the TOS precedence bits and/or the source IP from a set of
+         available IPs based upon some ACLs, generally to map different
+         users to different outgoing links and traffic profiles.
        
 Changes to Squid-2.4.DEVEL4 ():
 
index 5d5e7a479c672356d9af8e3a3eb8dfd06aae5d50..47b9c34b4d91ac2a88e74c78e876672f169235a4 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.cc,v 1.259 2001/09/03 10:33:02 robertc Exp $
+ * $Id: acl.cc,v 1.260 2001/10/10 15:17:38 adrian Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -51,7 +51,6 @@ static void aclParseMethodList(void *curlist);
 static void aclParseTimeSpec(void *curlist);
 static void aclParseIntRange(void *curlist);
 static char *strtokFile(void);
-static void aclDestroyAclList(acl_list * list);
 static void aclDestroyTimeList(acl_time_data * data);
 static void aclDestroyIntRange(intrange *);
 static void aclLookupProxyAuthStart(aclCheck_t * checklist);
@@ -966,9 +965,6 @@ aclParseAccessLine(acl_access ** head)
     acl_access *A = NULL;
     acl_access *B = NULL;
     acl_access **T = NULL;
-    acl_list *L = NULL;
-    acl_list **Tail = NULL;
-    acl *a = NULL;
 
     /* first expect either 'allow' or 'deny' */
     if ((t = strtok(NULL, w_space)) == NULL) {
@@ -990,10 +986,31 @@ aclParseAccessLine(acl_access ** head)
        cbdataFree(A);
        return;
     }
+    aclParseAclList(&A->acl_list);
+    if (A->acl_list == NULL) {
+       debug(28, 0) ("%s line %d: %s\n",
+           cfg_filename, config_lineno, config_input_line);
+       debug(28, 0) ("aclParseAccessLine: Access line contains no ACL's, skipping\n");
+       cbdataFree(A);
+       return;
+    }
+    A->cfgline = xstrdup(config_input_line);
+    /* Append to the end of this list */
+    for (B = *head, T = head; B; T = &B->next, B = B->next);
+    *T = A;
+    /* We lock _acl_access structures in aclCheck() */
+}
+
+void
+aclParseAclList(acl_list ** head)
+{
+    acl_list *L = NULL;
+    acl_list **Tail = head;    /* sane name in the use below */
+    acl *a = NULL;
+    char *t;
 
     /* next expect a list of ACL names, possibly preceeded
      * by '!' for negation */
-    Tail = &A->acl_list;
     while ((t = strtok(NULL, w_space))) {
        L = memAllocate(MEM_ACL_LIST);
        L->op = 1;              /* defaults to non-negated */
@@ -1015,18 +1032,6 @@ aclParseAccessLine(acl_access ** head)
        *Tail = L;
        Tail = &L->next;
     }
-    if (A->acl_list == NULL) {
-       debug(28, 0) ("%s line %d: %s\n",
-           cfg_filename, config_lineno, config_input_line);
-       debug(28, 0) ("aclParseAccessLine: Access line contains no ACL's, skipping\n");
-       cbdataFree(A);
-       return;
-    }
-    A->cfgline = xstrdup(config_input_line);
-    /* Append to the end of this list */
-    for (B = *head, T = head; B; T = &B->next, B = B->next);
-    *T = A;
-    /* We lock _acl_access structures in aclCheck() */
 }
 
 /**************/
@@ -2101,13 +2106,13 @@ aclDestroyAcls(acl ** head)
     *head = NULL;
 }
 
-static void
-aclDestroyAclList(acl_list * list)
+void
+aclDestroyAclList(acl_list ** head)
 {
-    acl_list *next = NULL;
-    for (; list; list = next) {
-       next = list->next;
-       memFree(list, MEM_ACL_LIST);
+    acl_list *l;
+    for (l = *head; l; l = *head) {
+       *head = l->next;
+       memFree(l, MEM_ACL_LIST);
     }
 }
 
@@ -2119,8 +2124,7 @@ aclDestroyAccessList(acl_access ** list)
     for (l = *list; l; l = next) {
        debug(28, 3) ("aclDestroyAccessList: '%s'\n", l->cfgline);
        next = l->next;
-       aclDestroyAclList(l->acl_list);
-       l->acl_list = NULL;
+       aclDestroyAclList(&l->acl_list);
        safe_free(l->cfgline);
        cbdataFree(l);
     }
@@ -2200,13 +2204,13 @@ aclHostDomainCompare(const void *a, const void *b)
 
 /* compare two network specs
  * 
- * NOTE: this is very similar to aclIpNetworkCompare and it's not yet
- * clear whether this OK. The problem could be with when a network
- * is a subset of the other networks:
- * 
- * 128.1.2.0/255.255.255.128 == 128.1.2.0/255.255.255.0 ?
- * 
- * Currently only the first address of the first network is used.
+ * NOTE: this is very similar to aclIpNetworkCompare and it's not yet
+ * clear whether this OK. The problem could be with when a network
+ * is a subset of the other networks:
+ * 
+ * 128.1.2.0/255.255.255.128 == 128.1.2.0/255.255.255.0 ?
+ * 
+ * Currently only the first address of the first network is used.
  */
 
 /* compare an address and a network spec */
index 0bda6cd0628744d4c2a233649560432e0d7d441f..63999f7d209363cf8ccec48851382fdecfdf02b9 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.cc,v 1.390 2001/08/23 13:20:46 robertc Exp $
+ * $Id: cache_cf.cc,v 1.391 2001/10/10 15:17:39 adrian Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -563,20 +563,26 @@ free_acl(acl ** ae)
 }
 
 static void
-dump_acl_access(StoreEntry * entry, const char *name, acl_access * head)
+dump_acl_list(StoreEntry * entry, acl_list * head)
 {
     acl_list *l;
-    while (head != NULL) {
+    for (l = head; l; l = l->next) {
+       storeAppendPrintf(entry, " %s%s",
+           l->op ? null_string : "!",
+           l->acl->name);
+    }
+}
+
+static void
+dump_acl_access(StoreEntry * entry, const char *name, acl_access * head)
+{
+    acl_access *l;
+    for (l = head; l; l = l->next) {
        storeAppendPrintf(entry, "%s %s",
            name,
-           head->allow ? "Allow" : "Deny");
-       for (l = head->acl_list; l != NULL; l = l->next) {
-           storeAppendPrintf(entry, " %s%s",
-               l->op ? null_string : "!",
-               l->acl->name);
-       }
+           l->allow ? "Allow" : "Deny");
+       dump_acl_list(entry, l->acl_list);
        storeAppendPrintf(entry, "\n");
-       head = head->next;
     }
 }
 
@@ -620,6 +626,110 @@ free_address(struct in_addr *addr)
     memset(addr, '\0', sizeof(struct in_addr));
 }
 
+CBDATA_TYPE(acl_address);
+
+static void
+dump_acl_address(StoreEntry * entry, const char *name, acl_address * head)
+{
+    acl_address *l;
+    for (l = head; l; l = l->next) {
+       if (l->addr.s_addr != INADDR_ANY)
+           storeAppendPrintf(entry, "%s %s", name, inet_ntoa(l->addr));
+       else
+           storeAppendPrintf(entry, "%s autoselect", name);
+       dump_acl_list(entry, l->acl_list);
+       storeAppendPrintf(entry, "\n");
+    }
+}
+
+static void
+freed_acl_address(void *data)
+{
+    acl_address *l = data;
+    aclDestroyAclList(&l->acl_list);
+}
+
+static void
+parse_acl_address(acl_address ** head)
+{
+    acl_address *l;
+    acl_address **tail = head; /* sane name below */
+    CBDATA_INIT_TYPE_FREECB(acl_address, freed_acl_address);
+    l = cbdataAlloc(acl_address);
+    parse_address(&l->addr);
+    aclParseAclList(&l->acl_list);
+    while (*tail)
+       tail = &(*tail)->next;
+    *tail = l;
+}
+
+static void
+free_acl_address(acl_address ** head)
+{
+    while (*head) {
+       acl_address *l = *head;
+       *head = l->next;
+       cbdataFree(l);
+    }
+}
+
+CBDATA_TYPE(acl_tos);
+
+static void
+dump_acl_tos(StoreEntry * entry, const char *name, acl_tos * head)
+{
+    acl_tos *l;
+    for (l = head; l; l = l->next) {
+       if (l->tos > 0)
+           storeAppendPrintf(entry, "%s 0x%02X", name, l->tos);
+       else
+           storeAppendPrintf(entry, "%s none", name);
+       dump_acl_list(entry, l->acl_list);
+       storeAppendPrintf(entry, "\n");
+    }
+}
+
+static void
+freed_acl_tos(void *data)
+{
+    acl_tos *l = data;
+    aclDestroyAclList(&l->acl_list);
+}
+
+static void
+parse_acl_tos(acl_tos ** head)
+{
+    acl_tos *l;
+    acl_tos **tail = head;     /* sane name below */
+    int tos;
+    char junk;
+    char *token = strtok(NULL, w_space);
+    if (!token)
+       self_destruct();
+    if (sscanf(token, "0x%x%c", &tos, &junk) != 1)
+       self_destruct();
+    if (tos < 0 || tos > 255)
+       self_destruct();
+    CBDATA_INIT_TYPE_FREECB(acl_tos, freed_acl_tos);
+    l = cbdataAlloc(acl_tos);
+    l->tos = tos;
+    aclParseAclList(&l->acl_list);
+    while (*tail)
+       tail = &(*tail)->next;
+    *tail = l;
+}
+
+static void
+free_acl_tos(acl_tos ** head)
+{
+    while (*head) {
+       acl_tos *l = *head;
+       *head = l->next;
+       l->next = NULL;
+       cbdataFree(l);
+    }
+}
+
 #if DELAY_POOLS
 
 /* do nothing - free_delay_pool_count is the magic free function.
index af7c56c34a2d1a8f5dcc892c5583fcbd06c558e3..0246f79eab1ff71f8b1ee9f3b98e1c943e3a81bd 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.231 2001/10/04 12:47:59 hno Exp $
+# $Id: cf.data.pre,v 1.232 2001/10/10 15:17:40 adrian Exp $
 #
 #
 # SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -94,7 +94,7 @@ DOC_START
 
         The socket address where Squid will listen for HTTPS client
         requests.
-       
+
         This is really only useful for situations where you are running
         squid in accelerator mode and you want to do the SSL work at the
         accelerator level.
@@ -173,12 +173,6 @@ DOC_START
 DOC_END
 
 
-NAME: tcp_outgoing_address outbound_address
-TYPE: address
-LOC: Config.Addrs.tcp_outgoing
-DEFAULT: 255.255.255.255
-DOC_NONE
-
 NAME: udp_incoming_address
 TYPE: address
 LOC:Config.Addrs.udp_incoming
@@ -193,8 +187,6 @@ DOC_START
        Usage: tcp_incoming_address 10.20.30.40
               udp_outgoing_address fully.qualified.domain.name
 
-       tcp_outgoing_address    is used for connections made to remote
-                               servers and other caches.
        udp_incoming_address    is used for the ICP socket receiving packets
                                from other caches.
        udp_outgoing_address    is used for ICP packets sent out to other
@@ -2100,6 +2092,60 @@ DOC_START
        the configure script.
 DOC_END
 
+NAME: tcp_outgoing_tos tcp_outgoing_ds tcp_outgoin_dscp
+TYPE: acl_tos
+DEFAULT: none
+LOC: Config.accessList.outgoing_tos
+DOC_START
+       Allows you to select a TOS/Diffserv value to mark outgoing
+       connections with, based on the username or source address
+       making the request.
+
+       tcp_outgoing_tos ds-field [!]aclname ...
+
+       Example where normal_service_net uses the TOS value 0x00
+       and normal_service_net uses 0x20
+
+       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_tos 0x00 normal_service_net 0x00
+       tcp_outgoing_tos 0x20 good_service_net
+
+       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, or
+       "default" to use whatever default your host has.
+
+       Processing proceeds in the order specified, and stops at first fully
+       matching line.
+DOC_END
+
+NAME: tcp_outgoing_address
+TYPE: acl_address
+DEFAULT: none
+LOC: Config.accessList.outgoing_address
+DOC_START
+       Allows you to map requests to different outgoing IP addresses
+       based on the username or sourceaddress of the user making
+       the request.
+       
+       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.
+
+       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.0.3
+
+       Processing proceeds in the order specified, and stops at first fully
+       matching line.
+DOC_END
 
 NAME: reply_body_max_size
 COMMENT: bytes allow|deny acl acl...
index b6717fddf2f0a6f76f701980cbbf511dbd46d1d7..0156980fb24d495c699845667ef44cc5d972bf84 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm.cc,v 1.320 2001/08/26 22:22:43 hno Exp $
+ * $Id: comm.cc,v 1.321 2001/10/10 15:17:40 adrian Exp $
  *
  * DEBUG: section 5     Socket Functions
  * AUTHOR: Harvest Derived
@@ -148,7 +148,7 @@ commBind(int s, struct in_addr in_addr, u_short port)
 }
 
 /* Create a socket. Default is blocking, stream (TCP) socket.  IO_TYPE
- * is OR of flags specified in comm.h. */
+ * is OR of flags specified in comm.h. Defaults TOS */
 int
 comm_open(int sock_type,
     int proto,
@@ -156,8 +156,24 @@ comm_open(int sock_type,
     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. */
@@ -177,10 +193,23 @@ comm_open(int sock_type,
        }
        return -1;
     }
+    /* set TOS if needed */
+    if (TOS) {
+#ifdef IP_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());
+#else
+       debug(50, 0) ("comm_open: setsockopt(IP_TOS) not supported on this platform\n");
+#endif
+    }
     /* update fdstat */
     debug(5, 5) ("comm_open: FD %d is a new socket\n", new_socket);
     fd_open(new_socket, FD_SOCKET, note);
     F = &fd_table[new_socket];
+    F->local_addr = addr;
+    F->tos = tos;
     if (!(flags & COMM_NOCLOEXEC))
        commSetCloseOnExec(new_socket);
     if ((flags & COMM_REUSEADDR))
@@ -303,6 +332,7 @@ static int
 commResetFD(ConnectStateData * cs)
 {
     int fd2;
+    fde *F;
     if (!cbdataValid(cs->data))
        return 0;
     statCounter.syscalls.sock.sockets++;
@@ -318,23 +348,34 @@ commResetFD(ConnectStateData * cs)
        debug(5, 0) ("commResetFD: dup2: %s\n", xstrerror());
        if (ENFILE == errno || EMFILE == errno)
            fdAdjustReserved();
+       close(fd2);
        return 0;
     }
     close(fd2);
+    F = &fd_table[cs->fd];
     fd_table[cs->fd].flags.called_connect = 0;
     /*
      * yuck, this has assumptions about comm_open() arguments for
      * the original socket
      */
-    commSetCloseOnExec(cs->fd);
-    if (Config.Addrs.tcp_outgoing.s_addr != no_addr.s_addr) {
-       if (commBind(cs->fd, Config.Addrs.tcp_outgoing, 0) != COMM_OK) {
-           return 0;
-       }
+    if (commBind(cs->fd, F->local_addr, F->local_port) != COMM_OK) {
+       debug(5, 0) ("commResetFD: bind: %s\n", xstrerror());
+       return 0;
     }
-    commSetNonBlocking(cs->fd);
+#ifdef IP_TOS
+    if (F->tos) {
+       int tos = F->tos;
+       if (setsockopt(cs->fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(int)) < 0)
+               debug(50, 1) ("commResetFD: setsockopt(IP_TOS) on FD %d: %s\n", cs->fd, xstrerror());
+    }
+#endif
+    if (F->flags.close_on_exec)
+       commSetCloseOnExec(cs->fd);
+    if (F->flags.nonblocking)
+       commSetNonBlocking(cs->fd);
 #ifdef TCP_NODELAY
-    commSetTcpNoDelay(cs->fd);
+    if (F->flags.nodelay)
+       commSetTcpNoDelay(cs->fd);
 #endif
     if (Config.tcpRcvBufsz > 0)
        commSetTcpRcvbuf(cs->fd, Config.tcpRcvBufsz);
@@ -786,6 +827,7 @@ commSetCloseOnExec(int fd)
     }
     if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
        debug(50, 0) ("FD %d: set close-on-exec failed: %s\n", fd, xstrerror());
+    fd_table[fd].flags.close_on_exec = 1;
 #endif
 }
 
@@ -796,6 +838,7 @@ commSetTcpNoDelay(int fd)
     int on = 1;
     if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0)
        debug(50, 1) ("commSetTcpNoDelay: FD %d: %s\n", fd, xstrerror());
+    fd_table[fd].flags.nodelay = 1;
 }
 #endif
 
index 3def2973931f6baebd028fa902f25e3b82a5ace3..ae41e9f935b4c3ba5675e7329028f60fc22d0339 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: forward.cc,v 1.81 2001/03/03 10:39:31 hno Exp $
+ * $Id: forward.cc,v 1.82 2001/10/10 15:17:41 adrian Exp $
  *
  * DEBUG: section 17    Request Forwarding
  * AUTHOR: Duane Wessels
@@ -266,6 +266,58 @@ fwdConnectTimeout(int fd, void *data)
     comm_close(fd);
 }
 
+static struct in_addr
+aclMapAddr(acl_address * head, aclCheck_t * ch)
+{
+    acl_address *l;
+    struct in_addr addr;
+    for (l = head; l; l = l->next) {
+       if (aclMatchAclList(l->acl_list, ch))
+           return l->addr;
+    }
+    addr.s_addr = INADDR_ANY;
+    return addr;
+}
+
+static int
+aclMapTOS(acl_tos * head, aclCheck_t * ch)
+{
+    acl_tos *l;
+    for (l = head; l; l = l->next) {
+       if (aclMatchAclList(l->acl_list, ch))
+           return l->tos;
+    }
+    return 0;
+}
+
+struct in_addr
+getOutgoingAddr(request_t * request)
+{
+    aclCheck_t ch;
+    memset(&ch, '\0', sizeof(aclCheck_t));
+    if (request) {
+       ch.src_addr = request->client_addr;
+       ch.my_addr = request->my_addr;
+       ch.my_port = request->my_port;
+       ch.request = request;
+    }
+    return aclMapAddr(Config.accessList.outgoing_address, &ch);
+}
+
+unsigned long
+getOutgoingTOS(request_t * request)
+{
+    aclCheck_t ch;
+    memset(&ch, '\0', sizeof(aclCheck_t));
+    if (request) {
+       ch.src_addr = request->client_addr;
+       ch.my_addr = request->my_addr;
+       ch.my_port = request->my_port;
+       ch.request = request;
+    }
+    return aclMapTOS(Config.accessList.outgoing_tos, &ch);
+}
+
 static void
 fwdConnectStart(void *data)
 {
@@ -277,6 +329,8 @@ fwdConnectStart(void *data)
     const char *host;
     unsigned short port;
     time_t ctimeout;
+    struct in_addr outgoing;
+    unsigned short tos;
     assert(fs);
     assert(fwdState->server_fd == -1);
     debug(17, 3) ("fwdConnectStart: %s\n", url);
@@ -306,11 +360,17 @@ fwdConnectStart(void *data)
 #if URL_CHECKSUM_DEBUG
     assert(fwdState->entry->mem_obj->chksum == url_checksum(url));
 #endif
-    fd = comm_open(SOCK_STREAM,
+    outgoing = getOutgoingAddr(fwdState->request);
+    tos = getOutgoingTOS(fwdState->request);
+
+    debug(17, 3) ("fwdConnectStart: got addr %s, tos %d\n",
+       inet_ntoa(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 7741f0e3a27e164d4e42289f8333dee9f3360473..1010c56c065c5d74acb95699589f25d633bc59f6 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ftp.cc,v 1.311 2001/09/18 13:55:00 hno Exp $
+ * $Id: ftp.cc,v 1.312 2001/10/10 15:17:41 adrian Exp $
  *
  * DEBUG: section 9     File Transfer Protocol (FTP)
  * AUTHOR: Harvest Derived
@@ -1680,7 +1680,8 @@ ftpSendPasv(FtpStateData * ftpState)
     if (getsockname(ftpState->ctrl.fd, (struct sockaddr *) &addr, &addr_len)) {
        debug(9, 0) ("ftpSendPasv: getsockname(%d,..): %s\n",
            ftpState->ctrl.fd, xstrerror());
-       addr.sin_addr = Config.Addrs.tcp_outgoing;
+       ftpFail(ftpState);
+       return;
     }
     /* Open data channel with the same local address as control channel */
     fd = comm_open(SOCK_STREAM,
index d31371c3ade684290564777633ec190fb5dd338c..8b6c07b71a1362afa97e1404809f825753adee8a 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: neighbors.cc,v 1.297 2001/06/26 21:02:05 wessels Exp $
+ * $Id: neighbors.cc,v 1.298 2001/10/10 15:17:41 adrian Exp $
  *
  * DEBUG: section 15    Neighbor Routines
  * AUTHOR: Harvest Derived
@@ -759,9 +759,9 @@ neighborIgnoreNonPeer(const struct sockaddr_in *from, icp_opcode opcode)
 
 /* ignoreMulticastReply
  * 
- * We want to ignore replies from multicast peers if the
- * cache_host_domain rules would normally prevent the peer
- * from being used
+ * We want to ignore replies from multicast peers if the
+ * cache_host_domain rules would normally prevent the peer
+ * from being used
  */
 static int
 ignoreMulticastReply(peer * p, MemObject * mem)
@@ -1072,7 +1072,7 @@ peerProbeConnect(peer * p)
        return;                 /* probe already running */
     if (squid_curtime - p->stats.last_connect_probe < Config.Timeout.connect)
        return;                 /* don't probe to often */
-    fd = comm_open(SOCK_STREAM, 0, Config.Addrs.tcp_outgoing,
+    fd = comm_open(SOCK_STREAM, 0, getOutgoingAddr(NULL),
        0, COMM_NONBLOCKING, p->host);
     if (fd < 0)
        return;
index 363887296c18a94023060b3c97b47dbcfd675d0f..dd63eeb26f6371e55641ab7a2b6fbbd9012b6008 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.413 2001/10/08 16:18:32 hno Exp $
+ * $Id: protos.h,v 1.414 2001/10/10 15:17:41 adrian Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -59,7 +59,9 @@ extern void aclChecklistFree(aclCheck_t *);
 extern int aclMatchAclList(const acl_list * list, aclCheck_t * checklist);
 extern void aclDestroyAccessList(struct _acl_access **list);
 extern void aclDestroyAcls(acl **);
+extern void aclDestroyAclList(acl_list **);
 extern void aclParseAccessLine(struct _acl_access **);
+extern void aclParseAclList(acl_list **);
 extern void aclParseAclLine(acl **);
 extern int aclIsProxyAuth(const char *name);
 extern err_type aclGetDenyInfoPage(acl_deny_info_list ** head, const char *name);
@@ -153,6 +155,7 @@ extern int comm_connect_addr(int sock, const struct sockaddr_in *);
 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);
@@ -720,6 +723,8 @@ extern void fwdUninit(void);
 extern void fwdLogRotate(void);
 extern void fwdStatus(FwdState *, http_status);
 #endif
+struct in_addr getOutgoingAddr(request_t * request);
+unsigned long getOutgoingTOS(request_t * request);
 
 extern void urnStart(request_t *, StoreEntry *);
 
index 0953e1d841a3378c5acde1955349548d43f6dc60..31cc8f02ac848d5ae3bb0e0530cad650db92551e 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ssl.cc,v 1.114 2001/07/17 10:33:28 hno Exp $
+ * $Id: ssl.cc,v 1.115 2001/10/10 15:17:42 adrian Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -468,11 +468,12 @@ sslStart(int fd, const char *url, request_t * request, size_t * size_ptr, int *s
     statCounter.server.all.requests++;
     statCounter.server.other.requests++;
     /* Create socket. */
-    sock = comm_open(SOCK_STREAM,
+    sock = comm_openex(SOCK_STREAM,
        0,
-       Config.Addrs.tcp_outgoing,
+       getOutgoingAddr(request),
        0,
        COMM_NONBLOCKING,
+       getOutgoingTOS(request),
        url);
     if (sock == COMM_ERROR) {
        debug(26, 4) ("sslStart: Failed because we're out of sockets.\n");
index 5a3c92f74e5403d6e3fd21962fefbf2a6883617e..d2d214475e738aeb3905a656f9374c6c8e75d6b2 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.402 2001/10/08 16:18:33 hno Exp $
+ * $Id: structs.h,v 1.403 2001/10/10 15:17:42 adrian Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -260,6 +260,18 @@ struct _acl_access {
     acl_access *next;
 };
 
+struct _acl_address {
+    acl_address *next;
+    acl_list *acl_list;
+    struct in_addr addr;
+};
+
+struct _acl_tos {
+    acl_tos *next;
+    acl_list *acl_list;
+    int tos;
+};
+
 struct _aclCheck_t {
     const acl_access *access_list;
     struct in_addr src_addr;
@@ -490,7 +502,6 @@ struct _SquidConfig {
        u_short port;
     } Announce;
     struct {
-       struct in_addr tcp_outgoing;
        struct in_addr udp_incoming;
        struct in_addr udp_outgoing;
 #if SQUID_SNMP
@@ -589,6 +600,8 @@ struct _SquidConfig {
 #endif
        acl_access *redirector;
        acl_access *reply;
+       acl_address *outgoing_address;
+       acl_tos *outgoing_tos;
     } accessList;
     acl_deny_info_list *denyInfoList;
     struct _authConfig {
@@ -733,6 +746,8 @@ struct _fde {
     unsigned int type;
     u_short local_port;
     u_short remote_port;
+    struct in_addr local_addr;
+    unsigned char tos;
     char ipaddr[16];           /* dotted decimal address of peer */
     char desc[FD_DESC_SZ];
     struct {
@@ -745,6 +760,8 @@ struct _fde {
        unsigned int nonblocking:1;
        unsigned int ipc:1;
        unsigned int called_connect:1;
+       unsigned int nodelay:1;
+       unsigned int close_on_exec:1;
     } flags;
     int bytes_read;
     int bytes_written;
index d286e68379d253f8d4b9b3a3adfb08047e603ba5..104b6189aa6e170ddaa3c93c26b6fe48af6d59b2 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tunnel.cc,v 1.114 2001/07/17 10:33:28 hno Exp $
+ * $Id: tunnel.cc,v 1.115 2001/10/10 15:17:42 adrian Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -468,11 +468,12 @@ sslStart(int fd, const char *url, request_t * request, size_t * size_ptr, int *s
     statCounter.server.all.requests++;
     statCounter.server.other.requests++;
     /* Create socket. */
-    sock = comm_open(SOCK_STREAM,
+    sock = comm_openex(SOCK_STREAM,
        0,
-       Config.Addrs.tcp_outgoing,
+       getOutgoingAddr(request),
        0,
        COMM_NONBLOCKING,
+       getOutgoingTOS(request),
        url);
     if (sock == COMM_ERROR) {
        debug(26, 4) ("sslStart: Failed because we're out of sockets.\n");
index 209429b6555f1f3fec25f87e541f0dccf4e69973..0a307e758ec9acd561bcc30102d50263cc3465d0 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: typedefs.h,v 1.131 2001/10/08 16:18:33 hno Exp $
+ * $Id: typedefs.h,v 1.132 2001/10/10 15:17:42 adrian Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -75,6 +75,8 @@ typedef struct _acl acl;
 typedef struct _acl_snmp_comm acl_snmp_comm;
 typedef struct _acl_list acl_list;
 typedef struct _acl_access acl_access;
+typedef struct _acl_address acl_address;
+typedef struct _acl_tos acl_tos;
 typedef struct _aclCheck_t aclCheck_t;
 typedef struct _wordlist wordlist;
 typedef struct _intlist intlist;