New patch attached for review.
This excludes the XXX/TODO and pipeline parts, most of which are already
merged and the remainder being deferred until a later update.
Amos
On 11/05/2013 4:31 p.m., Amos Jeffries wrote:
On 11/05/2013 5:07 a.m., Alex Rousskov wrote:
On 05/10/2013 09:05 AM, Amos Jeffries wrote:
Bumping this old design conversation back into gear. I would like to
start implementation and rollout of this master transaction code,
effective immediately.
I think this is a good start, but I do not think the proposed patch
should go in immediately.
First of all, pipelining changes are a totally separate can of worms
IMO. If you insist on merging MasterXact changes and pipelining change
in one patch, we will have to accept that, but it would be best to
separate the two issues into two different email threads/patches.
I'm already separating it out. The SQUID_PIPELINE_MAX and associated
XXX in a standalone patch will be submitted later today I think. The
array stuff is just to kee the Client* pipeline objects list separate
from eth Xaction at this point and I can drop easily.
I will focus on higher-level issues for pipelining and then provide a
more detailed review of MasterXact changes below.
Pipelining:
* If you are going to allow more than two transactions, the depth of the
pipeline should probably be configurable via squid.conf, replacing or
deprecating the on/off switch we already have. You may still have a
hard-coded maximum, but only if there is a good reason to have it. I do
not see one.
Agreed. However at this pint I'm not even happy making it generally
configurable. Thus the developers-only setting while we figure out for
certain where the flaws actually are.
* Please use an std::queue instead of C array for the
ConnStateData::xaction pipeline. Arrays are poor underlying structures
for FIFO queues.
Ack. queue or the current list management does seem better. I will
drop it from the initial patch for now, we will have to have a final
decision by the time the parser updates start to happen.
* Please remove references to pipelining from MasterXaction.h. Nothing
in MasterXaction.h should expose users to details relevant to only a
small part of Squid.
Done. It is left in client_side.h for now.
Master Transaction:
=== modified file 'src/CommCalls.h'
...
+ /// Transaction which this call is part of.
+ MasterXaction::Pointer xaction;
It feels wrong to place that object inside every Comm call. A Comm call
is a very low-level event. What would it do with a Master Transaction?
It would not even know which part of the Master Transaction corresponds
to the call! In fact, there are Comm calls that are not associated with
a master transaction. Let's not try to cram master transactions
everywhere just because it is needed somewhere. It will force us to
either create fake master transactions or deal with possibly nil master
transaction pointers.
Right now the TcpAcceptor AsyncJob is using it in AcceptCbParams to
pass the new transaction out to its child.
I am envisioning that the CloseCbParams will need to use it to pass it
to the Comm layer close handlers, and that the IoCbParms will need to
use it to pass to low level I/O handlers - for each of those
components to write the stats accounting details into the xaction
data. For now it is a NULL pointer on these parameters.
+#ifndef SQUID_SRC_MASTERXACTION_H
+#define SQUID_SRC_MASTERXACTION_H
+
+#include "anyp/PortCfg.h"
Please avoid exposing every master transaction user to PortCfg.
Will do. Planning to add anyp/forward.h to replace this.
FWIW all the callers I can find *do* need the port details (and
Comm::Connection details) in one way or another. But I agree
consistency on this will be useful.
+/** Master transaction state object.
Do we really want this class to store the current state of the master
transaction? Or should it only contain history/stats? The difference is
critical for the design of this class IMO:
If master transaction reflects the current state, it may have pointers
to client-side, server-side, and adaptation-side jobs (to name just a
few), facilitating their communication. It will be a powerful tool, but
will probably increase the dependencies among various "sides" and may
ultimately lead to messy and buggy code where one side is trying to
figure out what other sides are currently active and communicate with
them. We should be very careful if we decide to move down this path.
If master transaction collects the history and stats, it becomes very
useful for annotations and logging, but would not help with inter-side
communication.
Yes. I am thinking this be the stats and history up to the present. As
we roll it out we need to make clear decisions about what state is
shared and goes in here and what state is private to the AsyncJob.
With an API on the Job (Calls? Subscription?) for accessing the
private details.
Communication between the "sides" should be done via client-streams
API or whatever we adapt it into. I have alternative designs going
through my head based on the HTTP/2 frame-based messaging which can
pass blocks between components. For now that means the current methods
of accessing other sides Jobs will need to be left in place alongside
this MasterXaction state rollout.
The only reasons we have today for HttpStateData for example needing
to access something as far away as ConnStateData is to bypass all the
store systems lack of 1xx support (broken store API), or to access the
PortCfg details (lack of master transaction data in HttpStateData).
We will need to adjust the description of the MasterXaction class
accordingly. For now, I suggest adding three important pieces of
information:
* What is a "client transaction"? Should we define that as anything
worth logging into access.log? Or does that extend to ICP clients? SNMP?
* What event starts/creates a master transaction?
I am thinking these conditions create a new transaction:
1. New TCP connection, New UDP connection, New SCTP connection, etc. etc.
2. Parsing a new request on an existing persistent connection of any
above type.
3. starting a Squid internally generated request
We get into some tricky semantics with ssl-bump and ESI that still
need to be worked out.
* What event ends/destroys a master transaction?
The completion of the logging of a transaction should destroy it. We
may need to alter it to CbcPointer instead of RefCount at some point -
for now RefCount is sufficient.
I am thinking that we log at these points:
* completed delivery of a HTTP "final status"
* connection closure / abort.
NP: which logs are used to log it will depend on the transport type as
you mention below.
While working on this, please keep in mind that not all clients are
going to be HTTP clients. We already have ICP and SNMP clients, and the
FTP gateway project adds FTP clients. While we might want to exclude
things like SNMP from MasterXaction scope, I am not sure that is a good
idea, and I am sure this needs to be a conscious decision rather than an
accident.
I agree, and this was one of the key deciding factors in me going with
your proposal to have MasterXaction just a set of pointers to other
state objects.
Once finalized, the above additions will clarify master transaction
scope and will have long-lasting effects. This is important, even though
the initial changes will not cover the entire scope.
+
+ if (xaction != NULL)
+ os << ", xaction.id=" << xaction->id;
The InstanceId object will print the right prefix. Please drop the
"xaction.id=" prefix if this code stays at all.
ConnStateData();
+ ConnStateData(const MasterXaction::Pointer &xact);
Should the old constructor be removed now?
The new constructor is missing an "explicit" keyword.
Oops. right. fixed.
The old constructor is there as a "// do not implement."
+ MasterXaction::Pointer xaction[SQUID_PIPELINE_MAX];
The new member should be called "xactions" because there are many of
them.
+ params.xaction = new MasterXaction;
+ params.xaction->squidPort =
static_cast<AnyP::PortCfg*>(params.data); // do this here or in the
caller?
The question should be asked on the previous line: If we decide that
master transaction starts at accept time (which is what the current code
implies), then we must fill all the available details at that time. If
we decide that master transactions are started by ConnStateData, after
TcpAcceptor is done, then we should create and populate xaction there.
Attached is a patch implementing a basic MasterXaction class. It is
created by TcpAcceptor when a new client connects and gets passed out
for use when constructing a ConnStateData object to manage the
connection. The ConnStateData object does need to retain its own
pointers to the data received in that initial transaction - so that
when
receiving pipelined requests on a persistent connection it can spawn
new
MasterXaction objects with the same TCP details as the original.
Right. The question is whether it would be better to start the master
transaction from ConnStateData, especially since you still need to keep
all the tcp-level info independent of the MasterXaction anyway. There
are several advantages to creating MasterXaction inside ConnStateData:
* MasterXaction creation code becomes uniform. Currently, there are two
different cases: One in TCP acceptor and one in ConnStateData.
There will be more creation point cases as other alternative to
ConnStateData are added for non-TCP protocol ports and for squid
internally generated requests/transations. So this is a non-gain IMO.
* MasterXaction relationship with ConnStateData becomes simpler.
Currently, we are first creating ConnStateData using MasterXaction and
then are creating MasterXactions using ConnStateData, which is rather
messy, and forces us to explain why we want to keep some TCP data, etc.
See above. We will have a complex case anyway as ConnStateData creates
xaction on parsing request and also creates a transaction immediately
to log aborted connections, or continues to hide the aborted
connections from everyone.
* TcpAcceptor may be accepting a connection for something that is not
related to MasterXaction.
Such as? and why?
* Different protocol/port code may create different MasterXaction
objects (e.g., HTTP, HTTPS, and FTP acceptors might all want different
MasterXactions). I do not know whether we will need HttpMasterXaction
and FtpMasterTransaction in the future, but this design allows for it.
That is the protocol-specific pointer in MasterXaction. TcpAcceptor
Job scope is managing setup of the tcpClient and squidPort pointers.
Another non-TCP protocol acceptor would setup squidPort and its own
snmpClient/udpClient pointers for example.
This was my thinking when I moved it from the initial location of
ConnStateDate to TcpAcceptor. We also then have the consistency of
new-connection == new transaction. ConnStateData is one of the sepcial
cases which need their own copy of *some* details on the first xaction
received for creating future ones - I'm expecting all Jobs
* There is no pressure to stuff MasterXact into all Comm callbacks where
it does not belong.
If the state shared between all Jobs is going to be in here logically
we will end up placing the transaction in/out buffers in here as well.
In which case the Comm systems will all be using it for source/sink.
And by intention the read/write at least will be adding their stats here.
What are the advantages of creating MasterXact earlier, at TCP accept
level?
We gain the guarantee that a transaction object exists as soon as
possible, and fully describes the history so far. It can therefore be
logged as a transaction with no request (client error/abort?) using a
single MasterXaction based API to logging and comm - even if
ConnStateData setup fails for any reason.
We can plug a TcpAcceptor into some form of TunnelStateData directly
and have a SOCKS-like proxy, or a port-X to HTTP gateway. (port 1
intercepted, converted to CONNECT and delivered via peers?).
It also demonstrates to you and others the mechanism for passing
between Jobs. Whether we move this back to ConnStateData for the final
commit or not you can see here the model I'm proposing to roll through
the rest of Squid. Like SBuf, once the core and some examplar code is
in we can all work on continuing the rollout.
I've marked all the branching points where MasterXaction could extend
out of ConnStateData with XXX right now instead of rolling
MasterXaction
down through the entire codebase. As you can see from this patch
already
simply rolling it fully into ConnStateData is causing a lot of
polishing
changes to happen. That is likely to be the norm rather than the
exception, so I'm intending to submit each individual step as a
separate
patch on trunk with SourceLayout bundled alongside Xaction rollout.
Sounds good. Please do not commit all those XXXs/TODOs though. After the
MasterXact skeleton is finished and committed (this thread), just post
the new MasterXact-using code as you have time to work on it.
Do you not think it better to mark the missing API alterations for
others to be aware of and maybe chose to join in working on?
Amos
=== modified file 'src/CommCalls.cc'
--- src/CommCalls.cc 2012-08-28 13:00:30 +0000
+++ src/CommCalls.cc 2013-06-09 12:04:13 +0000
@@ -7,12 +7,12 @@
/* CommCommonCbParams */
CommCommonCbParams::CommCommonCbParams(void *aData):
- data(cbdataReference(aData)), conn(), flag(COMM_OK), xerrno(0), fd(-1)
+ data(cbdataReference(aData)), conn(), flag(COMM_OK), xerrno(0),
fd(-1), xaction()
{
}
CommCommonCbParams::CommCommonCbParams(const CommCommonCbParams &p):
- data(cbdataReference(p.data)), conn(p.conn), flag(p.flag),
xerrno(p.xerrno), fd(p.fd)
+ data(cbdataReference(p.data)), conn(p.conn), flag(p.flag),
xerrno(p.xerrno), fd(p.fd), xaction(p.xaction)
{
}
@@ -35,6 +35,9 @@
os << ", flag=" << flag;
if (data)
os << ", data=" << data;
+
+ if (xaction != NULL)
+ os << ", " << xaction->id;
}
/* CommAcceptCbParams */
=== modified file 'src/CommCalls.h'
--- src/CommCalls.h 2013-01-02 23:40:49 +0000
+++ src/CommCalls.h 2013-06-09 12:04:33 +0000
@@ -5,6 +5,7 @@
#include "base/AsyncJobCalls.h"
#include "comm_err_t.h"
#include "comm/forward.h"
+#include "MasterXaction.h"
/* CommCalls implement AsyncCall interface for comm_* callbacks.
* The classes cover two call dialer kinds:
@@ -79,6 +80,10 @@
int xerrno; ///< The last errno to occur. non-zero if flag is
COMM_ERR.
int fd; ///< FD which the call was about. Set by the async call creator.
+
+ /// Transaction which this call is part of.
+ MasterXaction::Pointer xaction;
+
private:
// should not be needed and not yet implemented
CommCommonCbParams &operator =(const CommCommonCbParams ¶ms);
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2013-06-07 04:35:25 +0000
+++ src/Makefile.am 2013-06-07 04:41:21 +0000
@@ -422,6 +422,8 @@
LogTags.h \
lookup_t.h \
main.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
Mem.h \
mem.cc \
mem_node.cc \
@@ -1251,6 +1253,8 @@
HttpRequestMethod.cc \
int.h \
int.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
SquidList.h \
SquidList.cc \
mem_node.cc \
@@ -1488,6 +1492,8 @@
internal.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
multicast.h \
multicast.cc \
mem_node.cc \
@@ -1668,6 +1674,8 @@
int.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
MemBuf.cc \
MemObject.cc \
mem_node.cc \
@@ -1904,6 +1912,8 @@
internal.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
Mem.h \
mem.cc \
mem_node.cc \
@@ -2152,6 +2162,8 @@
internal.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
MemBlob.cc \
MemBuf.cc \
MemObject.cc \
@@ -2397,6 +2409,8 @@
ipcache.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
MemBlob.cc \
MemBuf.cc \
MemObject.cc \
@@ -2687,6 +2701,8 @@
internal.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
multicast.h \
multicast.cc \
mem_node.cc \
@@ -2860,6 +2876,8 @@
int.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
Mem.h \
mem.cc \
mem_node.cc \
@@ -3085,6 +3103,8 @@
RequestFlags.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
MemObject.cc \
StoreSwapLogData.cc \
StoreIOState.cc \
@@ -3271,6 +3291,8 @@
int.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
Mem.h \
mem.cc \
MemBuf.cc \
@@ -3655,6 +3677,8 @@
internal.cc \
SquidList.h \
SquidList.cc \
+ MasterXaction.cc \
+ MasterXaction.h \
multicast.h \
multicast.cc \
Mem.h \
=== modified file 'src/anyp/Makefile.am'
--- src/anyp/Makefile.am 2013-01-28 13:24:51 +0000
+++ src/anyp/Makefile.am 2013-06-07 04:41:21 +0000
@@ -4,6 +4,7 @@
noinst_LTLIBRARIES = libanyp.la
libanyp_la_SOURCES = \
+ forward.h \
PortCfg.cc \
PortCfg.h \
ProtocolType.cc \
=== modified file 'src/anyp/PortCfg.h'
--- src/anyp/PortCfg.h 2013-02-10 16:31:40 +0000
+++ src/anyp/PortCfg.h 2013-06-07 04:41:21 +0000
@@ -1,8 +1,8 @@
#ifndef SQUID_ANYP_PORTCFG_H
#define SQUID_ANYP_PORTCFG_H
+#include "anyp/forward.h"
#include "anyp/TrafficMode.h"
-#include "cbdata.h"
#include "comm/Connection.h"
#if USE_SSL
=== added file 'src/anyp/forward.h'
--- src/anyp/forward.h 1970-01-01 00:00:00 +0000
+++ src/anyp/forward.h 2013-06-07 04:16:20 +0000
@@ -0,0 +1,15 @@
+#ifndef _SQUID_SRC_ANYP_FORWARD_H
+#define _SQUID_SRC_ANYP_FORWARD_H
+
+#include "base/CbcPointer.h"
+
+namespace AnyP
+{
+
+class PortCfg;
+typedef CbcPointer<PortCfg> PortCfgPointer;
+
+} // namespace AnyP
+
+#endif /* _SQUID_SRC_ANYP_FORWARD_H */
+
=== modified file 'src/client_side.cc'
--- src/client_side.cc 2013-06-07 08:49:36 +0000
+++ src/client_side.cc 2013-06-09 12:19:09 +0000
@@ -245,8 +245,6 @@
char *skipLeadingSpace(char *aString);
static void connNoteUseOfBuffer(ConnStateData* conn, size_t byteCount);
-static ConnStateData *connStateCreate(const Comm::ConnectionPointer &client,
AnyP::PortCfg *port);
-
clientStreamNode *
ClientSocketContext::getTail() const
{
@@ -3330,23 +3328,37 @@
io.conn->close();
}
-ConnStateData *
-connStateCreate(const Comm::ConnectionPointer &client, AnyP::PortCfg *port)
+ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) :
+ AsyncJob("ConnStateData"),
+#if USE_SSL
+ sslBumpMode(Ssl::bumpEnd),
+ switchedToHttps_(false),
+ sslServerBump(NULL),
+#endif
+ stoppedSending_(NULL),
+ stoppedReceiving_(NULL)
{
- ConnStateData *result = new ConnStateData;
-
- result->clientConnection = client;
- result->log_addr = client->remote;
- result->log_addr.applyMask(Config.Addrs.client_netmask);
- result->in.buf = (char *)memAllocBuf(CLIENT_REQ_BUF_SZ,
&result->in.allocatedSize);
- result->port = cbdataReference(port);
+ 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());
+ log_addr = xact->tcpClient->remote;
+ log_addr.applyMask(Config.Addrs.client_netmask);
+
+ in.buf = (char *)memAllocBuf(CLIENT_REQ_BUF_SZ, &in.allocatedSize);
if (port->disable_pmtu_discovery != DISABLE_PMTU_OFF &&
- (result->transparent() || port->disable_pmtu_discovery ==
DISABLE_PMTU_ALWAYS)) {
+ (transparent() || port->disable_pmtu_discovery ==
DISABLE_PMTU_ALWAYS)) {
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
int i = IP_PMTUDISC_DONT;
- if (setsockopt(client->fd, SOL_IP, IP_MTU_DISCOVER, &i, sizeof(i)) < 0)
- debugs(33, 2, "WARNING: Path MTU discovery disabling failed on "
<< client << " : " << xstrerror());
+ 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;
@@ -3358,33 +3370,33 @@
}
typedef CommCbMemFunT<ConnStateData, CommCloseCbParams> Dialer;
- AsyncCall::Pointer call = JobCallback(33, 5, Dialer, result,
ConnStateData::connStateClosed);
- comm_add_close_handler(client->fd, call);
+ AsyncCall::Pointer call = JobCallback(33, 5, Dialer, this,
ConnStateData::connStateClosed);
+ comm_add_close_handler(clientConnection->fd, call);
if (Config.onoff.log_fqdn)
- fqdncache_gethostbyaddr(client->remote, FQDN_LOOKUP_IF_MISS);
+ fqdncache_gethostbyaddr(clientConnection->remote, FQDN_LOOKUP_IF_MISS);
#if USE_IDENT
if (Ident::TheConfig.identLookup) {
ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, NULL,
NULL);
- identChecklist.src_addr = client->remote;
- identChecklist.my_addr = client->local;
+ identChecklist.src_addr = xact->tcpClient->remote;
+ identChecklist.my_addr = xact->tcpClient->local;
if (identChecklist.fastCheck() == ACCESS_ALLOWED)
- Ident::Start(client, clientIdentDone, result);
+ Ident::Start(xact->tcpClient, clientIdentDone, this);
}
#endif
- clientdbEstablished(client->remote, 1);
+ clientdbEstablished(clientConnection->remote, 1);
- result->flags.readMore = true;
- return result;
+ flags.readMore = true;
}
/** Handle a new connection on HTTP socket. */
void
httpAccept(const CommAcceptCbParams ¶ms)
{
- AnyP::PortCfg *s = static_cast<AnyP::PortCfg *>(params.data);
+ MasterXaction::Pointer xact = params.xaction;
+ AnyP::PortCfgPointer s = xact->squidPort;
if (params.flag != COMM_OK) {
// Its possible the call was still queued when the client disconnected
@@ -3402,7 +3414,7 @@
++ incoming_sockets_accepted;
// Socket is ready, setup the connection manager to start using it
- ConnStateData *connState = connStateCreate(params.conn, s);
+ ConnStateData *connState = new ConnStateData(xact);
typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> TimeoutDialer;
AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
@@ -3651,7 +3663,7 @@
/**
* A callback function to use with the ACLFilledChecklist callback.
- * In the case of ACCES_ALLOWED answer initializes a bumped SSL connection,
+ * In the case of ACCESS_ALLOWED answer initializes a bumped SSL connection,
* else reverts the connection to tunnel mode.
*/
static void
@@ -3693,7 +3705,9 @@
static void
httpsAccept(const CommAcceptCbParams ¶ms)
{
- AnyP::PortCfg *s = static_cast<AnyP::PortCfg *>(params.data);
+ MasterXaction::Pointer xact = params.xaction;
+ const AnyP::PortCfgPointer s = xact->squidPort;
+ assert(s.valid());
if (params.flag != COMM_OK) {
// Its possible the call was still queued when the client disconnected
@@ -3711,7 +3725,7 @@
++incoming_sockets_accepted;
// Socket is ready, setup the connection manager to start using it
- ConnStateData *connState = connStateCreate(params.conn, s);
+ ConnStateData *connState = new ConnStateData(xact);
if (s->flags.tunnelSslBumping) {
debugs(33, 5, "httpsAccept: accept transparent connection: " <<
params.conn);
@@ -4310,24 +4324,6 @@
CBDATA_CLASS_INIT(ConnStateData);
-ConnStateData::ConnStateData() :
- AsyncJob("ConnStateData"),
-#if USE_SSL
- 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;
-}
-
bool
ConnStateData::transparent() const
{
=== modified file 'src/client_side.h'
--- src/client_side.h 2013-05-30 14:58:49 +0000
+++ src/client_side.h 2013-06-09 12:09:06 +0000
@@ -187,8 +187,7 @@
{
public:
-
- ConnStateData();
+ explicit ConnStateData(const MasterXaction::Pointer &xact);
~ConnStateData();
void readSomeData();
@@ -255,13 +254,14 @@
*/
ClientSocketContext::Pointer currentobject;
- Ip::Address log_addr;
+ Ip::Address log_addr; // TODO: remove entirely and produce masked IP on
demand.
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 */
@@ -273,6 +273,7 @@
AsyncCall::Pointer closeHandler; /*The close handler for pinned server
side connection*/
} pinning;
+ // Squid listening port details where this connection arrived.
AnyP::PortCfg *port;
bool transparent() const;
=== modified file 'src/comm/TcpAcceptor.cc'
--- src/comm/TcpAcceptor.cc 2013-06-03 14:05:16 +0000
+++ src/comm/TcpAcceptor.cc 2013-06-07 04:41:21 +0000
@@ -33,6 +33,7 @@
*/
#include "squid.h"
+#include "anyp/PortCfg.h"
#include "base/TextException.h"
#include "client_db.h"
#include "comm/AcceptLimiter.h"
@@ -46,6 +47,7 @@
#include "fde.h"
#include "globals.h"
#include "ip/Intercept.h"
+#include "MasterXaction.h"
#include "profiler/Profiler.h"
#include "SquidConfig.h"
#include "SquidTime.h"
@@ -286,8 +288,10 @@
if (theCallSub != NULL) {
AsyncCall::Pointer call = theCallSub->callback();
CommAcceptCbParams ¶ms = GetCommParams<CommAcceptCbParams>(call);
+ params.xaction = new MasterXaction;
+ params.xaction->squidPort = static_cast<AnyP::PortCfg*>(params.data);
params.fd = conn->fd;
- params.conn = newConnDetails;
+ params.conn = params.xaction->tcpClient = newConnDetails;
params.flag = flag;
params.xerrno = errcode;
ScheduleCallHere(call);