=== modified file 'src/AccessLogEntry.cc' --- src/AccessLogEntry.cc 2014-03-30 12:00:34 +0000 +++ src/AccessLogEntry.cc 2014-06-20 08:37:12 +0000 @@ -43,22 +43,21 @@ AccessLogEntry::~AccessLogEntry() { safe_free(headers.request); #if USE_ADAPTATION safe_free(adapt.last_meta); #endif safe_free(headers.reply); safe_free(headers.adapted_request); HTTPMSGUNLOCK(adapted_request); HTTPMSGUNLOCK(reply); HTTPMSGUNLOCK(request); #if ICAP_CLIENT HTTPMSGUNLOCK(icap.reply); HTTPMSGUNLOCK(icap.request); #endif - cbdataReferenceDone(cache.port); } === modified file 'src/AccessLogEntry.h' --- src/AccessLogEntry.h 2014-04-22 02:47:09 +0000 +++ src/AccessLogEntry.h 2014-06-20 04:33:45 +0000 @@ -168,41 +168,41 @@ #if USE_OPENSSL ssluser(NULL), #endif port(NULL) { caddr.setNoAddr(); } Ip::Address caddr; int64_t highOffset; int64_t objectSize; LogTags code; struct timeval start_time; ///< The time the master transaction started int msec; const char *rfc931; const char *extuser; #if USE_OPENSSL const char *ssluser; Ssl::X509_Pointer sslClientCert; ///< cert received from the client #endif - AnyP::PortCfg *port; + AnyP::PortCfgPointer port; } cache; /** \brief This subclass holds log info for various headers in raw format * \todo shuffle this to the relevant protocol section. */ class Headers { public: Headers() : request(NULL), adapted_request(NULL), reply(NULL) {} char *request; //< virgin HTTP request headers char *adapted_request; //< HTTP request headers after adaptation and redirection char *reply; } headers; === modified file 'src/CommCalls.cc' --- src/CommCalls.cc 2014-06-05 14:57:58 +0000 +++ src/CommCalls.cc 2014-06-20 04:25:30 +0000 @@ -1,21 +1,22 @@ #include "squid.h" +#include "anyp/PortCfg.h" #include "comm/Connection.h" #include "CommCalls.h" #include "fde.h" #include "globals.h" /* CommCommonCbParams */ CommCommonCbParams::CommCommonCbParams(void *aData): data(cbdataReference(aData)), conn(), flag(Comm::OK), xerrno(0), fd(-1) { } CommCommonCbParams::CommCommonCbParams(const CommCommonCbParams &p): data(cbdataReference(p.data)), conn(p.conn), flag(p.flag), xerrno(p.xerrno), fd(p.fd) { } CommCommonCbParams::~CommCommonCbParams() { cbdataReferenceDone(data); === modified file 'src/MasterXaction.h' --- src/MasterXaction.h 2013-06-18 23:26:17 +0000 +++ src/MasterXaction.h 2014-06-20 08:16:45 +0000 @@ -1,25 +1,25 @@ #ifndef SQUID_SRC_MASTERXACTION_H #define SQUID_SRC_MASTERXACTION_H #include "anyp/forward.h" -#include "base/CbcPointer.h" +//#include "base/CbcPointer.h" #include "base/InstanceId.h" #include "base/Lock.h" #include "comm/forward.h" /** Master transaction details. * * Aggregates historical data from individual related protocol-specific * transactions such as an HTTP client transaction and the corresponding * HTTP or FTP server transaction. * * Individual transaction information worth sending or logging should be * recorded here, ideally without exposing other master transaction users * to internal details of individual transactions. For example, storing an * HTTP client IP address is a good idea but storing a pointer to some * client-side job which maintains that address is not. * * A master transaction is created by a newly accepted client connection, * a new request on the existing client connection, or an internal request * generated by Squid. All client-side protocols, including HTTP, HTCP, ICP, * and SNMP will eventually create master transactions. === modified file 'src/SquidConfig.h' --- src/SquidConfig.h 2014-04-04 16:36:47 +0000 +++ src/SquidConfig.h 2014-06-21 04:07:37 +0000 @@ -119,46 +119,40 @@ } Timeout; size_t maxRequestHeaderSize; int64_t maxRequestBodySize; int64_t maxChunkedRequestBodySize; size_t maxRequestBufferSize; size_t maxReplyHeaderSize; AclSizeLimit *ReplyBodySize; struct { unsigned short icp; #if USE_HTCP unsigned short htcp; #endif #if SQUID_SNMP unsigned short snmp; #endif } Port; - struct { - AnyP::PortCfg *http; -#if USE_OPENSSL - AnyP::PortCfg *https; -#endif - } Sockaddr; #if SQUID_SNMP struct { char *configFile; char *agentInfo; } Snmp; #endif #if USE_WCCP struct { Ip::Address router; Ip::Address address; int version; } Wccp; #endif #if USE_WCCPv2 struct { Ip::Address_list *router; Ip::Address address; === modified file 'src/acl/Acl.cc' --- src/acl/Acl.cc 2014-02-10 12:58:49 +0000 +++ src/acl/Acl.cc 2014-06-21 04:06:43 +0000 @@ -208,52 +208,52 @@ if (strlen(t) >= ACL_NAME_SZ) { debugs(28, DBG_CRITICAL, "aclParseAclLine: aclParseAclLine: ACL name '" << t << "' too long, max " << ACL_NAME_SZ - 1 << " characters supported"); parser.destruct(); return; } xstrncpy(aclname, t, ACL_NAME_SZ); /* snarf the ACL type */ const char *theType; if ((theType = ConfigParser::NextToken()) == NULL) { debugs(28, DBG_CRITICAL, "aclParseAclLine: missing ACL type."); parser.destruct(); return; } // Is this ACL going to work? if (strcmp(theType, "myip") == 0) { - AnyP::PortCfg *p = Config.Sockaddr.http; - while (p) { + AnyP::PortCfgPointer p = HttpPortList; + while (p != NULL) { // Bug 3239: not reliable when there is interception traffic coming if (p->flags.natIntercept) debugs(28, DBG_CRITICAL, "WARNING: 'myip' ACL is not reliable for interception proxies. Please use 'myportname' instead."); p = p->next; } debugs(28, DBG_IMPORTANT, "UPGRADE: ACL 'myip' type is has been renamed to 'localip' and matches the IP the client connected to."); theType = "localip"; } else if (strcmp(theType, "myport") == 0) { - AnyP::PortCfg *p = Config.Sockaddr.http; - while (p) { + AnyP::PortCfgPointer p = HttpPortList; + while (p != NULL) { // Bug 3239: not reliable when there is interception traffic coming // Bug 3239: myport - not reliable (yet) when there is interception traffic coming if (p->flags.natIntercept) debugs(28, DBG_CRITICAL, "WARNING: 'myport' ACL is not reliable for interception proxies. Please use 'myportname' instead."); p = p->next; } theType = "localport"; debugs(28, DBG_IMPORTANT, "UPGRADE: ACL 'myport' type is has been renamed to 'localport' and matches the port the client connected to."); } if (!Prototype::Registered(theType)) { debugs(28, DBG_CRITICAL, "FATAL: Invalid ACL type '" << theType << "'"); // XXX: make this an ERROR and skip the ACL creation. We *may* die later when its use is attempted. Or may not. parser.destruct(); return; } if ((A = FindByName(aclname)) == NULL) { debugs(28, 3, "aclParseAclLine: Creating ACL '" << aclname << "'"); A = ACL::Factory(theType); === modified file 'src/anyp/PortCfg.cc' --- src/anyp/PortCfg.cc 2014-04-16 21:58:08 +0000 +++ src/anyp/PortCfg.cc 2014-06-22 11:15:06 +0000 @@ -1,38 +1,41 @@ #include "squid.h" #include "anyp/PortCfg.h" #include "comm.h" #include "fatal.h" #if USE_OPENSSL #include "ssl/support.h" #endif #include #include -CBDATA_NAMESPACED_CLASS_INIT(AnyP, PortCfg); +AnyP::PortCfgPointer HttpPortList; +#if USE_OPENSSL +AnyP::PortCfgPointer HttpsPortList; +#endif int NHttpSockets = 0; int HttpSockets[MAXTCPLISTENPORTS]; AnyP::PortCfg::PortCfg() : - next(NULL), + next(), s(), transport(AnyP::PROTO_HTTP,1,1), // "Squid is an HTTP proxy", etc. name(NULL), defaultsite(NULL), flags(), allow_direct(false), vhost(false), actAsOrigin(false), ignore_cc(false), connection_auth_disabled(false), vport(0), disable_pmtu_discovery(0), listenConn() #if USE_OPENSSL ,cert(NULL), key(NULL), version(0), cipher(NULL), options(NULL), clientca(NULL), @@ -67,44 +70,44 @@ listenConn->close(); listenConn = NULL; } safe_free(name); safe_free(defaultsite); #if USE_OPENSSL safe_free(cert); safe_free(key); safe_free(options); safe_free(cipher); safe_free(cafile); safe_free(capath); safe_free(dhfile); safe_free(sslflags); safe_free(sslContextSessionId); #endif } -AnyP::PortCfg * +AnyP::PortCfgPointer AnyP::PortCfg::clone() const { - AnyP::PortCfg *b = new AnyP::PortCfg(); + AnyP::PortCfgPointer b = new AnyP::PortCfg(); b->s = s; if (name) b->name = xstrdup(name); if (defaultsite) b->defaultsite = xstrdup(defaultsite); b->transport = transport; b->flags = flags; b->allow_direct = allow_direct; b->vhost = vhost; b->vport = vport; b->connection_auth_disabled = connection_auth_disabled; b->disable_pmtu_discovery = disable_pmtu_discovery; b->tcp_keepalive = tcp_keepalive; #if 0 // TODO: AYJ: 2009-07-18: for now SSL does not clone. Configure separate ports with IPs and SSL settings #if USE_OPENSSL char *cert; === modified file 'src/anyp/PortCfg.h' --- src/anyp/PortCfg.h 2014-03-30 12:00:34 +0000 +++ src/anyp/PortCfg.h 2014-06-22 11:13:12 +0000 @@ -1,54 +1,54 @@ #ifndef SQUID_ANYP_PORTCFG_H #define SQUID_ANYP_PORTCFG_H #include "anyp/forward.h" #include "anyp/ProtocolVersion.h" #include "anyp/TrafficMode.h" #include "comm/Connection.h" #if USE_OPENSSL #include "ssl/gadgets.h" #endif namespace AnyP { -class PortCfg +class PortCfg : public RefCountable { public: PortCfg(); ~PortCfg(); - AnyP::PortCfg *clone() const; + AnyP::PortCfgPointer clone() const; #if USE_OPENSSL /// creates, configures, and validates SSL context and related port options void configureSslServerContext(); #endif /** * Set this ports transport type from a string representation. * Unknown transport type representations will halt Squid. * Supports: HTTP, HTTP/1.1, HTTPS, HTTPS/1.1. */ void setTransport(const char *aProtocol); - PortCfg *next; + PortCfgPointer next; Ip::Address s; AnyP::ProtocolVersion transport; ///< transport protocol and version received by this port char *name; /* visible name */ char *defaultsite; /* default web site */ TrafficMode flags; ///< flags indicating what type of traffic to expect via this port. bool allow_direct; ///< Allow direct forwarding in accelerator mode bool vhost; ///< uses host header bool actAsOrigin; ///< update replies to conform with RFC 2616 bool ignore_cc; ///< Ignore request Cache-Control directives bool connection_auth_disabled; ///< Don't support connection oriented auth int vport; ///< virtual port support. -1 if dynamic, >0 static int disable_pmtu_discovery; struct { unsigned int idle; @@ -77,34 +77,40 @@ char *dhfile; char *sslflags; char *sslContextSessionId; ///< "session id context" for staticSslContext bool generateHostCertificates; ///< dynamically make host cert for sslBump size_t dynamicCertMemCacheSize; ///< max size of generated certificates memory cache Ssl::SSL_CTX_Pointer staticSslContext; ///< for HTTPS accelerator or static sslBump Ssl::X509_Pointer signingCert; ///< x509 certificate for signing generated certificates Ssl::EVP_PKEY_Pointer signPkey; ///< private key for sighing generated certificates Ssl::X509_STACK_Pointer certsToChain; ///< x509 certificates to send with the generated cert Ssl::X509_Pointer untrustedSigningCert; ///< x509 certificate for signing untrusted generated certificates Ssl::EVP_PKEY_Pointer untrustedSignPkey; ///< private key for signing untrusted generated certificates Ssl::X509_CRL_STACK_Pointer clientVerifyCrls; ///< additional CRL lists to use when verifying the client certificate Ssl::X509_NAME_STACK_Pointer clientCA; ///< CA certificates to use when verifying client certificates Ssl::DH_Pointer dhParams; ///< DH parameters for temporary/ephemeral DH key exchanges Ssl::ContextMethod contextMethod; ///< The context method (SSL_METHOD) to use when creating certificates long sslContextFlags; ///< flags modifying the use of SSL long sslOptions; ///< SSL engine options #endif - - CBDATA_CLASS2(PortCfg); // namespaced }; } // namespace AnyP +/// list of Squid http_port configured +extern AnyP::PortCfgPointer HttpPortList; + +#if USE_OPENSSL +/// list of Squid https_port configured +extern AnyP::PortCfgPointer HttpsPortList; +#endif + // Max number of TCP listening ports #define MAXTCPLISTENPORTS 128 // TODO: kill this global array. Need to check performance of array vs list though. extern int NHttpSockets; extern int HttpSockets[MAXTCPLISTENPORTS]; #endif /* SQUID_ANYP_PORTCFG_H */ === modified file 'src/anyp/forward.h' --- src/anyp/forward.h 2014-02-07 13:45:20 +0000 +++ src/anyp/forward.h 2014-06-19 18:57:39 +0000 @@ -1,17 +1,17 @@ #ifndef _SQUID_SRC_ANYP_FORWARD_H #define _SQUID_SRC_ANYP_FORWARD_H -#include "base/CbcPointer.h" +#include "base/RefCount.h" namespace AnyP { class PortCfg; -typedef CbcPointer PortCfgPointer; +typedef RefCount PortCfgPointer; class UriScheme; } // namespace AnyP #endif /* _SQUID_SRC_ANYP_FORWARD_H */ === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2014-06-02 06:23:12 +0000 +++ src/cache_cf.cc 2014-06-21 04:49:41 +0000 @@ -212,44 +212,44 @@ #endif static void dump_HeaderWithAclList(StoreEntry * entry, const char *name, HeaderWithAclList *headers); static void parse_HeaderWithAclList(HeaderWithAclList **header); static void free_HeaderWithAclList(HeaderWithAclList **header); static void parse_note(Notes *); static void dump_note(StoreEntry *, const char *, Notes &); static void free_note(Notes *); static void parse_denyinfo(AclDenyInfoList ** var); static void dump_denyinfo(StoreEntry * entry, const char *name, AclDenyInfoList * var); static void free_denyinfo(AclDenyInfoList ** var); #if USE_WCCPv2 static void parse_IpAddress_list(Ip::Address_list **); static void dump_IpAddress_list(StoreEntry *, const char *, const Ip::Address_list *); static void free_IpAddress_list(Ip::Address_list **); #if CURRENTLY_UNUSED static int check_null_IpAddress_list(const Ip::Address_list *); #endif /* CURRENTLY_UNUSED */ #endif /* USE_WCCPv2 */ -static void parsePortCfg(AnyP::PortCfg **, const char *protocol); +static void parsePortCfg(AnyP::PortCfgPointer *, const char *protocol); #define parse_PortCfg(l) parsePortCfg((l), token) -static void dump_PortCfg(StoreEntry *, const char *, const AnyP::PortCfg *); -static void free_PortCfg(AnyP::PortCfg **); +static void dump_PortCfg(StoreEntry *, const char *, const AnyP::PortCfgPointer &); +#define free_PortCfg(h) *(h)=NULL #if USE_OPENSSL static void parse_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign); static void dump_sslproxy_cert_sign(StoreEntry *entry, const char *name, sslproxy_cert_sign *cert_sign); static void free_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign); static void parse_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt); static void dump_sslproxy_cert_adapt(StoreEntry *entry, const char *name, sslproxy_cert_adapt *cert_adapt); static void free_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt); static void parse_sslproxy_ssl_bump(acl_access **ssl_bump); static void dump_sslproxy_ssl_bump(StoreEntry *entry, const char *name, acl_access *ssl_bump); static void free_sslproxy_ssl_bump(acl_access **ssl_bump); #endif /* USE_OPENSSL */ static void parse_ftp_epsv(acl_access **ftp_epsv); static void dump_ftp_epsv(StoreEntry *entry, const char *name, acl_access *ftp_epsv); static void free_ftp_epsv(acl_access **ftp_epsv); static void parse_b_size_t(size_t * var); static void parse_b_int64_t(int64_t * var); @@ -919,49 +919,49 @@ Config.effectiveGroup); return; } Config2.effectiveGroupID = grp->gr_gid; } #if USE_OPENSSL debugs(3, DBG_IMPORTANT, "Initializing https proxy context"); Config.ssl_client.sslContext = sslCreateClientContext(Config.ssl_client.cert, Config.ssl_client.key, Config.ssl_client.version, Config.ssl_client.cipher, Config.ssl_client.options, Config.ssl_client.flags, Config.ssl_client.cafile, Config.ssl_client.capath, Config.ssl_client.crlfile); for (CachePeer *p = Config.peers; p != NULL; p = p->next) { if (p->use_ssl) { debugs(3, DBG_IMPORTANT, "Initializing cache_peer " << p->name << " SSL context"); p->sslContext = sslCreateClientContext(p->sslcert, p->sslkey, p->sslversion, p->sslcipher, p->ssloptions, p->sslflags, p->sslcafile, p->sslcapath, p->sslcrlfile); } } - for (AnyP::PortCfg *s = Config.Sockaddr.http; s != NULL; s = s->next) { + for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (!s->flags.tunnelSslBumping) continue; debugs(3, DBG_IMPORTANT, "Initializing http_port " << s->s << " SSL context"); s->configureSslServerContext(); } - for (AnyP::PortCfg *s = Config.Sockaddr.https; s != NULL; s = s->next) { + for (AnyP::PortCfgPointer s = HttpsPortList; s != NULL; s = s->next) { debugs(3, DBG_IMPORTANT, "Initializing https_port " << s->s << " SSL context"); s->configureSslServerContext(); } #endif // prevent infinite fetch loops in the request parser // due to buffer full but not enough data recived to finish parse if (Config.maxRequestBufferSize <= Config.maxRequestHeaderSize) { fatalf("Client request buffer of %u bytes cannot hold a request with %u bytes of headers." \ " Change client_request_buffer_max or request_header_max_size limits.", (uint32_t)Config.maxRequestBufferSize, (uint32_t)Config.maxRequestHeaderSize); } /* * Disable client side request pipelining if client_persistent_connections OFF. * Waste of resources queueing any pipelined requests when the first will close the connection. */ if (Config.pipeline_max_prefetch > 0 && !Config.onoff.client_pconns) { debugs(3, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: pipeline_prefetch " << Config.pipeline_max_prefetch << @@ -3498,41 +3498,41 @@ free_IpAddress_list(Ip::Address_list ** head) { if (*head) delete *head; *head = NULL; } #if CURRENTLY_UNUSED /* This code was previously used by http_port. Left as it really should * be used by icp_port and htcp_port */ static int check_null_IpAddress_list(const Ip::Address_list * s) { return NULL == s; } #endif /* CURRENTLY_UNUSED */ #endif /* USE_WCCPv2 */ static void -parsePortSpecification(AnyP::PortCfg * s, char *token) +parsePortSpecification(const AnyP::PortCfgPointer &s, char *token) { char *host = NULL; unsigned short port = 0; char *t = NULL; char *junk = NULL; s->disable_pmtu_discovery = DISABLE_PMTU_OFF; s->name = xstrdup(token); s->connection_auth_disabled = false; const char *portType = AnyP::UriScheme(s->transport.protocol).c_str(); if (*token == '[') { /* [ipv6]:port */ host = token + 1; t = strchr(host, ']'); if (!t) { debugs(3, DBG_CRITICAL, "FATAL: " << portType << "_port: missing ']' on IPv6 address: " << token); self_destruct(); } @@ -3575,41 +3575,41 @@ debugs(3, 3, portType << "_port: found Listen on wildcard address: *:" << s->s.port()); } else if ( (s->s = host) ) { /* check/parse numeric IPA */ s->s.port(port); if (!Ip::EnableIpv6) s->s.setIPv4(); debugs(3, 3, portType << "_port: Listen on Host/IP: " << host << " --> " << s->s); } else if ( s->s.GetHostByName(host) ) { /* check/parse for FQDN */ /* dont use ipcache */ s->defaultsite = xstrdup(host); s->s.port(port); if (!Ip::EnableIpv6) s->s.setIPv4(); debugs(3, 3, portType << "_port: found Listen as Host " << s->defaultsite << " on IP: " << s->s); } else { debugs(3, DBG_CRITICAL, "FATAL: " << portType << "_port: failed to resolve Host/IP: " << host); self_destruct(); } } static void -parse_port_option(AnyP::PortCfg * s, char *token) +parse_port_option(AnyP::PortCfgPointer &s, char *token) { /* modes first */ if (strcmp(token, "accel") == 0) { if (s->flags.isIntercepted()) { debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: Accelerator mode requires its own port. It cannot be shared with other modes."); self_destruct(); } s->flags.accelSurrogate = true; s->vhost = true; } else if (strcmp(token, "transparent") == 0 || strcmp(token, "intercept") == 0) { if (s->flags.accelSurrogate || s->flags.tproxyIntercept) { debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: Intercept mode requires its own interception port. It cannot be shared with other modes."); self_destruct(); } s->flags.natIntercept = true; Ip::Interceptor.StartInterception(); /* Log information regarding the port modes under interception. */ debugs(3, DBG_IMPORTANT, "Starting Authentication on port " << s->s); debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (interception enabled)"); @@ -3769,110 +3769,109 @@ safe_free(s->sslContextSessionId); s->sslContextSessionId = xstrdup(token + 11); } else if (strcmp(token, "generate-host-certificates") == 0) { s->generateHostCertificates = true; } else if (strcmp(token, "generate-host-certificates=on") == 0) { s->generateHostCertificates = true; } else if (strcmp(token, "generate-host-certificates=off") == 0) { s->generateHostCertificates = false; } else if (strncmp(token, "dynamic_cert_mem_cache_size=", 28) == 0) { parseBytesOptionValue(&s->dynamicCertMemCacheSize, B_BYTES_STR, token + 28); #endif } else { debugs(3, DBG_CRITICAL, "FATAL: Unknown http(s)_port option '" << token << "'."); self_destruct(); } } void add_http_port(char *portspec) { - AnyP::PortCfg *s = new AnyP::PortCfg(); + AnyP::PortCfgPointer s = new AnyP::PortCfg(); s->setTransport("HTTP"); parsePortSpecification(s, portspec); // we may need to merge better if the above returns a list with clones assert(s->next == NULL); - s->next = cbdataReference(Config.Sockaddr.http); - cbdataReferenceDone(Config.Sockaddr.http); - Config.Sockaddr.http = cbdataReference(s); + s->next = HttpPortList; + HttpPortList = s; } static void -parsePortCfg(AnyP::PortCfg ** head, const char *optionName) +parsePortCfg(AnyP::PortCfgPointer *head, const char *optionName) { const char *protocol = NULL; if (strcmp(optionName, "http_port") == 0 || strcmp(optionName, "ascii_port") == 0) protocol = "http"; else if (strcmp(optionName, "https_port") == 0) protocol = "https"; if (!protocol) { self_destruct(); return; } char *token = ConfigParser::NextToken(); if (!token) { self_destruct(); return; } - AnyP::PortCfg *s = new AnyP::PortCfg(); + AnyP::PortCfgPointer s = new AnyP::PortCfg(); s->setTransport(protocol); parsePortSpecification(s, token); /* parse options ... */ while ((token = ConfigParser::NextToken())) { parse_port_option(s, token); } #if USE_OPENSSL if (s->transport.protocol == AnyP::PROTO_HTTPS) { /* ssl-bump on https_port configuration requires either tproxy or intercept, and vice versa */ const bool hijacked = s->flags.isIntercepted(); if (s->flags.tunnelSslBumping && !hijacked) { debugs(3, DBG_CRITICAL, "FATAL: ssl-bump on https_port requires tproxy/intercept which is missing."); self_destruct(); } if (hijacked && !s->flags.tunnelSslBumping) { debugs(3, DBG_CRITICAL, "FATAL: tproxy/intercept on https_port requires ssl-bump which is missing."); self_destruct(); } } #endif if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && s->s.isAnyAddr()) { // clone the port options from *s to *(s->next) - s->next = cbdataReference(s->clone()); + s->next = s->clone(); s->next->s.setIPv4(); debugs(3, 3, AnyP::UriScheme(s->transport.protocol).c_str() << "_port: clone wildcard address for split-stack: " << s->s << " and " << s->next->s); } - while (*head) - head = &(*head)->next; + while (*head != NULL) + head = &((*head)->next); - *head = cbdataReference(s); + *head = s; } static void -dump_generic_port(StoreEntry * e, const char *n, const AnyP::PortCfg * s) +dump_generic_port(StoreEntry * e, const char *n, const AnyP::PortCfgPointer &s) { char buf[MAX_IPSTRLEN]; storeAppendPrintf(e, "%s %s", n, s->s.toUrl(buf,MAX_IPSTRLEN)); // MODES and specific sub-options. if (s->flags.natIntercept) storeAppendPrintf(e, " intercept"); else if (s->flags.tproxyIntercept) storeAppendPrintf(e, " tproxy"); else if (s->flags.accelSurrogate) { storeAppendPrintf(e, " accel"); if (s->vhost) storeAppendPrintf(e, " vhost"); @@ -3962,57 +3961,45 @@ storeAppendPrintf(e, " crlfile=%s", s->crlfile); if (s->dhfile) storeAppendPrintf(e, " dhparams=%s", s->dhfile); if (s->sslflags) storeAppendPrintf(e, " sslflags=%s", s->sslflags); if (s->sslContextSessionId) storeAppendPrintf(e, " sslcontext=%s", s->sslContextSessionId); if (s->generateHostCertificates) storeAppendPrintf(e, " generate-host-certificates"); if (s->dynamicCertMemCacheSize != std::numeric_limits::max()) storeAppendPrintf(e, "dynamic_cert_mem_cache_size=%lu%s\n", (unsigned long)s->dynamicCertMemCacheSize, B_BYTES_STR); #endif } static void -dump_PortCfg(StoreEntry * e, const char *n, const AnyP::PortCfg * s) +dump_PortCfg(StoreEntry * e, const char *n, const AnyP::PortCfgPointer &s) { - while (s) { - dump_generic_port(e, n, s); + for (AnyP::PortCfgPointer p = s; p != NULL; p = p->next) { + dump_generic_port(e, n, p); storeAppendPrintf(e, "\n"); - s = s->next; - } -} - -static void -free_PortCfg(AnyP::PortCfg ** head) -{ - AnyP::PortCfg *s; - - while ((s = *head) != NULL) { - *head = s->next; - cbdataReferenceDone(s); } } void configFreeMemory(void) { free_all(); #if USE_OPENSSL SSL_CTX_free(Config.ssl_client.sslContext); #endif } void requirePathnameExists(const char *name, const char *path) { struct stat sb; char pathbuf[BUFSIZ]; assert(path != NULL); === modified file 'src/cf.data.pre' --- src/cf.data.pre 2014-06-16 16:21:19 +0000 +++ src/cf.data.pre 2014-06-20 10:50:03 +0000 @@ -1479,41 +1479,41 @@ the size of your largest error page. If you set this parameter none (the default), there will be no limit imposed. Configuration Format is: reply_body_max_size SIZE UNITS [acl ...] ie. reply_body_max_size 10 MB DOC_END COMMENT_START NETWORK OPTIONS ----------------------------------------------------------------------------- COMMENT_END NAME: http_port ascii_port TYPE: PortCfg DEFAULT: none -LOC: Config.Sockaddr.http +LOC: HttpPortList DOC_START Usage: port [mode] [options] hostname:port [mode] [options] 1.2.3.4:port [mode] [options] The socket addresses where Squid will listen for HTTP client requests. You may specify multiple socket addresses. There are three forms: port alone, hostname with port, and IP address with port. If you specify a hostname or IP address, Squid binds the socket to that specific address. Most likely, you do not need to bind to a specific address, so you can use the port number alone. If you are running Squid in accelerator mode, you probably want to listen on port 80 also, or instead. The -a command line option may be used to specify additional port(s) where Squid listens for proxy request. Such ports will be plain proxy ports with no options. @@ -1716,41 +1716,41 @@ In seconds; idle is the initial time before TCP starts probing the connection, interval how often to probe, and timeout the time before giving up. If you run Squid on a dual-homed machine with an internal and an external interface we recommend you to specify the internal address:port in http_port. This way Squid will only be visible on the internal address. NOCOMMENT_START # Squid normally listens to port 3128 http_port @DEFAULT_HTTP_PORT@ NOCOMMENT_END DOC_END NAME: https_port IFDEF: USE_OPENSSL TYPE: PortCfg DEFAULT: none -LOC: Config.Sockaddr.https +LOC: HttpsPortList DOC_START Usage: [ip:]port cert=certificate.pem [key=key.pem] [mode] [options...] The socket address where Squid will listen for client requests made over TLS or SSL connections. Commonly referred to as HTTPS. This is most useful for situations where you are running squid in accelerator mode and you want to do the SSL work at the accelerator level. You may specify multiple socket addresses on multiple lines, each with their own SSL certificate and/or options. Modes: accel Accelerator / reverse proxy mode intercept Support for IP-Layer interception of outgoing requests without browser settings. NP: disables authentication and IPv6 on the port. === modified file 'src/client_side.cc' --- src/client_side.cc 2014-06-18 00:14:50 +0000 +++ src/client_side.cc 2014-06-21 11:49:17 +0000 @@ -144,62 +144,62 @@ #include "ssl/ServerBump.h" #include "ssl/support.h" #endif #if USE_SSL_CRTD #include "ssl/certificate_db.h" #include "ssl/crtd_message.h" #endif #include #include #include #if LINGERING_CLOSE #define comm_close comm_lingering_close #endif /// dials clientListenerConnectionOpened call class ListeningStartedDialer: public CallDialer, public Ipc::StartListeningCb { public: - typedef void (*Handler)(AnyP::PortCfg *portCfg, const Ipc::FdNoteId note, const Subscription::Pointer &sub); - ListeningStartedDialer(Handler aHandler, AnyP::PortCfg *aPortCfg, const Ipc::FdNoteId note, const Subscription::Pointer &aSub): + typedef void (*Handler)(AnyP::PortCfgPointer &portCfg, const Ipc::FdNoteId note, const Subscription::Pointer &sub); + ListeningStartedDialer(Handler aHandler, AnyP::PortCfgPointer &aPortCfg, const Ipc::FdNoteId note, const Subscription::Pointer &aSub): handler(aHandler), portCfg(aPortCfg), portTypeNote(note), sub(aSub) {} virtual void print(std::ostream &os) const { startPrint(os) << - ", " << FdNote(portTypeNote) << " port=" << (void*)portCfg << ')'; + ", " << FdNote(portTypeNote) << " port=" << (void*)&portCfg << ')'; } virtual bool canDial(AsyncCall &) const { return true; } virtual void dial(AsyncCall &) { (handler)(portCfg, portTypeNote, sub); } public: Handler handler; private: - AnyP::PortCfg *portCfg; ///< from Config.Sockaddr.http + AnyP::PortCfgPointer portCfg; ///< from HttpPortList Ipc::FdNoteId portTypeNote; ///< Type of IPC socket being opened Subscription::Pointer sub; ///< The handler to be subscribed for this connetion listener }; -static void clientListenerConnectionOpened(AnyP::PortCfg *s, const Ipc::FdNoteId portTypeNote, const Subscription::Pointer &sub); +static void clientListenerConnectionOpened(AnyP::PortCfgPointer &s, const Ipc::FdNoteId portTypeNote, const Subscription::Pointer &sub); /* our socket-related context */ CBDATA_CLASS_INIT(ClientSocketContext); /* Local functions */ static IOCB clientWriteComplete; static IOCB clientWriteBodyComplete; static IOACB httpAccept; #if USE_OPENSSL static IOACB httpsAccept; #endif static CTCB clientLifetimeTimeout; static ClientSocketContext *parseHttpRequestAbort(ConnStateData * conn, const char *uri); static ClientSocketContext *parseHttpRequest(ConnStateData *, HttpParser *, HttpRequestMethod *, Http::ProtocolVersion *); #if USE_IDENT static IDCB clientIdentDone; #endif static CSCB clientSocketRecipient; static CSD clientSocketDetach; @@ -861,42 +861,40 @@ bool ConnStateData::isOpen() const { return cbdataReferenceValid(this) && // XXX: checking "this" in a method Comm::IsConnOpen(clientConnection) && !fd_table[clientConnection->fd].closing(); } ConnStateData::~ConnStateData() { assert(this != NULL); debugs(33, 3, HERE << clientConnection); if (isOpen()) debugs(33, DBG_IMPORTANT, "BUG: ConnStateData did not close " << clientConnection); if (!flags.swanSang) debugs(33, DBG_IMPORTANT, "BUG: ConnStateData was not destroyed properly; " << clientConnection); - cbdataReferenceDone(port); - if (bodyPipe != NULL) stopProducingFor(bodyPipe, false); #if USE_OPENSSL delete sslServerBump; #endif } /** * clientSetKeepaliveFlag() sets request->flags.proxyKeepalive. * This is the client-side persistent connection flag. We need * to set this relatively early in the request processing * to handle hacks for broken servers and clients. */ static void clientSetKeepaliveFlag(ClientHttpRequest * http) { HttpRequest *request = http->request; debugs(33, 3, "http_ver = " << request->http_ver); @@ -2246,41 +2244,41 @@ /* Will the following be true with HTTP/0.9 requests? probably not .. */ /* So the rest of the code will need to deal with '0'-byte headers (ie, none, so don't try parsing em) */ assert(req_sz > 0); hp->hdr_end = req_sz - 1; hp->hdr_start = hp->req.end + 1; /* Enforce max_request_size */ if (req_sz >= Config.maxRequestHeaderSize) { debugs(33, 5, "parseHttpRequest: Too large request"); hp->request_parse_status = Http::scHeaderTooLarge; return parseHttpRequestAbort(csd, "error:request-too-large"); } /* Set method_p */ *method_p = HttpRequestMethod(&hp->buf[hp->req.m_start], &hp->buf[hp->req.m_end]+1); /* deny CONNECT via accelerated ports */ - if (*method_p == Http::METHOD_CONNECT && csd->port && csd->port->flags.accelSurrogate) { + if (*method_p == Http::METHOD_CONNECT && csd->port != NULL && csd->port->flags.accelSurrogate) { debugs(33, DBG_IMPORTANT, "WARNING: CONNECT method received on " << csd->port->transport.protocol << " Accelerator port " << csd->port->s.port()); /* XXX need a way to say "this many character length string" */ debugs(33, DBG_IMPORTANT, "WARNING: for request: " << hp->buf); hp->request_parse_status = Http::scMethodNotAllowed; return parseHttpRequestAbort(csd, "error:method-not-allowed"); } if (*method_p == Http::METHOD_NONE) { /* XXX need a way to say "this many character length string" */ debugs(33, DBG_IMPORTANT, "clientParseRequestMethod: Unsupported method in request '" << hp->buf << "'"); hp->request_parse_status = Http::scMethodNotAllowed; return parseHttpRequestAbort(csd, "error:unsupported-request-method"); } /* * Process headers after request line * TODO: Use httpRequestParse here. */ /* XXX this code should be modified to take a const char * later! */ req_hdr = (char *) hp->buf + hp->req.end + 1; @@ -3261,41 +3259,41 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) : AsyncJob("ConnStateData"), #if USE_OPENSSL sslBumpMode(Ssl::bumpEnd), switchedToHttps_(false), sslServerBump(NULL), #endif stoppedSending_(NULL), stoppedReceiving_(NULL) { pinning.host = NULL; pinning.port = -1; pinning.pinned = false; pinning.auth = false; pinning.zeroReply = false; pinning.peer = NULL; // store the details required for creating more MasterXaction objects as new requests come in clientConnection = xact->tcpClient; - port = cbdataReference(xact->squidPort.get()); + port = xact->squidPort; log_addr = xact->tcpClient->remote; log_addr.applyMask(Config.Addrs.client_netmask); // ensure a buffer is present for this connection in.maybeMakeSpaceAvailable(); if (port->disable_pmtu_discovery != DISABLE_PMTU_OFF && (transparent() || port->disable_pmtu_discovery == DISABLE_PMTU_ALWAYS)) { #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) int i = IP_PMTUDISC_DONT; if (setsockopt(clientConnection->fd, SOL_IP, IP_MTU_DISCOVER, &i, sizeof(i)) < 0) debugs(33, 2, "WARNING: Path MTU discovery disabling failed on " << clientConnection << " : " << xstrerror()); #else static bool reported = false; if (!reported) { debugs(33, DBG_IMPORTANT, "NOTICE: Path MTU discovery disabling is not supported on your platform."); reported = true; } #endif @@ -3313,41 +3311,41 @@ ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, NULL, NULL); identChecklist.src_addr = xact->tcpClient->remote; identChecklist.my_addr = xact->tcpClient->local; if (identChecklist.fastCheck() == ACCESS_ALLOWED) Ident::Start(xact->tcpClient, clientIdentDone, this); } #endif clientdbEstablished(clientConnection->remote, 1); flags.readMore = true; } /** Handle a new connection on HTTP socket. */ void httpAccept(const CommAcceptCbParams ¶ms) { MasterXaction::Pointer xact = params.xaction; AnyP::PortCfgPointer s = xact->squidPort; - if (!s.valid()) { + if (!s) { // it is possible the call or accept() was still queued when the port was reconfigured debugs(33, 2, "HTTP accept failure: port reconfigured."); return; } if (params.flag != Comm::OK) { // Its possible the call was still queued when the client disconnected debugs(33, 2, "httpAccept: " << s->listenConn << ": accept failure: " << xstrerr(params.xerrno)); return; } debugs(33, 4, HERE << params.conn << ": accepted"); fd_note(params.conn->fd, "client http connect"); if (s->tcp_keepalive.enabled) { commSetTcpKeepalive(params.conn->fd, s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout); } ++ incoming_sockets_accepted; @@ -4021,192 +4019,189 @@ return false; } return true; } /// find any unused HttpSockets[] slot and store fd there or return false static bool AddOpenedHttpSocket(const Comm::ConnectionPointer &conn) { bool found = false; for (int i = 0; i < NHttpSockets && !found; ++i) { if ((found = HttpSockets[i] < 0)) HttpSockets[i] = conn->fd; } return found; } static void clientHttpConnectionsOpen(void) { - AnyP::PortCfg *s = NULL; - - for (s = Config.Sockaddr.http; s; s = s->next) { + for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (MAXTCPLISTENPORTS == NHttpSockets) { debugs(1, DBG_IMPORTANT, "WARNING: You have too many 'http_port' lines."); debugs(1, DBG_IMPORTANT, " The limit is " << MAXTCPLISTENPORTS << " HTTP ports."); continue; } #if USE_OPENSSL if (s->flags.tunnelSslBumping && !Config.accessList.ssl_bump) { debugs(33, DBG_IMPORTANT, "WARNING: No ssl_bump configured. Disabling ssl-bump on " << AnyP::UriScheme(s->transport.protocol) << "_port " << s->s); s->flags.tunnelSslBumping = false; } if (s->flags.tunnelSslBumping && !s->staticSslContext && !s->generateHostCertificates) { debugs(1, DBG_IMPORTANT, "Will not bump SSL at http_port " << s->s << " due to SSL initialization failure."); s->flags.tunnelSslBumping = false; } if (s->flags.tunnelSslBumping) { // Create ssl_ctx cache for this port. Ssl::TheGlobalContextStorage.addLocalStorage(s->s, s->dynamicCertMemCacheSize == std::numeric_limits::max() ? 4194304 : s->dynamicCertMemCacheSize); } #endif // Fill out a Comm::Connection which IPC will open as a listener for us // then pass back when active so we can start a TcpAcceptor subscription. s->listenConn = new Comm::Connection; s->listenConn->local = s->s; s->listenConn->flags = COMM_NONBLOCKING | (s->flags.tproxyIntercept ? COMM_TRANSPARENT : 0) | (s->flags.natIntercept ? COMM_INTERCEPTION : 0); // setup the subscriptions such that new connections accepted by listenConn are handled by HTTP typedef CommCbFunPtrCallT AcceptCall; - RefCount subCall = commCbCall(5, 5, "httpAccept", CommAcceptCbPtrFun(httpAccept, s)); + RefCount subCall = commCbCall(5, 5, "httpAccept", CommAcceptCbPtrFun(httpAccept, CommAcceptCbParams(NULL))); Subscription::Pointer sub = new CallSubscription(subCall); AsyncCall::Pointer listenCall = asyncCall(33,2, "clientListenerConnectionOpened", ListeningStartedDialer(&clientListenerConnectionOpened, s, Ipc::fdnHttpSocket, sub)); Ipc::StartListening(SOCK_STREAM, IPPROTO_TCP, s->listenConn, Ipc::fdnHttpSocket, listenCall); HttpSockets[NHttpSockets] = -1; // set in clientListenerConnectionOpened ++NHttpSockets; } } #if USE_OPENSSL static void clientHttpsConnectionsOpen(void) { - AnyP::PortCfg *s; - - for (s = Config.Sockaddr.https; s; s = s->next) { + for (AnyP::POrtCfgPointer s = HttpsPortList; s != NULL; s = s->next) { if (MAXTCPLISTENPORTS == NHttpSockets) { debugs(1, DBG_IMPORTANT, "Ignoring 'https_port' lines exceeding the limit."); debugs(1, DBG_IMPORTANT, "The limit is " << MAXTCPLISTENPORTS << " HTTPS ports."); continue; } if (!s->staticSslContext) { debugs(1, DBG_IMPORTANT, "Ignoring https_port " << s->s << " due to SSL initialization failure."); continue; } // TODO: merge with similar code in clientHttpConnectionsOpen() if (s->flags.tunnelSslBumping && !Config.accessList.ssl_bump) { debugs(33, DBG_IMPORTANT, "WARNING: No ssl_bump configured. Disabling ssl-bump on " << AnyP::UriScheme(s->transport.protocol) << "_port " << s->s); s->flags.tunnelSslBumping = false; } if (s->flags.tunnelSslBumping && !s->staticSslContext && !s->generateHostCertificates) { debugs(1, DBG_IMPORTANT, "Will not bump SSL at http_port " << s->s << " due to SSL initialization failure."); s->flags.tunnelSslBumping = false; } if (s->flags.tunnelSslBumping) { // Create ssl_ctx cache for this port. Ssl::TheGlobalContextStorage.addLocalStorage(s->s, s->dynamicCertMemCacheSize == std::numeric_limits::max() ? 4194304 : s->dynamicCertMemCacheSize); } // Fill out a Comm::Connection which IPC will open as a listener for us s->listenConn = new Comm::Connection; s->listenConn->local = s->s; s->listenConn->flags = COMM_NONBLOCKING | (s->flags.tproxyIntercept ? COMM_TRANSPARENT : 0) | (s->flags.natIntercept ? COMM_INTERCEPTION : 0); // setup the subscriptions such that new connections accepted by listenConn are handled by HTTPS typedef CommCbFunPtrCallT AcceptCall; - RefCount subCall = commCbCall(5, 5, "httpsAccept", CommAcceptCbPtrFun(httpsAccept, s)); + RefCount subCall = commCbCall(5, 5, "httpsAccept", CommAcceptCbPtrFun(httpsAccept, CommAcceptCbParams(NULL))); Subscription::Pointer sub = new CallSubscription(subCall); AsyncCall::Pointer listenCall = asyncCall(33, 2, "clientListenerConnectionOpened", ListeningStartedDialer(&clientListenerConnectionOpened, s, Ipc::fdnHttpsSocket, sub)); Ipc::StartListening(SOCK_STREAM, IPPROTO_TCP, s->listenConn, Ipc::fdnHttpsSocket, listenCall); HttpSockets[NHttpSockets] = -1; ++NHttpSockets; } } #endif /// process clientHttpConnectionsOpen result static void -clientListenerConnectionOpened(AnyP::PortCfg *s, const Ipc::FdNoteId portTypeNote, const Subscription::Pointer &sub) +clientListenerConnectionOpened(AnyP::PortCfgPointer &s, const Ipc::FdNoteId portTypeNote, const Subscription::Pointer &sub) { + Must(s != NULL); + if (!OpenedHttpSocket(s->listenConn, portTypeNote)) return; - Must(s); Must(Comm::IsConnOpen(s->listenConn)); // TCP: setup a job to handle accept() with subscribed handler - AsyncJob::Start(new Comm::TcpAcceptor(s->listenConn, FdNote(portTypeNote), sub)); + AsyncJob::Start(new Comm::TcpAcceptor(s, FdNote(portTypeNote), sub)); debugs(1, DBG_IMPORTANT, "Accepting " << (s->flags.natIntercept ? "NAT intercepted " : "") << (s->flags.tproxyIntercept ? "TPROXY intercepted " : "") << (s->flags.tunnelSslBumping ? "SSL bumped " : "") << (s->flags.accelSurrogate ? "reverse-proxy " : "") << FdNote(portTypeNote) << " connections at " << s->listenConn); Must(AddOpenedHttpSocket(s->listenConn)); // otherwise, we have received a fd we did not ask for } void clientOpenListenSockets(void) { clientHttpConnectionsOpen(); #if USE_OPENSSL clientHttpsConnectionsOpen(); #endif if (NHttpSockets < 1) fatal("No HTTP or HTTPS ports configured"); } void clientHttpConnectionsClose(void) { - for (AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) { + for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (s->listenConn != NULL) { debugs(1, DBG_IMPORTANT, "Closing HTTP port " << s->listenConn->local); s->listenConn->close(); s->listenConn = NULL; } } #if USE_OPENSSL - for (AnyP::PortCfg *s = Config.Sockaddr.https; s; s = s->next) { + for (AnyP::PortCfgPointer s = HttpsPortList; s != NULL; s = s->next) { if (s->listenConn != NULL) { debugs(1, DBG_IMPORTANT, "Closing HTTPS port " << s->listenConn->local); s->listenConn->close(); s->listenConn = NULL; } } #endif // TODO see if we can drop HttpSockets array entirely */ for (int i = 0; i < NHttpSockets; ++i) { HttpSockets[i] = -1; } NHttpSockets = 0; } int varyEvaluateMatch(StoreEntry * entry, HttpRequest * request) { const char *vary = request->vary_headers; === modified file 'src/client_side.h' --- src/client_side.h 2014-06-05 14:57:58 +0000 +++ src/client_side.h 2014-06-20 04:26:48 +0000 @@ -252,41 +252,41 @@ Ip::Address log_addr; int nrequests; struct { bool readMore; ///< needs comm_read (for this request or new requests) bool swanSang; // XXX: temporary flag to check proper cleanup } flags; struct { Comm::ConnectionPointer serverConnection; /* pinned server side connection */ char *host; /* host name of pinned connection */ int port; /* port of pinned connection */ bool pinned; /* this connection was pinned */ bool auth; /* pinned for www authentication */ bool zeroReply; ///< server closed w/o response (ERR_ZERO_SIZE_OBJECT) CachePeer *peer; /* CachePeer the connection goes via */ AsyncCall::Pointer readHandler; ///< detects serverConnection closure AsyncCall::Pointer closeHandler; /*The close handler for pinned server side connection*/ } pinning; /// Squid listening port details where this connection arrived. - AnyP::PortCfg *port; + AnyP::PortCfgPointer port; bool transparent() const; bool reading() const; void stopReading(); ///< cancels comm_read if it is scheduled /// true if we stopped receiving the request const char *stoppedReceiving() const { return stoppedReceiving_; } /// true if we stopped sending the response const char *stoppedSending() const { return stoppedSending_; } /// note request receiving error and close as soon as we write the response void stopReceiving(const char *error); /// note response sending error and close as soon as we read the request void stopSending(const char *error); void expectNoForwarding(); ///< cleans up virgin request [body] forwarding state BodyPipe::Pointer expectRequestBody(int64_t size); virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer); virtual void noteBodyConsumerAborted(BodyPipe::Pointer); === modified file 'src/client_side_request.cc' --- src/client_side_request.cc 2014-06-05 14:57:58 +0000 +++ src/client_side_request.cc 2014-06-20 04:33:27 +0000 @@ -147,41 +147,41 @@ no_cache_done = false; interpreted_req_hdrs = false; #if USE_OPENSSL sslBumpCheckDone = false; #endif debugs(85,3, HERE << this << " ClientRequestContext constructed"); } CBDATA_CLASS_INIT(ClientHttpRequest); ClientHttpRequest::ClientHttpRequest(ConnStateData * aConn) : #if USE_ADAPTATION AsyncJob("ClientHttpRequest"), #endif loggingEntry_(NULL) { setConn(aConn); al = new AccessLogEntry; al->cache.start_time = current_time; al->tcpClient = clientConnection = aConn->clientConnection; - al->cache.port = cbdataReference(aConn->port); + al->cache.port = aConn->port; al->cache.caddr = aConn->log_addr; #if USE_OPENSSL if (aConn->clientConnection != NULL && aConn->clientConnection->isOpen()) { if (SSL *ssl = fd_table[aConn->clientConnection->fd].ssl) al->cache.sslClientCert.reset(SSL_get_peer_certificate(ssl)); } #endif dlinkAdd(this, &active, &ClientActiveRequests); #if USE_ADAPTATION request_satisfaction_mode = false; #endif #if USE_OPENSSL sslBumpNeed_ = Ssl::bumpEnd; #endif } /* * returns true if client specified that the object must come from the cache * without contacting origin server === modified file 'src/comm/ModPoll.cc' --- src/comm/ModPoll.cc 2014-06-09 13:18:48 +0000 +++ src/comm/ModPoll.cc 2014-06-20 10:53:01 +0000 @@ -179,41 +179,41 @@ return 1; return 0; } static int fdIsDns(int fd) { if (fd == DnsSocketA) return 1; if (fd == DnsSocketB) return 1; return 0; } static int fdIsTcpListen(int fd) { - for (const AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) { + for (const AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (s->listenConn != NULL && s->listenConn->fd == fd) return 1; } return 0; } static int comm_check_incoming_poll_handlers(int nfds, int *fds) { int i; int fd; PF *hdl = NULL; int npfds; struct pollfd pfds[3 + MAXTCPLISTENPORTS]; PROF_start(comm_check_incoming); incoming_sockets_accepted = 0; for (i = npfds = 0; i < nfds; ++i) { === modified file 'src/comm/ModSelect.cc' --- src/comm/ModSelect.cc 2014-06-09 13:18:48 +0000 +++ src/comm/ModSelect.cc 2014-06-22 11:14:39 +0000 @@ -180,41 +180,41 @@ return 1; return 0; } static int fdIsDns(int fd) { if (fd == DnsSocketA) return 1; if (fd == DnsSocketB) return 1; return 0; } static int fdIsTcpListener(int fd) { - for (const AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) { + for (const AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (s->listenConn != NULL && s->listenConn->fd == fd) return 1; } return 0; } static int comm_check_incoming_select_handlers(int nfds, int *fds) { int i; int fd; int maxfd = 0; PF *hdl = NULL; fd_set read_mask; fd_set write_mask; FD_ZERO(&read_mask); FD_ZERO(&write_mask); incoming_sockets_accepted = 0; @@ -303,41 +303,41 @@ if (incoming_udp_interval > MAX_INCOMING_INTERVAL) incoming_udp_interval = MAX_INCOMING_INTERVAL; if (nevents > INCOMING_UDP_MAX) nevents = INCOMING_UDP_MAX; statCounter.comm_udp_incoming.count(nevents); } static void comm_select_tcp_incoming(void) { int nfds = 0; int fds[MAXTCPLISTENPORTS]; int nevents; tcp_io_events = 0; // XXX: only poll sockets that won't be deferred. But how do we identify them? - for (const AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) { + for (const AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (Comm::IsConnOpen(s->listenConn)) { fds[nfds] = s->listenConn->fd; ++nfds; } } nevents = comm_check_incoming_select_handlers(nfds, fds); incoming_tcp_interval += Config.comm_incoming.tcp.average - nevents; if (incoming_tcp_interval < 0) incoming_tcp_interval = 0; if (incoming_tcp_interval > MAX_INCOMING_INTERVAL) incoming_tcp_interval = MAX_INCOMING_INTERVAL; if (nevents > INCOMING_TCP_MAX) nevents = INCOMING_TCP_MAX; statCounter.comm_tcp_incoming.count(nevents); } === modified file 'src/comm/ModSelectWin32.cc' --- src/comm/ModSelectWin32.cc 2014-06-09 13:18:48 +0000 +++ src/comm/ModSelectWin32.cc 2014-06-20 10:53:38 +0000 @@ -174,41 +174,41 @@ return 1; return 0; } static int fdIsDns(int fd) { if (fd == DnsSocketA) return 1; if (fd == DnsSocketB) return 1; return 0; } static int fdIsTcpListener(int fd) { - for (const AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) { + for (const AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (s->listenConn != NULL && s->listenConn->fd == fd) return 1; } return 0; } static int comm_check_incoming_select_handlers(int nfds, int *fds) { int i; int fd; int maxfd = 0; PF *hdl = NULL; fd_set read_mask; fd_set write_mask; fd_set errfds; FD_ZERO(&errfds); FD_ZERO(&read_mask); FD_ZERO(&write_mask); @@ -300,41 +300,41 @@ if (incoming_udp_interval > MAX_INCOMING_INTERVAL) incoming_udp_interval = MAX_INCOMING_INTERVAL; if (nevents > INCOMING_UDP_MAX) nevents = INCOMING_UDP_MAX; statCounter.comm_udp_incoming.count(nevents); } static void comm_select_tcp_incoming(void) { int nfds = 0; int fds[MAXTCPLISTENPORTS]; int nevents; tcp_io_events = 0; // XXX: only poll sockets that won't be deferred. But how do we identify them? - for (const AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) { + for (const AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (Comm::IsConnOpen(s->listenConn)) { fds[nfds] = s->listenConn->fd; ++nfds; } } nevents = comm_check_incoming_select_handlers(nfds, fds); incoming_tcp_interval += Config.comm_incoming.tcp_average - nevents; if (incoming_tcp_interval < 0) incoming_tcp_interval = 0; if (incoming_tcp_interval > MAX_INCOMING_INTERVAL) incoming_tcp_interval = MAX_INCOMING_INTERVAL; if (nevents > INCOMING_TCP_MAX) nevents = INCOMING_TCP_MAX; statCounter.comm_tcp_incoming.count(nevents); } === modified file 'src/comm/TcpAcceptor.cc' --- src/comm/TcpAcceptor.cc 2014-06-09 13:18:48 +0000 +++ src/comm/TcpAcceptor.cc 2014-06-21 11:53:46 +0000 @@ -49,41 +49,51 @@ #include "ip/Intercept.h" #include "MasterXaction.h" #include "profiler/Profiler.h" #include "SquidConfig.h" #include "SquidTime.h" #include "StatCounters.h" #include #ifdef HAVE_NETINET_TCP_H // required for accept_filter to build. #include #endif CBDATA_NAMESPACED_CLASS_INIT(Comm, TcpAcceptor); Comm::TcpAcceptor::TcpAcceptor(const Comm::ConnectionPointer &newConn, const char *note, const Subscription::Pointer &aSub) : AsyncJob("Comm::TcpAcceptor"), errcode(0), isLimited(0), theCallSub(aSub), - conn(newConn) + conn(newConn), + listenPort_() +{} + +Comm::TcpAcceptor::TcpAcceptor(const AnyP::PortCfgPointer &p, const char *note, const Subscription::Pointer &aSub) : + AsyncJob("Comm::TcpAcceptor"), + errcode(0), + isLimited(0), + theCallSub(aSub), + conn(p->listenConn), + listenPort_(p) {} void Comm::TcpAcceptor::subscribe(const Subscription::Pointer &aSub) { debugs(5, 5, HERE << status() << " AsyncCall Subscription: " << aSub); unsubscribe("subscription change"); theCallSub = aSub; } void Comm::TcpAcceptor::unsubscribe(const char *reason) { debugs(5, 5, HERE << status() << " AsyncCall Subscription " << theCallSub << " removed: " << reason); theCallSub = NULL; } void Comm::TcpAcceptor::start() { @@ -290,41 +300,41 @@ Comm::TcpAcceptor::acceptNext() { Must(IsConnOpen(conn)); debugs(5, 2, HERE << "connection on " << conn); acceptOne(); } void Comm::TcpAcceptor::notify(const Comm::Flag flag, const Comm::ConnectionPointer &newConnDetails) const { // listener socket handlers just abandon the port with Comm::ERR_CLOSING // it should only happen when this object is deleted... if (flag == Comm::ERR_CLOSING) { return; } if (theCallSub != NULL) { AsyncCall::Pointer call = theCallSub->callback(); CommAcceptCbParams ¶ms = GetCommParams(call); params.xaction = new MasterXaction; - params.xaction->squidPort = static_cast(params.data); + params.xaction->squidPort = listenPort_; params.fd = conn->fd; params.conn = params.xaction->tcpClient = newConnDetails; params.flag = flag; params.xerrno = errcode; ScheduleCallHere(call); } } /** * accept() and process * Wait for an incoming connection on our listener socket. * * \retval Comm::OK success. details parameter filled. * \retval Comm::NOMESSAGE attempted accept() but nothing useful came in. * \retval Comm::COMM_ERROR an outright failure occured. * Or if this client has too many connections already. */ Comm::Flag Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details) { === modified file 'src/comm/TcpAcceptor.h' --- src/comm/TcpAcceptor.h 2014-06-05 14:57:58 +0000 +++ src/comm/TcpAcceptor.h 2014-06-21 11:52:52 +0000 @@ -1,97 +1,102 @@ #ifndef SQUID_COMM_TCPACCEPTOR_H #define SQUID_COMM_TCPACCEPTOR_H +#include "anyp/forward.h" #include "base/AsyncJob.h" #include "base/CbcPointer.h" #include "base/Subscription.h" #include "comm/Flag.h" #include "comm/forward.h" class CommCloseCbParams; namespace Comm { class AcceptLimiter; /** * Listens on a Comm::Connection for new incoming connections and * emits an active Comm::Connection descriptor for the new client. * * Handles all event limiting required to quash inbound connection * floods within the global FD limits of available Squid_MaxFD and * client_ip_max_connections. * * Fills the emitted connection with all connection details able to * be looked up. Currently these are the local/remote IP:port details * and the listening socket transparent-mode flag. */ class TcpAcceptor : public AsyncJob { public: typedef CbcPointer Pointer; private: virtual void start(); virtual bool doneAll() const; virtual void swanSong(); virtual const char *status() const; TcpAcceptor(const TcpAcceptor &); // not implemented. public: TcpAcceptor(const Comm::ConnectionPointer &conn, const char *note, const Subscription::Pointer &aSub); + TcpAcceptor(const AnyP::PortCfgPointer &listenPort, const char *note, const Subscription::Pointer &aSub); /** Subscribe a handler to receive calls back about new connections. * Unsubscribes any existing subscribed handler. */ void subscribe(const Subscription::Pointer &aSub); /** Remove the currently waiting callback subscription. * Already scheduled callbacks remain scheduled. */ void unsubscribe(const char *reason); /** Try and accept another connection (synchronous). * If one is pending already the subscribed callback handler will be scheduled * to handle it before this method returns. */ void acceptNext(); /// Call the subscribed callback handler with details about a new connection. void notify(const Comm::Flag flag, const Comm::ConnectionPointer &details) const; /// errno code of the last accept() or listen() action if one occurred. int errcode; protected: friend class AcceptLimiter; int32_t isLimited; ///< whether this socket is delayed and on the AcceptLimiter queue. private: Subscription::Pointer theCallSub; ///< used to generate AsyncCalls handling our events. /// conn being listened on for new connections /// Reserved for read-only use. ConnectionPointer conn; + /// configuration details of the listening port (if provided) + AnyP::PortCfgPointer listenPort_; + /// listen socket closure handler AsyncCall::Pointer closer_; /// Method to test if there are enough file descriptors to open a new client connection /// if not the accept() will be postponed static bool okToAccept(); /// Method callback for whenever an FD is ready to accept a client connection. static void doAccept(int fd, void *data); void acceptOne(); Comm::Flag oldAccept(Comm::ConnectionPointer &details); void setListen(); void handleClosure(const CommCloseCbParams &io); CBDATA_CLASS2(TcpAcceptor); }; } // namespace Comm === modified file 'src/format/Format.cc' --- src/format/Format.cc 2014-05-13 10:27:18 +0000 +++ src/format/Format.cc 2014-06-20 07:28:46 +0000 @@ -367,73 +367,73 @@ if (al->hier.tcpServer != NULL) { out = al->hier.tcpServer->remote.toStr(tmp,sizeof(tmp)); } break; case LFT_SERVER_FQDN_OR_PEER_NAME: out = al->hier.host; break; case LFT_SERVER_PORT: if (al->hier.tcpServer != NULL) { outint = al->hier.tcpServer->remote.port(); doint = 1; } break; case LFT_LOCAL_LISTENING_IP: { // avoid logging a dash if we have reliable info const bool interceptedAtKnownPort = al->request ? (al->request->flags.interceptTproxy || - al->request->flags.intercepted) && al->cache.port : + al->request->flags.intercepted) && al->cache.port != NULL : false; if (interceptedAtKnownPort) { const bool portAddressConfigured = !al->cache.port->s.isAnyAddr(); if (portAddressConfigured) out = al->cache.port->s.toStr(tmp, sizeof(tmp)); } else if (al->tcpClient != NULL) out = al->tcpClient->local.toStr(tmp, sizeof(tmp)); } break; case LFT_CLIENT_LOCAL_IP: if (al->tcpClient != NULL) { out = al->tcpClient->local.toStr(tmp,sizeof(tmp)); } break; case LFT_CLIENT_LOCAL_TOS: if (al->tcpClient != NULL) { snprintf(tmp, sizeof(tmp), "0x%x", (uint32_t)al->tcpClient->tos); out = tmp; } break; case LFT_CLIENT_LOCAL_NFMARK: if (al->tcpClient != NULL) { snprintf(tmp, sizeof(tmp), "0x%x", al->tcpClient->nfmark); out = tmp; } break; case LFT_LOCAL_LISTENING_PORT: - if (al->cache.port) { + if (al->cache.port != NULL) { outint = al->cache.port->s.port(); doint = 1; } break; case LFT_CLIENT_LOCAL_PORT: if (al->tcpClient != NULL) { outint = al->tcpClient->local.port(); doint = 1; } break; case LFT_SERVER_LOCAL_IP_OLD_27: case LFT_SERVER_LOCAL_IP: if (al->hier.tcpServer != NULL) { out = al->hier.tcpServer->local.toStr(tmp,sizeof(tmp)); } break; case LFT_SERVER_LOCAL_PORT: === modified file 'src/neighbors.cc' --- src/neighbors.cc 2014-06-05 14:57:58 +0000 +++ src/neighbors.cc 2014-06-20 10:53:56 +0000 @@ -566,41 +566,41 @@ } void neighbors_init(void) { struct servent *sep = NULL; const char *me = getMyHostname(); CachePeer *thisPeer = NULL; CachePeer *next = NULL; neighborsRegisterWithCacheManager(); if (Comm::IsConnOpen(icpIncomingConn)) { for (thisPeer = Config.peers; thisPeer; thisPeer = next) { next = thisPeer->next; if (0 != strcmp(thisPeer->host, me)) continue; - for (AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) { + for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (thisPeer->http_port != s->s.port()) continue; debugs(15, DBG_IMPORTANT, "WARNING: Peer looks like this host"); debugs(15, DBG_IMPORTANT, " Ignoring " << neighborTypeStr(thisPeer) << " " << thisPeer->host << "/" << thisPeer->http_port << "/" << thisPeer->icp.port); neighborRemove(thisPeer); } } } peerRefreshDNS((void *) 1); sep = getservbyname("echo", "udp"); echo_port = sep ? ntohs((unsigned short) sep->s_port) : 7; === modified file 'src/send-announce.cc' --- src/send-announce.cc 2013-06-03 14:05:16 +0000 +++ src/send-announce.cc 2014-06-21 15:22:52 +0000 @@ -14,40 +14,41 @@ * incorporates software developed and/or copyrighted by other * sources; see the CREDITS file for full details. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */ #include "squid.h" +#include "anyp/PortCfg.h" #include "comm/Connection.h" #include "disk.h" #include "event.h" #include "fd.h" #include "fde.h" #include "globals.h" #include "ICP.h" #include "ipcache.h" #include "SquidConfig.h" #include "SquidTime.h" #include "tools.h" static IPH send_announce; void start_announce(void *datanotused) { if (0 == Config.onoff.announce) return; @@ -64,41 +65,41 @@ { LOCAL_ARRAY(char, tbuf, 256); LOCAL_ARRAY(char, sndbuf, BUFSIZ); char *host = Config.Announce.host; char *file = NULL; unsigned short port = Config.Announce.port; int l; int n; int fd; if (ia == NULL) { debugs(27, DBG_IMPORTANT, "send_announce: Unknown host '" << host << "'"); return; } debugs(27, DBG_IMPORTANT, "Sending Announcement to " << host); sndbuf[0] = '\0'; snprintf(tbuf, 256, "cache_version SQUID/%s\n", version_string); strcat(sndbuf, tbuf); - assert(Config.Sockaddr.http); + assert(HttpPortList != NULL); snprintf(tbuf, 256, "Running on %s %d %d\n", getMyHostname(), getMyPort(), (int) Config.Port.icp); strcat(sndbuf, tbuf); if (Config.adminEmail) { snprintf(tbuf, 256, "cache_admin: %s\n", Config.adminEmail); strcat(sndbuf, tbuf); } snprintf(tbuf, 256, "generated %d [%s]\n", (int) squid_curtime, Time::FormatHttpd(squid_curtime)); strcat(sndbuf, tbuf); l = strlen(sndbuf); if ((file = Config.Announce.file) != NULL) { fd = file_open(file, O_RDONLY | O_TEXT); === modified file 'src/ssl/helper.cc' --- src/ssl/helper.cc 2013-10-25 00:13:46 +0000 +++ src/ssl/helper.cc 2014-06-20 10:55:37 +0000 @@ -16,43 +16,43 @@ { static Ssl::Helper sslHelper; return &sslHelper; } Ssl::Helper::Helper() : ssl_crtd(NULL) { } Ssl::Helper::~Helper() { Shutdown(); } void Ssl::Helper::Init() { assert(ssl_crtd == NULL); // we need to start ssl_crtd only if some port(s) need to bump SSL bool found = false; - for (AnyP::PortCfg *s = ::Config.Sockaddr.http; !found && s; s = s->next) + for (AnyP::PortCfgPointer s = HttpPortList; !found && s != NULL; s = s->next) found = s->flags.tunnelSslBumping; - for (AnyP::PortCfg *s = ::Config.Sockaddr.https; !found && s; s = s->next) + for (AnyP::PortCfgPointer s = HttpsPortList; !found && s != NULL; s = s->next) found = s->flags.tunnelSslBumping; if (!found) return; ssl_crtd = new helper("ssl_crtd"); ssl_crtd->childs.updateLimits(Ssl::TheConfig.ssl_crtdChildren); ssl_crtd->ipc_type = IPC_STREAM; // The crtd messages may contain the eol ('\n') character. We are // going to use the '\1' char as the end-of-message mark. ssl_crtd->eom = '\1'; assert(ssl_crtd->cmdline == NULL); { char *tmp = xstrdup(Ssl::TheConfig.ssl_crtd); char *tmp_begin = tmp; char * token = NULL; bool db_path_was_found = false; bool block_size_was_found = false; char buffer[20] = "2048"; while ((token = strwordtok(NULL, &tmp))) { wordlistAdd(&ssl_crtd->cmdline, token); @@ -117,43 +117,43 @@ if (!Ssl::TheConfig.ssl_crt_validator) return NULL; return &sslHelper; } Ssl::CertValidationHelper::CertValidationHelper() : ssl_crt_validator(NULL) { } Ssl::CertValidationHelper::~CertValidationHelper() { Shutdown(); } void Ssl::CertValidationHelper::Init() { assert(ssl_crt_validator == NULL); // we need to start ssl_crtd only if some port(s) need to bump SSL bool found = false; - for (AnyP::PortCfg *s = ::Config.Sockaddr.http; !found && s; s = s->next) + for (AnyP::PortCfgPointer s = HttpPortList; !found && s != NULL; s = s->next) found = s->flags.tunnelSslBumping; - for (AnyP::PortCfg *s = ::Config.Sockaddr.https; !found && s; s = s->next) + for (AnyP::PortCfgPointer s = HttpsPortList; !found && s != NULL; s = s->next) found = s->flags.tunnelSslBumping; if (!found) return; ssl_crt_validator = new helper("ssl_crt_validator"); ssl_crt_validator->childs.updateLimits(Ssl::TheConfig.ssl_crt_validator_Children); ssl_crt_validator->ipc_type = IPC_STREAM; // The crtd messages may contain the eol ('\n') character. We are // going to use the '\1' char as the end-of-message mark. ssl_crt_validator->eom = '\1'; assert(ssl_crt_validator->cmdline == NULL); int ttl = 60; size_t cache = 2048; { char *tmp = xstrdup(Ssl::TheConfig.ssl_crt_validator); char *tmp_begin = tmp; char * token = NULL; bool parseParams = true; while ((token = strwordtok(NULL, &tmp))) { === modified file 'src/ssl/support.cc' --- src/ssl/support.cc 2014-06-02 07:19:35 +0000 +++ src/ssl/support.cc 2014-06-20 10:56:43 +0000 @@ -1757,80 +1757,80 @@ // the reference count is not incremented and therefore the session must // not be explicitly freed with SSL_SESSION_free(3). *copy = 0; return session; } static void setSessionCallbacks(SSL_CTX *ctx) { if (SslSessionCache) { SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL); SSL_CTX_sess_set_new_cb(ctx, store_session_cb); SSL_CTX_sess_set_remove_cb(ctx, remove_session_cb); SSL_CTX_sess_set_get_cb(ctx, get_session_cb); } } static bool isSslServer() { - if (Config.Sockaddr.https) + if (HttpsPortList.valid()) return true; - for (AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) { + for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (s->flags.tunnelSslBumping) return true; } return false; } #define SSL_SESSION_ID_SIZE 32 #define SSL_SESSION_MAX_SIZE 10*1024 void Ssl::initialize_session_cache() { if (!isSslServer()) //no need to configure ssl session cache. return; // Check if the MemMap keys and data are enough big to hold // session ids and session data assert(SSL_SESSION_ID_SIZE >= MEMMAP_SLOT_KEY_SIZE); assert(SSL_SESSION_MAX_SIZE >= MEMMAP_SLOT_DATA_SIZE); int configuredItems = ::Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot); if (IamWorkerProcess() && configuredItems) SslSessionCache = new Ipc::MemMap(SslSessionCacheName); else { SslSessionCache = NULL; return; } - for (AnyP::PortCfg *s = ::Config.Sockaddr.https; s; s = s->next) { + for (AnyP::PortCfgPointer s = HttpsPortList; s != NULL; s = s->next) { if (s->staticSslContext.get() != NULL) setSessionCallbacks(s->staticSslContext.get()); } - for (AnyP::PortCfg *s = ::Config.Sockaddr.http; s; s = s->next) { + for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (s->staticSslContext.get() != NULL) setSessionCallbacks(s->staticSslContext.get()); } } void destruct_session_cache() { delete SslSessionCache; } /// initializes shared memory segments used by MemStore class SharedSessionCacheRr: public Ipc::Mem::RegisteredRunner { public: /* RegisteredRunner API */ SharedSessionCacheRr(): owner(NULL) {} virtual void useConfig(); virtual ~SharedSessionCacheRr(); === modified file 'src/tools.cc' --- src/tools.cc 2014-06-02 07:19:35 +0000 +++ src/tools.cc 2014-06-22 09:16:43 +0000 @@ -460,47 +460,47 @@ { shutting_down = 1; } const char * getMyHostname(void) { LOCAL_ARRAY(char, host, SQUIDHOSTNAMELEN + 1); static int present = 0; struct addrinfo *AI = NULL; Ip::Address sa; if (Config.visibleHostname != NULL) return Config.visibleHostname; if (present) return host; host[0] = '\0'; - if (Config.Sockaddr.http && sa.isAnyAddr()) - sa = Config.Sockaddr.http->s; + if (HttpPortList != NULL && sa.isAnyAddr()) + sa = HttpPortList->s; #if USE_OPENSSL - if (Config.Sockaddr.https && sa.isAnyAddr()) - sa = Config.Sockaddr.https->s; + if (HttpsPortList != NULL && sa.isAnyAddr()) + sa = HttpsPortList->s; #endif /* * If the first http_port address has a specific address, try a * reverse DNS lookup on it. */ if ( !sa.isAnyAddr() ) { sa.getAddrInfo(AI); /* we are looking for a name. */ if (getnameinfo(AI->ai_addr, AI->ai_addrlen, host, SQUIDHOSTNAMELEN, NULL, 0, NI_NAMEREQD ) == 0) { /* DNS lookup successful */ /* use the official name from DNS lookup */ debugs(50, 4, "getMyHostname: resolved " << sa << " to '" << host << "'"); present = 1; Ip::Address::FreeAddrInfo(AI); @@ -1114,55 +1114,55 @@ hosts = NULL; break; } wordlistAdd(&hosts, host); lt = nt + 1; } if (hosts) { fqdncacheAddEntryFromHosts(addr, hosts); wordlistDestroy(&hosts); } } fclose (fp); } int getMyPort(void) { - AnyP::PortCfg *p = NULL; - if ((p = Config.Sockaddr.http)) { + AnyP::PortCfgPointer p; + if ((p = HttpPortList) != NULL) { // skip any special interception ports - while (p && p->flags.isIntercepted()) + while (p != NULL && p->flags.isIntercepted()) p = p->next; - if (p) + if (p != NULL) return p->s.port(); } #if USE_OPENSSL - if ((p = Config.Sockaddr.https)) { + if ((p = HttpsPortList) != NULL) { // skip any special interception ports - while (p && p->flags.isIntercepted()) + while (p != NULL && p->flags.isIntercepted()) p = p->next; - if (p) + if (p != NULL) return p->s.port(); } #endif debugs(21, DBG_CRITICAL, "ERROR: No forward-proxy ports configured."); return 0; // Invalid port. This will result in invalid URLs on bad configurations. } /* * Set the umask to at least the given mask. This is in addition * to the umask set at startup */ void setUmask(mode_t mask) { // No way to get the current umask value without setting it. static const mode_t orig_umask = umask(mask); // once, to get umask(mask | orig_umask); // always, to set }