From: Amos Jeffries Date: Wed, 13 Aug 2014 14:35:32 +0000 (-0700) Subject: Rearrange PROXY/1.0 parser X-Git-Tag: SQUID_3_5_0_1~75^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=154ea56667e82cf7217580817f9088397a86a694;p=thirdparty%2Fsquid.git Rearrange PROXY/1.0 parser Add a first pass to confirm LF line terminator and wait for more bytes if missing. --- diff --git a/src/client_side.cc b/src/client_side.cc index 3945381553..a183790db2 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2986,17 +2986,33 @@ ConnStateData::parseProxy1p0() ::Parser::Tokenizer tok(in.buf); tok.skip(Proxy1p0magic); + // skip to first LF (assumes it is part of CRLF) + static const CharacterSet lineContent = CharacterSet::LF.complement("non-LF"); + SBuf line; + if (tok.prefix(line, lineContent, 107-Proxy1p0magic.length())) { + if (tok.skip('\n')) { + // found valid header + in.buf = tok.remaining(); + needProxyProtocolHeader_ = false; + // reset the tokenizer to work on found line only. + tok.reset(line); + } else + return false; // no LF yet + + } else // protocol error only if there are more than 107 bytes prefix header + return proxyProtocolError(in.buf.length() > 107? "PROXY/1.0 error: missing CRLF" : NULL); + static const SBuf unknown("UNKNOWN"), tcpName("TCP"); if (tok.skip(tcpName)) { // skip TCP/IP version number static const CharacterSet tcpVersions("TCP-version","46"); if(!tok.skipOne(tcpVersions)) - return proxyProtocolError(tok.atEnd() ? "PROXY/1.0 error: missing TCP version" : NULL); + return proxyProtocolError("PROXY/1.0 error: missing TCP version"); // skip SP after protocol version if (!tok.skip(' ')) - return proxyProtocolError(tok.atEnd() ? "PROXY/1.0 error: missing SP" : NULL); + return proxyProtocolError("PROXY/1.0 error: missing SP"); SBuf ipa, ipb; int64_t porta, portb; @@ -3010,13 +3026,7 @@ ConnStateData::parseProxy1p0() tok.int64(portb) && tok.skip('\r'); if (!correct) - return proxyProtocolError(!tok.atEnd() ? "PROXY/1.0 error: invalid syntax" : NULL); - - if (!tok.skip('\n')) // line terminator. - return proxyProtocolError("PROXY/1.0 error: missing LF"); - - in.buf = tok.remaining(); // sync buffers - needProxyProtocolHeader_ = false; // found successfully + return proxyProtocolError("PROXY/1.0 error: invalid syntax"); // parse IP and port strings Ip::Address originalClient, originalDest; @@ -3052,23 +3062,11 @@ ConnStateData::parseProxy1p0() return true; } else if (tok.skip(unknown)) { - // skip to first LF (assumes it is part of CRLF) - const SBuf::size_type pos = in.buf.findFirstOf(CharacterSet::LF); - if (pos != SBuf::npos) { - if (in.buf[pos-1] != '\r') - return proxyProtocolError("PROXY/1.0 error: missing CR"); - // found valid but unusable header - in.buf.consume(pos); - needProxyProtocolHeader_ = false; - return true; - } - // else, no LF found - - // protocol error only if there are more than 107 bytes prefix header - return proxyProtocolError(in.buf.length() > 107? "PROXY/1.0 error: missing CRLF":NULL); + // found valid but unusable header + return true; } else - return proxyProtocolError(tok.atEnd() ? "PROXY/1.0 error: invalid protocol family" : NULL); + return proxyProtocolError("PROXY/1.0 error: invalid protocol family"); return false; }