From: adrian <> Date: Wed, 10 Oct 2001 21:17:37 +0000 (+0000) Subject: Commit Roger Venning's TOS/source address ACL selection work. X-Git-Tag: SQUID_3_0_PRE1~1367 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d68277188a2ab77fc3d9016edd3fb9561ac9d22c;p=thirdparty%2Fsquid.git Commit Roger Venning's TOS/source address ACL selection work. 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. --- diff --git a/ChangeLog b/ChangeLog index 18061517e3..e160fdd9b9 100644 --- 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 (): diff --git a/src/acl.cc b/src/acl.cc index 5d5e7a479c..47b9c34b4d 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -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 */ diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 0bda6cd062..63999f7d20 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -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. diff --git a/src/cf.data.pre b/src/cf.data.pre index af7c56c34a..0246f79eab 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -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... diff --git a/src/comm.cc b/src/comm.cc index b6717fddf2..0156980fb2 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -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 diff --git a/src/forward.cc b/src/forward.cc index 3def297393..ae41e9f935 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -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()); diff --git a/src/ftp.cc b/src/ftp.cc index 7741f0e3a2..1010c56c06 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -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, diff --git a/src/neighbors.cc b/src/neighbors.cc index d31371c3ad..8b6c07b71a 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -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; diff --git a/src/protos.h b/src/protos.h index 363887296c..dd63eeb26f 100644 --- a/src/protos.h +++ b/src/protos.h @@ -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 *); diff --git a/src/ssl.cc b/src/ssl.cc index 0953e1d841..31cc8f02ac 100644 --- a/src/ssl.cc +++ b/src/ssl.cc @@ -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"); diff --git a/src/structs.h b/src/structs.h index 5a3c92f74e..d2d214475e 100644 --- a/src/structs.h +++ b/src/structs.h @@ -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; diff --git a/src/tunnel.cc b/src/tunnel.cc index d286e68379..104b6189aa 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -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"); diff --git a/src/typedefs.h b/src/typedefs.h index 209429b655..0a307e758e 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -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;