tunnelServerClosed(int fd, void *data)
{
TunnelStateData *tunnelState = (TunnelStateData *)data;
- debugs(26, 3, "tunnelServerClosed: FD " << fd);
+ debugs(26, 3, HERE << "FD " << fd);
tunnelState->server.conn = NULL;
if (tunnelState->noConnections()) {
tunnelClientClosed(int fd, void *data)
{
TunnelStateData *tunnelState = (TunnelStateData *)data;
- debugs(26, 3, "tunnelClientClosed: FD " << fd);
+ debugs(26, 3, HERE << "FD " << fd);
tunnelState->client.conn = NULL;
if (tunnelState->noConnections()) {
static void
tunnelStateFree(TunnelStateData * tunnelState)
{
- debugs(26, 3, "tunnelStateFree: tunnelState=" << tunnelState);
+ debugs(26, 3, HERE << "tunnelState=" << tunnelState);
assert(tunnelState != NULL);
assert(tunnelState->noConnections());
safe_free(tunnelState->url);
TunnelStateData::Connection::~Connection()
{
- safe_free (buf);
+ safe_free(buf);
}
int
void
TunnelStateData::Connection::bytesIn(int const &count)
{
+ debugs(26, 3, HERE << "len=" << len << " + count=" << count);
#if USE_DELAY_POOLS
delayId.bytesIn(count);
#endif
/* Read from server side and queue it for writing to the client */
void
-TunnelStateData::ReadServer(const Comm::ConnectionPointer &, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data)
+TunnelStateData::ReadServer(const Comm::ConnectionPointer &c, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data)
{
TunnelStateData *tunnelState = (TunnelStateData *)data;
assert(cbdataReferenceValid(tunnelState));
+ debugs(26, 3, HERE << c);
tunnelState->readServer(buf, len, errcode, xerrno);
}
void
TunnelStateData::readServer(char *buf, size_t len, comm_err_t errcode, int xerrno)
{
- debugs(26, 3, HERE << server.conn << ", read " << len << " bytes");
+ debugs(26, 3, HERE << server.conn << ", read " << len << " bytes, err=" << errcode);
/*
* Bail out early on COMM_ERR_CLOSING
void
TunnelStateData::readClient(char *buf, size_t len, comm_err_t errcode, int xerrno)
{
- debugs(26, 3, HERE << client.conn << ", read " << len << " bytes");
+ debugs(26, 3, HERE << client.conn << ", read " << len << " bytes, err=" << errcode);
/*
* Bail out early on COMM_ERR_CLOSING
void
TunnelStateData::copy (size_t len, comm_err_t errcode, int xerrno, Connection &from, Connection &to, IOCB *completion)
{
+ debugs(26, 3, HERE << "from={" << from.conn << "}, to={" << to.conn << "}");
+
/* I think this is to prevent free-while-in-a-callback behaviour
* - RBC 20030229
* from.conn->close() / to.conn->close() done here trigger close callbacks which may free TunnelStateData
if (errcode)
from.error (xerrno);
else if (len == 0 || !Comm::IsConnOpen(to.conn)) {
+ debugs(26, 3, HERE << "Nothing to write or client gone. Terminate the tunnel.");
from.conn->close();
/* Only close the remote end if we've finished queueing data to it */
to.conn->close();
}
} else if (cbdataReferenceValid(this)) {
- AsyncCall::Pointer call = commCbCall(5,5, "SomeTunnelWriteHandler",
+ debugs(26, 3, HERE << "Schedule Write");
+ AsyncCall::Pointer call = commCbCall(5,5, "TunnelBlindCopyWriteHandler",
CommIoCbPtrFun(completion, this));
Comm::Write(to.conn, from.buf, len, call, NULL);
}
void
TunnelStateData::writeServerDone(char *buf, size_t len, comm_err_t flag, int xerrno)
{
- debugs(26, 3, HERE << server.conn << ", " << len << " bytes written");
+ debugs(26, 3, HERE << server.conn << ", " << len << " bytes written, flag=" << flag);
/* Error? */
if (flag != COMM_OK) {
- if (flag != COMM_ERR_CLOSING)
+ if (flag != COMM_ERR_CLOSING) {
+ debugs(26, 4, HERE << "calling TunnelStateData::server.error(" << xerrno <<")");
server.error(xerrno); // may call comm_close
+ }
return;
}
/* EOF? */
if (len == 0) {
+ debugs(26, 4, HERE << "No read input. Closing server connection.");
server.conn->close();
return;
}
/* If the other end has closed, so should we */
if (!Comm::IsConnOpen(client.conn)) {
+ debugs(26, 4, HERE << "Client gone away. Shutting down server connection.");
server.conn->close();
return;
}
void
TunnelStateData::Connection::dataSent(size_t amount)
{
+ debugs(26, 3, HERE << "len=" << len << " - amount=" << amount);
assert(amount == (size_t)len);
len =0;
/* increment total object size */
void
TunnelStateData::writeClientDone(char *buf, size_t len, comm_err_t flag, int xerrno)
{
- debugs(26, 3, HERE << client.conn << ", " << len << " bytes written");
+ debugs(26, 3, HERE << client.conn << ", " << len << " bytes written, flag=" << flag);
/* Error? */
if (flag != COMM_OK) {
- if (flag != COMM_ERR_CLOSING)
+ if (flag != COMM_ERR_CLOSING) {
+ debugs(26, 4, HERE << "Closing client connection due to comm flags.");
client.error(xerrno); // may call comm_close
+ }
return;
}
/* EOF? */
if (len == 0) {
+ debugs(26, 4, HERE << "Closing client connection due to 0 byte read.");
client.conn->close();
return;
}
/* If the other end has closed, so should we */
if (!Comm::IsConnOpen(server.conn)) {
+ debugs(26, 4, HERE << "Server has gone away. Terminating client connection.");
client.conn->close();
return;
}
TunnelStateData::copyRead(Connection &from, IOCB *completion)
{
assert(from.len == 0);
- AsyncCall::Pointer call = commCbCall(5,4, "SomeTunnelReadHandler",
+ AsyncCall::Pointer call = commCbCall(5,4, "TunnelBlindCopyReadHandler",
CommIoCbPtrFun(completion, this));
comm_read(from.conn, from.buf, from.bytesWanted(1, SQUID_TCP_SO_RCVBUF), call);
}
tunnelConnectedWriteDone(const Comm::ConnectionPointer &conn, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
{
TunnelStateData *tunnelState = (TunnelStateData *)data;
+ debugs(26, 3, HERE << conn << ", flag=" << flag);
if (flag != COMM_OK) {
*tunnelState->status_ptr = HTTP_INTERNAL_SERVER_ERROR;
}
static void
-tunnelErrorComplete(int /*const Comm::ConnectionPointer &*/, void *data, size_t)
+tunnelErrorComplete(int fd/*const Comm::ConnectionPointer &*/, void *data, size_t)
{
TunnelStateData *tunnelState = (TunnelStateData *)data;
+ debugs(26, 3, HERE << "FD " << fd);
assert(tunnelState != NULL);
/* temporary lock to save our own feets (comm_close -> tunnelClientClosed -> Free) */
cbdataInternalLock(tunnelState);
TunnelStateData *tunnelState = (TunnelStateData *)data;
if (status != COMM_OK) {
+ debugs(26, 4, HERE << conn << ", comm failure recovery.");
/* At this point only the TCP handshake has failed. no data has been passed.
* we are allowed to re-try the TCP-level connection to alternate IPs for CONNECT.
*/
tunnelState->serverDestinations.shift();
if (status != COMM_TIMEOUT && tunnelState->serverDestinations.size() > 0) {
/* Try another IP of this destination host */
+ debugs(26, 4, HERE << "retry with : " << tunnelState->serverDestinations[0]);
AsyncCall::Pointer call = commCbCall(26,3, "tunnelConnectDone", CommConnectCbPtrFun(tunnelConnectDone, tunnelState));
Comm::ConnOpener *cs = new Comm::ConnOpener(tunnelState->serverDestinations[0], call, Config.Timeout.connect);
cs->setHost(tunnelState->url);
AsyncJob::Start(cs);
} else {
+ debugs(26, 4, HERE << "terminate with error.");
ErrorState *err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, tunnelState->request);
*tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
err->xerrno = xerrno;
tunnelState->request->peer_host = conn->getPeer() ? conn->getPeer()->host : NULL;
comm_add_close_handler(conn->fd, tunnelServerClosed, tunnelState);
+ debugs(26, 4, HERE << "determine post-connect handling pathway.");
if (conn->getPeer()) {
tunnelState->request->peer_login = conn->getPeer()->login;
tunnelState->request->flags.proxying = (conn->getPeer()->options.originserver?0:1);
void
tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr)
{
+ debugs(26, 3, HERE);
/* Create state structure. */
TunnelStateData *tunnelState = NULL;
ErrorState *err = NULL;
answer = ch.fastCheck();
if (answer == 0) {
+ debugs(26, 4, HERE << "MISS access forbidden.");
err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN, request);
*status_ptr = HTTP_FORBIDDEN;
errorSend(http->getConn()->clientConnection, err);
}
}
- debugs(26, 3, "tunnelStart: '" << RequestMethodStr(request->method) << " " << url << "'");
+ debugs(26, 3, HERE << "'" << RequestMethodStr(request->method) << " " << url << " HTTP/" << request->http_ver << "'");
statCounter.server.all.requests++;
statCounter.server.other.requests++;
TunnelStateData *tunnelState = (TunnelStateData *)data;
if (peer_paths == NULL || peer_paths->size() < 1) {
+ debugs(26, 3, HERE << "No paths found. Aborting CONNECT");
ErrorState *err;
err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE, tunnelState->request);
*tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
errorSend(tunnelState->client.conn, err);
return;
}
+ debugs(26, 3, HERE << "paths=" << peer_paths->size() << ", p[0]={" << (*peer_paths)[0] << "}, serverDest[0]={" <<
+ tunnelState->serverDestinations[0] << "}");
AsyncCall::Pointer call = commCbCall(26,3, "tunnelConnectDone", CommConnectCbPtrFun(tunnelConnectDone, tunnelState));
Comm::ConnOpener *cs = new Comm::ConnOpener(tunnelState->serverDestinations[0], call, Config.Timeout.connect);