Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Tunnel Server RESPONSE dumps #1975

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

eduard-bagdasaryan
Copy link
Contributor

Level-2 "Tunnel Server RESPONSE:..." debugs() incorrectly assumed that
its readBuf parameter contained hdr_sz header bytes. In reality, by the
time code reached that debugs(), readBuf no longer had any header bytes
(and often had no bytes at all). Besides broken header dumps, this bug
could lead to problems that Valgrind reports as "Conditional jump or
move depends on uninitialised value" in DebugChannel::writeToStream().

This fix mimics HttpStateData::processReplyHeader() reporting code,
including its known problems. Future changes should address those
problems and reduce code duplication across at least ten functions
containing similar "decorated" level-2 message dumps.

"Tunnel Server RESPONSE" debugs() in Http::Tunneler::handleResponse()
incorrectly assumed that readBuf contained hdr_sz bytes, but in reality
it contains no header bytes and usually is empty. To avoid such problems
we must pair rawContent() with the SBuf's length().
Adjusted Http::Tunneler::handleResponse() in line with a similar
HttpStateData::processReplyHeader().
Copy link
Contributor

@rousskov rousskov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for fixing this bug. I believe this PR explicit decision to duplicate old/known HttpStateData::processReplyHeader() problems (for now) is an acceptable step forward. I hope to find the time to fix those old problems (in dedicated PRs), and this PR facilitates those future fixes.

FWIW, here is a sample of Valgrind message that discovered the bug fixed by this PR:

Conditional jump or move depends on uninitialised value(s)
   at 0x484ED28: strlen (vg_replace_strmem.c:494)
   by 0x529FD30: __vfprintf_internal (vfprintf-internal.c:1517)
   by 0x52896C9: fprintf (fprintf.c:32)
   by 0xA0AAAC: DebugChannel::writeToStream(_IO_FILE&, DebugMessageHeader const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (debug.cc:615)
   by 0xA0AB70: CacheLogChannel::write(DebugMessageHeader const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (debug.cc:640)
   by 0xA0A38A: DebugChannel::log(DebugMessageHeader const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (debug.cc:550)
   by 0xA09F80: DebugModule::log(DebugMessageHeader const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (debug.cc:449)
   by 0xA0B226: Debug::LogMessage(Debug::Context const&) (debug.cc:818)
   by 0xA0C752: Debug::Finish() (debug.cc:1392)
   by 0x829226: Http::Tunneler::handleResponse(bool) (HttpTunneler.cc:317)
   by 0x82863C: Http::Tunneler::handleReadyRead(CommIoCbParams const&) (HttpTunneler.cc:230)
   by 0x82B922: CommCbMemFunT<Http::Tunneler, CommIoCbParams>::doDial() (CommCalls.h:190)
   by 0x82BB14: JobDialer<Http::Tunneler>::dial(AsyncCall&) (AsyncJobCalls.h:176)
   by 0x82B668: AsyncCallT<CommCbMemFunT<Http::Tunneler, CommIoCbParams> >::fire() (AsyncCall.h:148)
   by 0x870970: AsyncCall::make() (AsyncCall.cc:44)
   by 0x871F2F: AsyncCallQueue::fire() (AsyncCallQueue.cc:27)
   by 0x5B2D80: EventLoop::dispatchCalls() (EventLoop.cc:144)
   by 0x5B2C8C: EventLoop::runOnce() (EventLoop.cc:121)
   by 0x5B2ADF: EventLoop::run() (EventLoop.cc:83)
   by 0x70FDC4: SquidMain(int, char**) (main.cc:1727)
   by 0x70EC4E: SquidMainSafe(int, char**) (main.cc:1351)
   by 0x70EC08: main (main.cc:1339)

HttpReply::Pointer rep = new HttpReply;
rep->sources |= Http::Message::srcHttp;
rep->sline.set(hp->messageProtocol(), hp->messageStatus());
if (!rep->parseHeader(*hp) && rep->sline.status() == Http::scOkay) {
bailOnResponseError("malformed CONNECT response from peer", nullptr);
bailOnResponseError("malformed CONNECT response headers mime block from peer", nullptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This specific change makes this bailOnResponseError() reason distinct from !parsedOk reason. The adjusted wording is a bit awkward, but it now matches the wording used by HttpStateData::processReplyHeader(). Since this PR reuses relevant processReplyHeader() code (with all its problems), I think this is the right change; it and can be viewed as being in this PR scope.

This comment does not request any changes.

@rousskov rousskov added M-cleared-for-merge https://github.com/measurement-factory/anubis#pull-request-labels S-could-use-an-approval An approval may speed this PR merger (but is not required) labels Dec 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
M-cleared-for-merge https://github.com/measurement-factory/anubis#pull-request-labels S-could-use-an-approval An approval may speed this PR merger (but is not required)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants