From: Amos Jeffries Date: Fri, 17 Jun 2011 16:32:04 +0000 (+1200) Subject: Upgrade comm layer Connection handling X-Git-Tag: take08~55^2~124 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1c8f25b;p=thirdparty%2Fsquid.git Upgrade comm layer Connection handling The premise underlying this large patch is that instead of copying and re-copying and re-lookups for the FD related data we can take the ConnectionDetail class which is generated to store a few bits of IP information about newly accept()'d connections and make it persist across the whole of Squid. It has been renamed from ConnectionDetails to Comm::Connection and has absorbed a few FD data fields from other classes long the code paths. Its scope is to hold an FD (or potential FD) plus meta data. Comm::Connection are valid before, during and after the period when their particular FD is open. The meta data may be used beforehand to setup the FD (in the case of peer selection or other TcpAcceptor usage), and it may remain in use after FD closure until logging or all linked job and call objects have detected the closure and terminated. A global function Comm::IsConnOpen() may be used on the pointer objects to detect whether they point at an active connection. Most of the patch is simple parameter changes to functions and methods to pass a "cont Comm::ConnectionPointer &" instead of an "int FD". Along with class FD fields being converted to these object pointers. In order to support this alteration there have been behavioral changes to: The socket accept() Job Comm::TcpAcceptor altered to spawn Comm::Connection objects and to operate with one controlling their active/closed state. FTP data channel handling Calls. efficiency improvements making use of Comm::Connection as a feedback channel between TcpAcceptor and FtpStateData to cancel the listening Job. Most of the underlying logic change is already in trunk to use the Subscription API. This just streamlines and fixes some race bugs. Peer selection updated to spawn a set of Comm::Connection objects. To do this it is updated to determine *all* peers including DIRECT ones. Doing the DNS lookup instead of leaving it to comm_connect() on the other side of FwdState. It also absorbs the outgoing address selection from FwdState and can now specify details of local+remote ends of an outgoing TCP link. Forwarding updated to handle the new outputs from peer selection and to open sequentially. pconn handling updated to use destination IP/port and hold a Comm::Connection instead of domain name indexing an FD. This allows us to maintain idle pools and re-use FD more efficiently with virtual-hosted servers. Along with maintaining certainty that the pconn selected actually goes to the exact destination IP:port needed by forwarding. comm layer outgoing connections now have a control job Comm::ConnOpener to do this. Due to the peer selection and forwarding changes this is a much simpler operation. HTTP / CONNECT tunnel / gopher / whois / FTP updated to receive a server and client Comm::Connection object from forwarding. To operate on those until they close or are finished with. SNMP / ICP / HTCP / DNS port listeners updated to work with Comm::Connection holding their listening socket meta data. This is a side-effect of the ICP and Comm read/write/timeout changes. --- 1c8f25bbb056368c4405473ff7304156608e92cc diff --cc src/comm/Connection.h index 0000000000,8fe0a94a53..4245225c8a mode 000000,100644..100644 --- a/src/comm/Connection.h +++ b/src/comm/Connection.h @@@ -1,0 -1,198 +1,198 @@@ + /* + * DEBUG: section 05 Socket Functions + * AUTHOR: Amos Jeffries + * AUTHOR: Robert Collins + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * 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. + * + * + * Copyright (c) 2003, Robert Collins + * Copyright (c) 2010, Amos Jeffries + */ + + #ifndef _SQUIDCONNECTIONDETAIL_H_ + #define _SQUIDCONNECTIONDETAIL_H_ + + #include "config.h" + #include "comm/forward.h" + #include "hier_code.h" + #include "ip/Address.h" + #include "MemPool.h" + #include "RefCount.h" + #include "typedefs.h" + #if USE_SQUID_EUI + #include "eui/Eui48.h" + #include "eui/Eui64.h" + #endif + + #if HAVE_IOSFWD + #include + #endif + #if HAVE_OSTREAM + #include + #endif + + struct peer; + + namespace Comm { + + /* TODO: make these a struct of boolean flags members in the connection instead of a bitmap. + * we can't do that until all non-comm code uses Commm::Connection objects to create FD + * currently there is code still using comm_open() and comm_openex() synchronously!! + */ + #define COMM_UNSET 0x00 + #define COMM_NONBLOCKING 0x01 // default flag. + #define COMM_NOCLOEXEC 0x02 + #define COMM_REUSEADDR 0x04 // shared FD may be both accept()ing and read()ing + #define COMM_DOBIND 0x08 // requires a bind() + #define COMM_TRANSPARENT 0x10 // arrived via TPROXY + #define COMM_INTERCEPTION 0x20 // arrived via NAT + + /** + * Store data about the physical and logical attributes of a connection. + * + * Some link state can be infered from the data, however this is not an + * object for state data. But a semantic equivalent for FD with easily + * accessible cached properties not requiring repeated complex lookups. + * + * Connection properties may be changed until the connection is opened. + * Properties should be considered read-only outside of the Comm layer + * code once the connection is open. + * - * These objects must not be passed around directly, - * but a Comm::ConnectionPointer must be passed instead. ++ * These objects should not be passed around directly, ++ * but a Comm::ConnectionPointer should be passed instead. + */ + class Connection : public RefCountable + { + public: + MEMPROXY_CLASS(Comm::Connection); + + Connection(); + + /** Clear the connection properties and close any open socket. */ + ~Connection(); + + /** Copy an existing connections IP and properties. + * This excludes the FD. The new copy will be a closed connection. + */ + ConnectionPointer copyDetails() const; + + /** Close any open socket. */ + void close(); + + /** determine whether this object describes an active connection or not. */ + bool isOpen() const { return (fd >= 0); } + + /** retrieve the peer pointer for use. + * The caller is responsible for all CBDATA operations regarding the + * used of the pointer returned. + */ + peer * const getPeer() const; + + /** alter the stored peer pointer. + * Perform appropriate CBDATA operations for locking the peer pointer + */ + void setPeer(peer * p); + + private: + /** These objects may not be exactly duplicated. Use copyDetails() instead. */ + Connection(const Connection &c); + + /** These objects may not be exactly duplicated. Use copyDetails() instead. */ + Connection & operator =(const Connection &c); + + public: + /** Address/Port for the Squid end of a TCP link. */ + Ip::Address local; + + /** Address for the Remote end of a TCP link. */ + Ip::Address remote; + + /** Hierarchy code for this connection link */ + hier_code peerType; + + /** Socket used by this connection. Negative if not open. */ + int fd; + + /** Quality of Service TOS values currently sent on this connection */ + tos_t tos; + + /** Netfilter MARK values currently sent on this connection */ + nfmark_t nfmark; + + /** COMM flags set on this connection */ + int flags; + + char rfc931[USER_IDENT_SZ]; + + #if USE_SQUID_EUI + Eui::Eui48 remoteEui48; + Eui::Eui64 remoteEui64; + #endif + + private: + // XXX: we need to call this member peer_ but the struct peer_ global type + // behind peer* clashes despite our private Comm:: namespace + // (it being global gets inherited here too). + + /** cache_peer data object (if any) */ + peer *_peer; + }; + + MEMPROXY_CLASS_INLINE(Connection); + + }; // namespace Comm + + + // NP: Order and namespace here is very important. + // * The second define inlines the first. + // * Stream inheritance overloading is searched in the global scope first. + + inline std::ostream & + operator << (std::ostream &os, const Comm::Connection &conn) + { + os << "local=" << conn.local << " remote=" << conn.remote; + if (conn.fd >= 0) + os << " FD " << conn.fd; + if (conn.flags != COMM_UNSET) + os << " flags=" << conn.flags; + #if USE_IDENT + if (*conn.rfc931) + os << " IDENT::" << conn.rfc931; + #endif + return os; + } + + inline std::ostream & + operator << (std::ostream &os, const Comm::ConnectionPointer &conn) + { + if (conn != NULL) + os << *conn; + return os; + } + + #endif diff --cc src/errorpage.h index a87662f477,f62719aa7b..ab355f990a --- a/src/errorpage.h +++ b/src/errorpage.h @@@ -39,8 -39,8 +39,9 @@@ #include "auth/UserRequest.h" #endif #include "cbdata.h" + #include "comm/forward.h" #include "ip/Address.h" +#include "MemBuf.h" #if USE_SSL #include "ssl/ErrorDetail.h" #endif