mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-28 11:43:25 +02:00
Remove left-over squid patch file
This commit is contained in:
@@ -1,284 +0,0 @@
|
|||||||
------------------------------------------------------------
|
|
||||||
revno: 13225
|
|
||||||
revision-id: squid3@treenet.co.nz-20150709032133-qg1patn5zngt4o4h
|
|
||||||
parent: squid3@treenet.co.nz-20150501100500-3utkhrao1yrd8ig6
|
|
||||||
author: Alex Rousskov <rousskov@measurement-factory.com>
|
|
||||||
committer: Amos Jeffries <squid3@treenet.co.nz>
|
|
||||||
branch nick: 3.4
|
|
||||||
timestamp: Wed 2015-07-08 20:21:33 -0700
|
|
||||||
message:
|
|
||||||
Do not blindly forward cache peer CONNECT responses.
|
|
||||||
|
|
||||||
Squid blindly forwards cache peer CONNECT responses to clients. This
|
|
||||||
may break things if the peer responds with something like HTTP 403
|
|
||||||
(Forbidden) and keeps the connection with Squid open:
|
|
||||||
- The client application issues a CONNECT request.
|
|
||||||
- Squid forwards this request to a cache peer.
|
|
||||||
- Cache peer correctly responds back with a "403 Forbidden".
|
|
||||||
- Squid does not parse cache peer response and
|
|
||||||
just forwards it as if it was a Squid response to the client.
|
|
||||||
- The TCP connections are not closed.
|
|
||||||
|
|
||||||
At this stage, Squid is unaware that the CONNECT request has failed. All
|
|
||||||
subsequent requests on the user agent TCP connection are treated as
|
|
||||||
tunnelled traffic. Squid is forwarding these requests to the peer on the
|
|
||||||
TCP connection previously used for the 403-ed CONNECT request, without
|
|
||||||
proper processing. The additional headers which should have been applied
|
|
||||||
by Squid to these requests are not applied, and the requests are being
|
|
||||||
forwarded to the cache peer even though the Squid configuration may
|
|
||||||
state that these requests must go directly to the origin server.
|
|
||||||
|
|
||||||
This fixes Squid to parse cache peer responses, and if an error response
|
|
||||||
found, respond with "502 Bad Gateway" to the client and close the
|
|
||||||
connections.
|
|
||||||
------------------------------------------------------------
|
|
||||||
# Bazaar merge directive format 2 (Bazaar 0.90)
|
|
||||||
# revision_id: squid3@treenet.co.nz-20150709032133-qg1patn5zngt4o4h
|
|
||||||
# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.4
|
|
||||||
# testament_sha1: 6cbce093f30c8a09173eb610eaa423c7c305ff23
|
|
||||||
# timestamp: 2015-07-09 03:40:35 +0000
|
|
||||||
# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.4
|
|
||||||
# base_revision_id: squid3@treenet.co.nz-20150501100500-\
|
|
||||||
# 3utkhrao1yrd8ig6
|
|
||||||
#
|
|
||||||
# Begin patch
|
|
||||||
=== modified file 'src/tunnel.cc'
|
|
||||||
--- src/tunnel.cc 2014-04-26 10:58:22 +0000
|
|
||||||
+++ src/tunnel.cc 2015-07-09 03:21:33 +0000
|
|
||||||
@@ -122,6 +122,10 @@
|
|
||||||
(request->flags.interceptTproxy || request->flags.intercepted));
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /// Sends "502 Bad Gateway" error response to the client,
|
|
||||||
+ /// if it is waiting for Squid CONNECT response, closing connections.
|
|
||||||
+ void informUserOfPeerError(const char *errMsg);
|
|
||||||
+
|
|
||||||
class Connection
|
|
||||||
{
|
|
||||||
|
|
||||||
@@ -139,13 +143,14 @@
|
|
||||||
|
|
||||||
void error(int const xerrno);
|
|
||||||
int debugLevelForError(int const xerrno) const;
|
|
||||||
- /// handles a non-I/O error associated with this Connection
|
|
||||||
- void logicError(const char *errMsg);
|
|
||||||
void closeIfOpen();
|
|
||||||
void dataSent (size_t amount);
|
|
||||||
+ /// writes 'b' buffer, setting the 'writer' member to 'callback'.
|
|
||||||
+ void write(const char *b, int size, AsyncCall::Pointer &callback, FREE * free_func);
|
|
||||||
int len;
|
|
||||||
char *buf;
|
|
||||||
int64_t *size_ptr; /* pointer to size in an ConnStateData for logging */
|
|
||||||
+ AsyncCall::Pointer writer; ///< pending Comm::Write callback
|
|
||||||
|
|
||||||
Comm::ConnectionPointer conn; ///< The currently connected connection.
|
|
||||||
|
|
||||||
@@ -195,13 +200,14 @@
|
|
||||||
TunnelStateData *tunnelState = (TunnelStateData *)params.data;
|
|
||||||
debugs(26, 3, HERE << tunnelState->server.conn);
|
|
||||||
tunnelState->server.conn = NULL;
|
|
||||||
+ tunnelState->server.writer = NULL;
|
|
||||||
|
|
||||||
if (tunnelState->noConnections()) {
|
|
||||||
delete tunnelState;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!tunnelState->server.len) {
|
|
||||||
+ if (!tunnelState->client.writer) {
|
|
||||||
tunnelState->client.conn->close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -213,13 +219,14 @@
|
|
||||||
TunnelStateData *tunnelState = (TunnelStateData *)params.data;
|
|
||||||
debugs(26, 3, HERE << tunnelState->client.conn);
|
|
||||||
tunnelState->client.conn = NULL;
|
|
||||||
+ tunnelState->client.writer = NULL;
|
|
||||||
|
|
||||||
if (tunnelState->noConnections()) {
|
|
||||||
delete tunnelState;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!tunnelState->client.len) {
|
|
||||||
+ if (!tunnelState->server.writer) {
|
|
||||||
tunnelState->server.conn->close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -343,6 +350,23 @@
|
|
||||||
handleConnectResponse(len);
|
|
||||||
}
|
|
||||||
|
|
||||||
+void
|
|
||||||
+TunnelStateData::informUserOfPeerError(const char *errMsg)
|
|
||||||
+{
|
|
||||||
+ server.len = 0;
|
|
||||||
+ if (!clientExpectsConnectResponse()) {
|
|
||||||
+ // closing the connection is the best we can do here
|
|
||||||
+ debugs(50, 3, server.conn << " closing on error: " << errMsg);
|
|
||||||
+ server.conn->close();
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ ErrorState *err = new ErrorState(ERR_CONNECT_FAIL, Http::scBadGateway, request.getRaw());
|
|
||||||
+ err->callback = tunnelErrorComplete;
|
|
||||||
+ err->callback_data = this;
|
|
||||||
+ *status_ptr = Http::scBadGateway;
|
|
||||||
+ errorSend(http->getConn()->clientConnection, err);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Read from client side and queue it for writing to the server */
|
|
||||||
void
|
|
||||||
TunnelStateData::ReadConnectResponseDone(const Comm::ConnectionPointer &, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data)
|
|
||||||
@@ -374,7 +398,7 @@
|
|
||||||
const bool parsed = rep.parse(connectRespBuf, eof, &parseErr);
|
|
||||||
if (!parsed) {
|
|
||||||
if (parseErr > 0) { // unrecoverable parsing error
|
|
||||||
- server.logicError("malformed CONNECT response from peer");
|
|
||||||
+ informUserOfPeerError("malformed CONNECT response from peer");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -383,7 +407,7 @@
|
|
||||||
assert(!parseErr);
|
|
||||||
|
|
||||||
if (!connectRespBuf->hasSpace()) {
|
|
||||||
- server.logicError("huge CONNECT response from peer");
|
|
||||||
+ informUserOfPeerError("huge CONNECT response from peer");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -397,7 +421,8 @@
|
|
||||||
|
|
||||||
// bail if we did not get an HTTP 200 (Connection Established) response
|
|
||||||
if (rep.sline.status() != Http::scOkay) {
|
|
||||||
- server.logicError("unsupported CONNECT response status code");
|
|
||||||
+ // if we ever decide to reuse the peer connection, we must extract the error response first
|
|
||||||
+ informUserOfPeerError("unsupported CONNECT response status code");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -416,13 +441,6 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
-TunnelStateData::Connection::logicError(const char *errMsg)
|
|
||||||
-{
|
|
||||||
- debugs(50, 3, conn << " closing on error: " << errMsg);
|
|
||||||
- conn->close();
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
TunnelStateData::Connection::error(int const xerrno)
|
|
||||||
{
|
|
||||||
/* XXX fixme xstrerror and xerrno... */
|
|
||||||
@@ -517,7 +535,7 @@
|
|
||||||
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);
|
|
||||||
+ to.write(from.buf, len, call, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Writes data from the client buffer to the server side */
|
|
||||||
@@ -526,6 +544,7 @@
|
|
||||||
{
|
|
||||||
TunnelStateData *tunnelState = (TunnelStateData *)data;
|
|
||||||
assert (cbdataReferenceValid (tunnelState));
|
|
||||||
+ tunnelState->server.writer = NULL;
|
|
||||||
|
|
||||||
tunnelState->writeServerDone(buf, len, flag, xerrno);
|
|
||||||
}
|
|
||||||
@@ -575,6 +594,7 @@
|
|
||||||
{
|
|
||||||
TunnelStateData *tunnelState = (TunnelStateData *)data;
|
|
||||||
assert (cbdataReferenceValid (tunnelState));
|
|
||||||
+ tunnelState->client.writer = NULL;
|
|
||||||
|
|
||||||
tunnelState->writeClientDone(buf, len, flag, xerrno);
|
|
||||||
}
|
|
||||||
@@ -592,7 +612,14 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
-TunnelStateData::writeClientDone(char *buf, size_t len, comm_err_t flag, int xerrno)
|
|
||||||
+TunnelStateData::Connection::write(const char *b, int size, AsyncCall::Pointer &callback, FREE * free_func)
|
|
||||||
+{
|
|
||||||
+ writer = callback;
|
|
||||||
+ Comm::Write(conn, b, size, callback, free_func);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+TunnelStateData::writeClientDone(char *, size_t len, comm_err_t flag, int xerrno)
|
|
||||||
{
|
|
||||||
debugs(26, 3, HERE << client.conn << ", " << len << " bytes written, flag=" << flag);
|
|
||||||
|
|
||||||
@@ -712,6 +739,7 @@
|
|
||||||
{
|
|
||||||
TunnelStateData *tunnelState = (TunnelStateData *)data;
|
|
||||||
debugs(26, 3, HERE << conn << ", flag=" << flag);
|
|
||||||
+ tunnelState->client.writer = NULL;
|
|
||||||
|
|
||||||
if (flag != COMM_OK) {
|
|
||||||
*tunnelState->status_ptr = Http::scInternalServerError;
|
|
||||||
@@ -728,6 +756,7 @@
|
|
||||||
{
|
|
||||||
TunnelStateData *tunnelState = (TunnelStateData *)data;
|
|
||||||
debugs(26, 3, conn << ", flag=" << flag);
|
|
||||||
+ tunnelState->server.writer = NULL;
|
|
||||||
assert(tunnelState->waitingForConnectRequest());
|
|
||||||
|
|
||||||
if (flag != COMM_OK) {
|
|
||||||
@@ -768,7 +797,7 @@
|
|
||||||
else {
|
|
||||||
AsyncCall::Pointer call = commCbCall(5,5, "tunnelConnectedWriteDone",
|
|
||||||
CommIoCbPtrFun(tunnelConnectedWriteDone, tunnelState));
|
|
||||||
- Comm::Write(tunnelState->client.conn, conn_established, strlen(conn_established), call, NULL);
|
|
||||||
+ tunnelState->client.write(conn_established, strlen(conn_established), call, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -955,29 +984,20 @@
|
|
||||||
debugs(11, 2, "Tunnel Server REQUEST: " << tunnelState->server.conn << ":\n----------\n" <<
|
|
||||||
Raw("tunnelRelayConnectRequest", mb.content(), mb.contentSize()) << "\n----------");
|
|
||||||
|
|
||||||
- if (tunnelState->clientExpectsConnectResponse()) {
|
|
||||||
- // hack: blindly tunnel peer response (to our CONNECT request) to the client as ours.
|
|
||||||
- AsyncCall::Pointer writeCall = commCbCall(5,5, "tunnelConnectedWriteDone",
|
|
||||||
- CommIoCbPtrFun(tunnelConnectedWriteDone, tunnelState));
|
|
||||||
- Comm::Write(srv, &mb, writeCall);
|
|
||||||
- } else {
|
|
||||||
- // we have to eat the connect response from the peer (so that the client
|
|
||||||
- // does not see it) and only then start shoveling data to the client
|
|
||||||
- AsyncCall::Pointer writeCall = commCbCall(5,5, "tunnelConnectReqWriteDone",
|
|
||||||
- CommIoCbPtrFun(tunnelConnectReqWriteDone,
|
|
||||||
- tunnelState));
|
|
||||||
- Comm::Write(srv, &mb, writeCall);
|
|
||||||
- tunnelState->connectReqWriting = true;
|
|
||||||
-
|
|
||||||
- tunnelState->connectRespBuf = new MemBuf;
|
|
||||||
- // SQUID_TCP_SO_RCVBUF: we should not accumulate more than regular I/O buffer
|
|
||||||
- // can hold since any CONNECT response leftovers have to fit into server.buf.
|
|
||||||
- // 2*SQUID_TCP_SO_RCVBUF: HttpMsg::parse() zero-terminates, which uses space.
|
|
||||||
- tunnelState->connectRespBuf->init(SQUID_TCP_SO_RCVBUF, 2*SQUID_TCP_SO_RCVBUF);
|
|
||||||
- tunnelState->readConnectResponse();
|
|
||||||
-
|
|
||||||
- assert(tunnelState->waitingForConnectExchange());
|
|
||||||
- }
|
|
||||||
+ AsyncCall::Pointer writeCall = commCbCall(5,5, "tunnelConnectReqWriteDone",
|
|
||||||
+ CommIoCbPtrFun(tunnelConnectReqWriteDone, tunnelState));
|
|
||||||
+
|
|
||||||
+ tunnelState->server.write(mb.buf, mb.size, writeCall, mb.freeFunc());
|
|
||||||
+ tunnelState->connectReqWriting = true;
|
|
||||||
+
|
|
||||||
+ tunnelState->connectRespBuf = new MemBuf;
|
|
||||||
+ // SQUID_TCP_SO_RCVBUF: we should not accumulate more than regular I/O buffer
|
|
||||||
+ // can hold since any CONNECT response leftovers have to fit into server.buf.
|
|
||||||
+ // 2*SQUID_TCP_SO_RCVBUF: HttpMsg::parse() zero-terminates, which uses space.
|
|
||||||
+ tunnelState->connectRespBuf->init(SQUID_TCP_SO_RCVBUF, 2*SQUID_TCP_SO_RCVBUF);
|
|
||||||
+ tunnelState->readConnectResponse();
|
|
||||||
+
|
|
||||||
+ assert(tunnelState->waitingForConnectExchange());
|
|
||||||
|
|
||||||
AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "tunnelTimeout",
|
|
||||||
CommTimeoutCbPtrFun(tunnelTimeout, tunnelState));
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user