For details see: http://www.squid-cache.org/Versions/v3/3.5/changesets/
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org --- lfs/squid | 5 + src/patches/squid/squid-3.5-14057.patch | 132 ++++++ src/patches/squid/squid-3.5-14058.patch | 732 ++++++++++++++++++++++++++++++++ src/patches/squid/squid-3.5-14059.patch | 49 +++ src/patches/squid/squid-3.5-14060.patch | 117 +++++ src/patches/squid/squid-3.5-14061.patch | 237 +++++++++++ 6 files changed, 1272 insertions(+) create mode 100644 src/patches/squid/squid-3.5-14057.patch create mode 100644 src/patches/squid/squid-3.5-14058.patch create mode 100644 src/patches/squid/squid-3.5-14059.patch create mode 100644 src/patches/squid/squid-3.5-14060.patch create mode 100644 src/patches/squid/squid-3.5-14061.patch
diff --git a/lfs/squid b/lfs/squid index edaf943..c2b899e 100644 --- a/lfs/squid +++ b/lfs/squid @@ -76,6 +76,11 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14054.patch cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14055.patch cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14056.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14057.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14058.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14059.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14060.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14061.patch cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid-3.5.17-fix-max-file-descriptors.patch
cd $(DIR_APP) && autoreconf -vfi diff --git a/src/patches/squid/squid-3.5-14057.patch b/src/patches/squid/squid-3.5-14057.patch new file mode 100644 index 0000000..fd4ddc3 --- /dev/null +++ b/src/patches/squid/squid-3.5-14057.patch @@ -0,0 +1,132 @@ +------------------------------------------------------------ +revno: 14057 +revision-id: squid3@treenet.co.nz-20160524200503-1nn3hijw86ti726r +parent: squid3@treenet.co.nz-20160521172919-du6cbdirqcxdjbtr +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4485 +author: Eduard Bagdasaryan eduard.bagdasaryan@measurement-factory.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Wed 2016-05-25 08:05:03 +1200 +message: + Bug 4485: off-by-one out-of-bounds Parser::Tokenizer::int64() read errors +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20160524200503-1nn3hijw86ti726r +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: a7a643f09c2d39665e013fc7a6bc87577f0890e0 +# timestamp: 2016-05-24 20:51:02 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20160521172919-\ +# du6cbdirqcxdjbtr +# +# Begin patch +=== modified file 'src/parser/Tokenizer.cc' +--- src/parser/Tokenizer.cc 2016-01-01 00:14:27 +0000 ++++ src/parser/Tokenizer.cc 2016-05-24 20:05:03 +0000 +@@ -111,8 +111,9 @@ + } else if (*s == '+') { + ++s; + } ++ + if (s >= end) return false; +- if (( base == 0 || base == 16) && *s == '0' && (s+1 <= end ) && ++ if (( base == 0 || base == 16) && *s == '0' && (s+1 < end ) && + tolower(*(s+1)) == 'x') { + s += 2; + base = 16; +@@ -135,7 +136,8 @@ + + int any = 0, c; + int64_t acc = 0; +- for (c = *s++; s <= end; c = *s++) { ++ do { ++ c = *s; + if (xisdigit(c)) { + c -= '0'; + } else if (xisalpha(c)) { +@@ -152,7 +154,7 @@ + acc *= base; + acc += c; + } +- } ++ } while (++s < end); + + if (any == 0) // nothing was parsed + return false; +@@ -164,6 +166,6 @@ + acc = -acc; + + result = acc; +- return success(s - buf_.rawContent() - 1); ++ return success(s - buf_.rawContent()); + } + + +=== modified file 'src/tests/testTokenizer.cc' +--- src/tests/testTokenizer.cc 2016-01-01 00:14:27 +0000 ++++ src/tests/testTokenizer.cc 2016-05-24 20:05:03 +0000 +@@ -144,6 +144,7 @@ + const int64_t benchmark = 1234; + CPPUNIT_ASSERT(t.int64(rv, 10)); + CPPUNIT_ASSERT_EQUAL(benchmark,rv); ++ CPPUNIT_ASSERT(t.buf().isEmpty()); + } + + // successful parse, autodetect base +@@ -153,6 +154,7 @@ + const int64_t benchmark = 1234; + CPPUNIT_ASSERT(t.int64(rv)); + CPPUNIT_ASSERT_EQUAL(benchmark,rv); ++ CPPUNIT_ASSERT(t.buf().isEmpty()); + } + + // successful parse, autodetect base +@@ -162,6 +164,7 @@ + const int64_t benchmark = 01234; + CPPUNIT_ASSERT(t.int64(rv)); + CPPUNIT_ASSERT_EQUAL(benchmark,rv); ++ CPPUNIT_ASSERT(t.buf().isEmpty()); + } + + // successful parse, autodetect base +@@ -171,6 +174,7 @@ + const int64_t benchmark = 0x12f4; + CPPUNIT_ASSERT(t.int64(rv)); + CPPUNIT_ASSERT_EQUAL(benchmark,rv); ++ CPPUNIT_ASSERT(t.buf().isEmpty()); + } + + // API mismatch: don't eat leading space +@@ -178,6 +182,7 @@ + int64_t rv; + Parser::Tokenizer t(SBuf(" 1234")); + CPPUNIT_ASSERT(!t.int64(rv)); ++ CPPUNIT_ASSERT_EQUAL(SBuf(" 1234"), t.buf()); + } + + // API mismatch: don't eat multiple leading spaces +@@ -185,6 +190,7 @@ + int64_t rv; + Parser::Tokenizer t(SBuf(" 1234")); + CPPUNIT_ASSERT(!t.int64(rv)); ++ CPPUNIT_ASSERT_EQUAL(SBuf(" 1234"), t.buf()); + } + + // trailing spaces +@@ -222,6 +228,7 @@ + int64_t rv; + Parser::Tokenizer t(SBuf("1029397752385698678762234")); + CPPUNIT_ASSERT(!t.int64(rv)); ++ CPPUNIT_ASSERT_EQUAL(SBuf("1029397752385698678762234"), t.buf()); + } + + // buffered sub-string parsing +@@ -233,6 +240,7 @@ + CPPUNIT_ASSERT_EQUAL(SBuf("22"),t.buf()); + CPPUNIT_ASSERT(t.int64(rv)); + CPPUNIT_ASSERT_EQUAL(benchmark,rv); ++ CPPUNIT_ASSERT(t.buf().isEmpty()); + } + + // base-16, prefix + diff --git a/src/patches/squid/squid-3.5-14058.patch b/src/patches/squid/squid-3.5-14058.patch new file mode 100644 index 0000000..451b964 --- /dev/null +++ b/src/patches/squid/squid-3.5-14058.patch @@ -0,0 +1,732 @@ +------------------------------------------------------------ +revno: 14058 +revision-id: squid3@treenet.co.nz-20160615220816-yqh6bmry6ijvfwi1 +parent: squid3@treenet.co.nz-20160524200503-1nn3hijw86ti726r +author: Alex Rousskov rousskov@measurement-factory.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Thu 2016-06-16 10:08:16 +1200 +message: + Do not allow low-level debugging to hide important/critical messages. + + Removed debugs() side effects that inadvertently resulted in some + important/critical messages logged at the wrong debugging level and, + hence, becoming invisible to the admin. The removed side effects set the + "current" debugging level when a debugs() parameter called a function + that also called debugs(). The last nested debugs() called affected the + level of all debugs() still in progress! + + Related changes: + + * Reentrant debugging messages no longer clobber parent messages. Each + debugging message is logged separately, in the natural order of + debugs() calls that would have happened if debugs() were a function + (that gets already evaluated arguments) and not a macro (that + evaluates its arguments in the middle of the call). This order is + "natural" because good macros work like functions from the caller + point of view. + + * Assertions hit while evaluating debugs() parameters are now logged + instead of being lost with the being-built debugs() log line. + + * 10-20% faster debugs() performance because we no longer allocate a new + std::ostringstream buffer for the vast majority of debugs() calls. + Only reentrant calls get a new buffer. + + * Removed old_debug(), addressing an old "needs to die" to-do. + + * Removed do_debug() that changed debugging level while testing whether + debugging is needed. Use side-effect-free Debug::Enabled() instead. + + Also removed the OutStream wrapper class. The wrapper was added in trunk + revision 13767 that promised to (but did not?) MemPool the debug output + buffers. We no longer "new" the buffer stream so a custom new() method + would be unused. Besides, the r13767 explanation implied that providing + a Child::new() method would somehow overwrite Parent::allocator_type, + which did not compute for me. Finally, Squid "new"s other allocator- + enabled STL objects without overriding their new methods so either the + same problem is still there or it did not exist (or was different?). + + Also removed Debug::xassert() because the debugs() assertions now work + OK without that hack. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20160615220816-yqh6bmry6ijvfwi1 +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: 1d7a703d3dfe6ebd05138880652ab78c3260a323 +# timestamp: 2016-06-15 22:51:04 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20160524200503-\ +# 1nn3hijw86ti726r +# +# Begin patch +=== modified file 'src/Debug.h' +--- src/Debug.h 2016-01-01 00:14:27 +0000 ++++ src/Debug.h 2016-06-15 22:08:16 +0000 +@@ -49,38 +49,51 @@ + { + + public: ++ /// meta-information for debugs() or a similar debugging call ++ class Context ++ { ++ public: ++ Context(const int aSectionLevel, const int aLevel); ++ ++ int level; ///< minimum debugging level required by the debugs() call ++ int sectionLevel; ///< maximum debugging level allowed during the call ++ ++ private: ++ friend class Debug; ++ void rewind(const int aSection, const int aLevel); ++ void formatStream(); ++ Context *upper; ///< previous or parent record in nested debugging calls ++ std::ostringstream buf; ///< debugs() output sink ++ }; ++ ++ /// whether debugging the given section and the given level produces output ++ static bool Enabled(const int section, const int level) ++ { ++ return level <= Debug::Levels[section]; ++ } ++ + static char *debugOptions; + static char *cache_log; + static int rotateNumber; + static int Levels[MAX_DEBUG_SECTIONS]; +- static int level; ///< minimum debugging level required by debugs() call +- static int sectionLevel; ///< maximum debugging level allowed now + static int override_X; + static int log_stderr; + static bool log_syslog; + +- static std::ostream &getDebugOut(); +- static void finishDebug(); + static void parseOptions(char const *); + ++ /// minimum level required by the current debugs() call ++ static int Level() { return Current ? Current->level : 1; } ++ /// maximum level currently allowed ++ static int SectionLevel() { return Current ? Current->sectionLevel : 1; } ++ ++ /// opens debugging context and returns output buffer ++ static std::ostringstream &Start(const int section, const int level); ++ /// logs output buffer created in Start() and closes debugging context ++ static void Finish(); ++ + private: +- // Hack: replaces global ::xassert() to debug debugging assertions +- static void xassert(const char *msg, const char *file, int line); +- +- /// Wrapper class to prevent SquidNew.h overrides getting confused +- /// with the libc++6 std::ostringstream definitions +- class OutStream : public std::ostringstream +- { +- // XXX: use MEMPROXY_CLASS() once that no longer pulls in typedefs.h and enums.h and globals.h +- public: +- void *operator new(size_t size) throw(std::bad_alloc) {return xmalloc(size);} +- void operator delete(void *address) throw() {xfree(address);} +- void *operator new[] (size_t size) throw(std::bad_alloc) ; //{return xmalloc(size);} +- void operator delete[] (void *address) throw() ; // {xfree(address);} +- }; +- +- static OutStream *CurrentDebug; +- static int TheDepth; // level of nested debugging calls ++ static Context *Current; ///< deepest active context; nil outside debugs() + }; + + extern FILE *debug_log; +@@ -91,15 +104,15 @@ + /* Debug stream */ + #define debugs(SECTION, LEVEL, CONTENT) \ + do { \ +- if ((Debug::level = (LEVEL)) <= Debug::Levels[SECTION]) { \ +- Debug::sectionLevel = Debug::Levels[SECTION]; \ +- std::ostream &_dbo=Debug::getDebugOut(); \ +- if (Debug::level > DBG_IMPORTANT) { \ +- _dbo << (SECTION) << ',' << (LEVEL) << "| " \ ++ const int _dbg_level = (LEVEL); \ ++ if (Debug::Enabled((SECTION), _dbg_level)) { \ ++ std::ostream &_dbo = Debug::Start((SECTION), _dbg_level); \ ++ if (_dbg_level > DBG_IMPORTANT) { \ ++ _dbo << (SECTION) << ',' << _dbg_level << "| " \ + << SkipBuildPrefix(__FILE__)<<"("<<__LINE__<<") "<<__FUNCTION__<<": "; \ + } \ + _dbo << CONTENT; \ +- Debug::finishDebug(); \ ++ Debug::Finish(); \ + } \ + } while (/*CONSTCOND*/ 0) + +@@ -135,10 +148,6 @@ + return (os << (int)d); + } + +-/* Legacy debug style. Still used in some places. needs to die... */ +-#define do_debug(SECTION, LEVEL) ((Debug::level = (LEVEL)) <= Debug::Levels[SECTION]) +-#define old_debug(SECTION, LEVEL) if do_debug((SECTION), (LEVEL)) _db_print +- + /* Legacy debug function definitions */ + void _db_init(const char *logfile, const char *options); + void _db_print(const char *,...) PRINTF_FORMAT_ARG1; + +=== modified file 'src/adaptation/ecap/Host.cc' +--- src/adaptation/ecap/Host.cc 2016-02-23 15:58:54 +0000 ++++ src/adaptation/ecap/Host.cc 2016-06-15 22:08:16 +0000 +@@ -147,18 +147,16 @@ + { + const int squidLevel = SquidLogLevel(lv); + const int squidSection = 93; // XXX: this should be a global constant +- // XXX: Debug.h should provide this to us +- if ((Debug::level = squidLevel) <= Debug::Levels[squidSection]) +- return &Debug::getDebugOut(); +- else +- return NULL; ++ return Debug::Enabled(squidSection, squidLevel) ? ++ &Debug::Start(squidSection, squidLevel) : ++ NULL; + } + + void + Adaptation::Ecap::Host::closeDebug(std::ostream *debug) + { + if (debug) +- Debug::finishDebug(); ++ Debug::Finish(); + } + + Adaptation::Ecap::Host::MessagePtr + +=== modified file 'src/base/Lock.h' +--- src/base/Lock.h 2016-01-01 00:14:27 +0000 ++++ src/base/Lock.h 2016-06-15 22:08:16 +0000 +@@ -33,7 +33,7 @@ + /// All locks must be cleared before it may be destroyed. + void lock() const { + #if defined(LOCKCOUNT_DEBUG) +- old_debug(0,1)("Incrementing this %p from count %u\n",this,count_); ++ debugs(0,1, "Incrementing this " << static_cast<void*>(this) << " from count " << count_); + #endif + assert(count_ < UINT32_MAX); + ++count_; +@@ -43,7 +43,7 @@ + /// All locks must be cleared before it may be destroyed. + uint32_t unlock() const { + #if defined(LOCKCOUNT_DEBUG) +- old_debug(0,1)("Decrementing this %p from count %u\n",this,count_); ++ debugs(0,1, "Decrementing this " << static_cast<void*>(this) << " from count " << count_); + #endif + assert(count_ > 0); + return --count_; + +=== modified file 'src/client_side.cc' +--- src/client_side.cc 2016-05-02 10:51:18 +0000 ++++ src/client_side.cc 2016-06-15 22:08:16 +0000 +@@ -3778,7 +3778,7 @@ + debugs(83, 2, "clientNegotiateSSL: Session " << SSL_get_session(ssl) << + " reused on FD " << fd << " (" << fd_table[fd].ipaddr << ":" << (int)fd_table[fd].remote_port << ")"); + } else { +- if (do_debug(83, 4)) { ++ if (Debug::Enabled(83, 4)) { + /* Write out the SSL session details.. actually the call below, but + * OpenSSL headers do strange typecasts confusing GCC.. */ + /* PEM_write_SSL_SESSION(debug_log, SSL_get_session(ssl)); */ + +=== modified file 'src/debug.cc' +--- src/debug.cc 2016-03-23 14:46:37 +0000 ++++ src/debug.cc 2016-06-15 22:08:16 +0000 +@@ -22,8 +22,6 @@ + int Debug::log_stderr = -1; + bool Debug::log_syslog = false; + int Debug::Levels[MAX_DEBUG_SECTIONS]; +-int Debug::level; +-int Debug::sectionLevel; + char *Debug::cache_log = NULL; + int Debug::rotateNumber = -1; + FILE *debug_log = NULL; +@@ -134,7 +132,7 @@ + static void + _db_print_stderr(const char *format, va_list args) + { +- if (Debug::log_stderr < Debug::level) ++ if (Debug::log_stderr < Debug::Level()) + return; + + if (debug_log == stderr) +@@ -149,7 +147,7 @@ + { + /* level 0,1 go to syslog */ + +- if (Debug::level > 1) ++ if (Debug::Level() > 1) + return; + + if (!Debug::log_syslog) +@@ -162,7 +160,7 @@ + + tmpbuf[BUFSIZ - 1] = '\0'; + +- syslog(Debug::level == 0 ? LOG_WARNING : LOG_NOTICE, "%s", tmpbuf); ++ syslog(Debug::Level() == 0 ? LOG_WARNING : LOG_NOTICE, "%s", tmpbuf); + } + #endif /* HAVE_SYSLOG */ + +@@ -512,7 +510,7 @@ + static char buf[128]; + static time_t last_t = 0; + +- if (Debug::level > 1) { ++ if (Debug::Level() > 1) { + char buf2[128]; + tm = localtime(&t); + strftime(buf2, 127, "%Y/%m/%d %H:%M:%S", tm); +@@ -714,55 +712,75 @@ + return Ctx_Descrs[ctx] ? Ctx_Descrs[ctx] : "<null>"; + } + +-int Debug::TheDepth = 0; +- +-Debug::OutStream *Debug::CurrentDebug(NULL); +- +-std::ostream & +-Debug::getDebugOut() +-{ +- assert(TheDepth >= 0); +- ++TheDepth; +- if (TheDepth > 1) { +- assert(CurrentDebug); +- *CurrentDebug << std::endl << "reentrant debuging " << TheDepth << "-{"; +- } else { +- assert(!CurrentDebug); +- CurrentDebug = new Debug::OutStream; +- // set default formatting flags +- CurrentDebug->setf(std::ios::fixed); +- CurrentDebug->precision(2); +- } +- return *CurrentDebug; +-} +- +-void +-Debug::finishDebug() +-{ +- assert(TheDepth >= 0); +- assert(CurrentDebug); +- if (TheDepth > 1) { +- *CurrentDebug << "}-" << TheDepth << std::endl; +- } else { +- assert(TheDepth == 1); +- _db_print("%s\n", CurrentDebug->str().c_str()); +- delete CurrentDebug; +- CurrentDebug = NULL; +- } +- --TheDepth; +-} +- +-// Hack: replaces global ::xassert() to debug debugging assertions +-// Relies on assert macro calling xassert() without a specific scope. +-void +-Debug::xassert(const char *msg, const char *file, int line) +-{ +- +- if (CurrentDebug) { +- *CurrentDebug << "assertion failed: " << file << ":" << line << +- ": "" << msg << """; +- } +- abort(); ++Debug::Context *Debug::Current = NULL; ++ ++Debug::Context::Context(const int aSection, const int aLevel): ++ level(aLevel), ++ sectionLevel(Levels[aSection]), ++ upper(Current) ++{ ++ formatStream(); ++} ++ ++/// Optimization: avoids new Context creation for every debugs(). ++void ++Debug::Context::rewind(const int aSection, const int aLevel) ++{ ++ level = aLevel; ++ sectionLevel = Levels[aSection]; ++ assert(upper == Current); ++ ++ buf.str(std::string()); ++ buf.clear(); ++ // debugs() users are supposed to preserve format, but ++ // some do not, so we have to waste cycles resetting it for all. ++ formatStream(); ++} ++ ++/// configures default formatting for the debugging stream ++void ++Debug::Context::formatStream() ++{ ++ const static std::ostringstream cleanStream; ++ buf.flags(cleanStream.flags() | std::ios::fixed); ++ buf.width(cleanStream.width()); ++ buf.precision(2); ++ buf.fill(' '); ++ // If this is not enough, use copyfmt(cleanStream) which is ~10% slower. ++} ++ ++std::ostringstream & ++Debug::Start(const int section, const int level) ++{ ++ Context *future = NULL; ++ ++ // prepare future context ++ if (Current) { ++ // all reentrant debugs() calls get here; create a dedicated context ++ future = new Context(section, level); ++ } else { ++ // Optimization: Nearly all debugs() calls get here; avoid allocations ++ static Context *topContext = new Context(1, 1); ++ topContext->rewind(section, level); ++ future = topContext; ++ } ++ ++ Current = future; ++ ++ return future->buf; ++} ++ ++void ++Debug::Finish() ++{ ++ // TODO: Optimize to remove at least one extra copy. ++ _db_print("%s\n", Current->buf.str().c_str()); ++ ++ Context *past = Current; ++ Current = past->upper; ++ if (Current) ++ delete past; ++ // else it was a static topContext from Debug::Start() + } + + size_t +@@ -799,8 +817,8 @@ + + // finalize debugging level if no level was set explicitly via minLevel() + const int finalLevel = (level >= 0) ? level : +- (size_ > 40 ? DBG_DATA : Debug::sectionLevel); +- if (finalLevel <= Debug::sectionLevel) { ++ (size_ > 40 ? DBG_DATA : Debug::SectionLevel()); ++ if (finalLevel <= Debug::SectionLevel()) { + os << (label_ ? '=' : ' '); + if (data_) + os.write(data_, size_); + +=== modified file 'src/esi/Expression.cc' +--- src/esi/Expression.cc 2016-01-01 00:14:27 +0000 ++++ src/esi/Expression.cc 2016-06-15 22:08:16 +0000 +@@ -116,8 +116,6 @@ + static int membercompare(stackmember a, stackmember b); + static char const *trim(char const *s); + static stackmember getsymbol(const char *s, char const **endptr); +-static void printliteral(stackmember s); +-static void printmember(stackmember s); + + /* -2 = failed to compate + * -1 = a less than b +@@ -846,105 +844,106 @@ + return rv; + } + +-void +-printliteral(stackmember s) ++static void ++printLiteral(std::ostream &os, const stackmember &s) + { + switch (s.valuestored) { + + case ESI_LITERAL_INVALID: +- old_debug(86, 1)( " Invalid " ); ++ os << " Invalid "; + break; + + case ESI_LITERAL_FLOAT: +- old_debug(86,1)("%f", s.value.floating); ++ os << s.value.floating; + break; + + case ESI_LITERAL_STRING: +- old_debug(86,1)("'%s'", s.value.string); ++ os << ''' << s.value.string << '''; + break; + + case ESI_LITERAL_INT: +- old_debug(86,1)("%d", s.value.integral); ++ os << s.value.integral; + break; + + case ESI_LITERAL_BOOL: +- old_debug(86,1)("%s",s.value.integral ? "true" : "false"); ++ os << (s.value.integral ? "true" : "false"); + } + } + +-void +-printmember(stackmember s) ++static std::ostream & ++operator <<(std::ostream &os, const stackmember &s) + { + switch (s.valuetype) { + + case ESI_EXPR_INVALID: +- old_debug(86,1)(" Invalid "); ++ os << " Invalid "; + break; + + case ESI_EXPR_LITERAL: +- printliteral(s); ++ printLiteral(os, s); + break; + + case ESI_EXPR_EXPR: +- old_debug(86,1)("%s", s.value.integral ? "true" : "false"); ++ os << (s.value.integral ? "true" : "false"); + break; + + case ESI_EXPR_OR: +- old_debug(86,1)("|"); ++ os << "|"; + break; + + case ESI_EXPR_AND: +- old_debug(86,1)("&"); ++ os << "&"; + break; + + case ESI_EXPR_NOT: +- old_debug(86,1)("!"); ++ os << "!"; + break; + + case ESI_EXPR_START: +- old_debug(86,1)("("); ++ os << "("; + break; + + case ESI_EXPR_END: +- old_debug(86,1)(")"); ++ os << ")"; + break; + + case ESI_EXPR_EQ: +- old_debug(86,1)("=="); ++ os << "=="; + break; + + case ESI_EXPR_NOTEQ: +- old_debug(86,1)("!="); ++ os << "!="; + break; + + case ESI_EXPR_LESS: +- old_debug(86,1)("<"); ++ os << "<"; + break; + + case ESI_EXPR_LESSEQ: +- old_debug(86,1)("<="); ++ os << "<="; + break; + + case ESI_EXPR_MORE: +- old_debug(86,1)(">"); ++ os << ">"; + break; + + case ESI_EXPR_MOREEQ: +- old_debug(86,1)(">="); ++ os << ">="; + break; + } ++ ++ return os; + } + + void + dumpstack(stackmember * stack, int depth) + { +- int i; +- +- for (i = 0; i < depth; ++i) +- printmember(stack[i]); +- +- if (depth) +- old_debug(86,1)("\n"); ++ if (depth) { ++ std::ostringstream buf; ++ for (int i = 0; i < depth; ++i) ++ buf << stack[i]; ++ debugs(86,1, buf.str()); ++ } + } + + int + +=== modified file 'src/servers/FtpServer.cc' +--- src/servers/FtpServer.cc 2016-03-23 15:43:55 +0000 ++++ src/servers/FtpServer.cc 2016-06-15 22:08:16 +0000 +@@ -1303,7 +1303,7 @@ + Must(header.has(HDR_FTP_ARGUMENTS)); + String ¶ms = header.findEntry(HDR_FTP_ARGUMENTS)->value; + +- if (do_debug(9, 2)) { ++ if (Debug::Enabled(9, 2)) { + MemBuf mb; + Packer p; + mb.init(); + +=== modified file 'src/ssl/support.cc' +--- src/ssl/support.cc 2016-04-19 15:04:09 +0000 ++++ src/ssl/support.cc 2016-06-15 22:08:16 +0000 +@@ -135,7 +135,7 @@ + } + + if (newkey) { +- if (do_debug(83, 5)) ++ if (Debug::Enabled(83, 5)) + PEM_write_RSAPrivateKey(debug_log, rsa, NULL, NULL, 0, NULL, NULL); + + debugs(83, DBG_IMPORTANT, "Generated ephemeral RSA key of length " << keylen); + +=== modified file 'src/tests/stub_debug.cc' +--- src/tests/stub_debug.cc 2016-01-01 00:14:27 +0000 ++++ src/tests/stub_debug.cc 2016-06-15 22:08:16 +0000 +@@ -17,14 +17,11 @@ + #include "Debug.h" + + FILE *debug_log = NULL; +-int Debug::TheDepth = 0; + + char *Debug::debugOptions; + char *Debug::cache_log= NULL; + int Debug::rotateNumber = 0; + int Debug::Levels[MAX_DEBUG_SECTIONS]; +-int Debug::level; +-int Debug::sectionLevel; + int Debug::override_X = 0; + int Debug::log_stderr = 1; + bool Debug::log_syslog = false; +@@ -81,71 +78,52 @@ + static void + _db_print_stderr(const char *format, va_list args) + { +- if (1 < Debug::level) ++ if (1 < Debug::Level()) + return; + + vfprintf(stderr, format, args); + } + +-Debug::OutStream *Debug::CurrentDebug(NULL); +- +-std::ostream & +-Debug::getDebugOut() +-{ +- assert(TheDepth >= 0); +- ++TheDepth; +- if (TheDepth > 1) { +- assert(CurrentDebug); +- *CurrentDebug << std::endl << "reentrant debuging " << TheDepth << "-{"; +- } else { +- assert(!CurrentDebug); +- CurrentDebug = new Debug::OutStream; +- // set default formatting flags +- CurrentDebug->setf(std::ios::fixed); +- CurrentDebug->precision(2); +- } +- return *CurrentDebug; +-} +- + void + Debug::parseOptions(char const *) + { + return; + } + +-void +-Debug::finishDebug() +-{ +- assert(TheDepth >= 0); +- assert(CurrentDebug); +- if (TheDepth > 1) { +- *CurrentDebug << "}-" << TheDepth << std::endl; +- } else { +- assert(TheDepth == 1); +- _db_print("%s\n", CurrentDebug->str().c_str()); +- delete CurrentDebug; +- CurrentDebug = NULL; +- } +- --TheDepth; +-} +- +-void +-Debug::xassert(const char *msg, const char *file, int line) +-{ +- +- if (CurrentDebug) { +- *CurrentDebug << "assertion failed: " << file << ":" << line << +- ": "" << msg << """; +- } +- abort(); +-} +- + const char* + SkipBuildPrefix(const char* path) + { + return path; + } + ++Debug::Context *Debug::Current = NULL; ++ ++Debug::Context::Context(const int aSection, const int aLevel): ++ level(aLevel), ++ sectionLevel(Levels[aSection]), ++ upper(Current) ++{ ++ buf.setf(std::ios::fixed); ++ buf.precision(2); ++} ++ ++std::ostringstream & ++Debug::Start(const int section, const int level) ++{ ++ Current = new Context(section, level); ++ return Current->buf; ++} ++ ++void ++Debug::Finish() ++{ ++ if (Current) { ++ _db_print("%s\n", Current->buf.str().c_str()); ++ delete Current; ++ Current = NULL; ++ } ++} ++ + std::ostream & + Raw::print(std::ostream &os) const + { +@@ -157,10 +135,13 @@ + + // finalize debugging level if no level was set explicitly via minLevel() + const int finalLevel = (level >= 0) ? level : +- (size_ > 40 ? DBG_DATA : Debug::sectionLevel); +- if (finalLevel <= Debug::sectionLevel) { ++ (size_ > 40 ? DBG_DATA : Debug::SectionLevel()); ++ if (finalLevel <= Debug::SectionLevel()) { + os << (label_ ? '=' : ' '); +- os.write(data_, size_); ++ if (data_) ++ os.write(data_, size_); ++ else ++ os << "[null]"; + } + + return os; + diff --git a/src/patches/squid/squid-3.5-14059.patch b/src/patches/squid/squid-3.5-14059.patch new file mode 100644 index 0000000..5fbd503 --- /dev/null +++ b/src/patches/squid/squid-3.5-14059.patch @@ -0,0 +1,49 @@ +------------------------------------------------------------ +revno: 14059 +revision-id: squidadm@squid-cache.org-20160616001416-jb7a6qq30tm5gpoc +parent: squid3@treenet.co.nz-20160615220816-yqh6bmry6ijvfwi1 +committer: Source Maintenance squidadm@squid-cache.org +branch nick: 3.5 +timestamp: Thu 2016-06-16 00:14:16 +0000 +message: + SourceFormat Enforcement +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squidadm@squid-cache.org-20160616001416-\ +# jb7a6qq30tm5gpoc +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: 222d2b2638e1aae18afd737bbdf56623ee8ecab3 +# timestamp: 2016-06-16 00:51:03 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20160615220816-\ +# yqh6bmry6ijvfwi1 +# +# Begin patch +=== modified file 'src/adaptation/ecap/Host.cc' +--- src/adaptation/ecap/Host.cc 2016-06-15 22:08:16 +0000 ++++ src/adaptation/ecap/Host.cc 2016-06-16 00:14:16 +0000 +@@ -148,8 +148,8 @@ + const int squidLevel = SquidLogLevel(lv); + const int squidSection = 93; // XXX: this should be a global constant + return Debug::Enabled(squidSection, squidLevel) ? +- &Debug::Start(squidSection, squidLevel) : +- NULL; ++ &Debug::Start(squidSection, squidLevel) : ++ NULL; + } + + void + +=== modified file 'src/debug.cc' +--- src/debug.cc 2016-06-15 22:08:16 +0000 ++++ src/debug.cc 2016-06-16 00:14:16 +0000 +@@ -729,7 +729,7 @@ + level = aLevel; + sectionLevel = Levels[aSection]; + assert(upper == Current); +- ++ + buf.str(std::string()); + buf.clear(); + // debugs() users are supposed to preserve format, but + diff --git a/src/patches/squid/squid-3.5-14060.patch b/src/patches/squid/squid-3.5-14060.patch new file mode 100644 index 0000000..02e8675 --- /dev/null +++ b/src/patches/squid/squid-3.5-14060.patch @@ -0,0 +1,117 @@ +------------------------------------------------------------ +revno: 14060 +revision-id: squid3@treenet.co.nz-20160618114803-m7riuy90mrdlxw1f +parent: squidadm@squid-cache.org-20160616001416-jb7a6qq30tm5gpoc +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=3579 +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Sat 2016-06-18 23:48:03 +1200 +message: + Bug 3579: assertion failed 'MemPools[type]' from dst_as ACL +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20160618114803-m7riuy90mrdlxw1f +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: cc798e8d0b4767544c21f3614ce995d435bca867 +# timestamp: 2016-06-18 11:50:56 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squidadm@squid-cache.org-20160616001416-\ +# jb7a6qq30tm5gpoc +# +# Begin patch +=== modified file 'src/PeerSelectState.h' +--- src/PeerSelectState.h 2016-01-01 00:14:27 +0000 ++++ src/PeerSelectState.h 2016-06-18 11:48:03 +0000 +@@ -38,11 +38,17 @@ + class FwdServer + { + public: ++ MEMPROXY_CLASS(FwdServer); ++ FwdServer(CachePeer *p, hier_code c) : _peer(cbdataReference(p)), code(c), next(NULL) {} ++ ~FwdServer() {cbdataReferenceDone(_peer);} ++ + CachePeer *_peer; /* NULL --> origin server */ + hier_code code; + FwdServer *next; + }; + ++MEMPROXY_CLASS_INLINE(FwdServer); ++ + class ps_state + { + + +=== modified file 'src/enums.h' +--- src/enums.h 2016-01-01 00:14:27 +0000 ++++ src/enums.h 2016-06-18 11:48:03 +0000 +@@ -170,7 +170,6 @@ + MEM_DONTFREE, + // following pools are initialized late by their component if needed (or never) + MEM_FQDNCACHE_ENTRY, +- MEM_FWD_SERVER, + MEM_IDNS_QUERY, + MEM_IPCACHE_ENTRY, + MEM_MAX + +=== modified file 'src/peer_select.cc' +--- src/peer_select.cc 2016-01-01 00:14:27 +0000 ++++ src/peer_select.cc 2016-06-18 11:48:03 +0000 +@@ -71,7 +71,7 @@ + while (servers) { + FwdServer *next = servers->next; + cbdataReferenceDone(servers->_peer); +- memFree(servers, MEM_FWD_SERVER); ++ delete servers; + servers = next; + } + +@@ -246,7 +246,7 @@ + // clear the used fs and continue + psstate->servers = fs->next; + cbdataReferenceDone(fs->_peer); +- memFree(fs, MEM_FWD_SERVER); ++ delete fs; + peerSelectDnsPaths(psstate); + return; + } +@@ -268,7 +268,7 @@ + while (fs) { + psstate->servers = fs->next; + cbdataReferenceDone(fs->_peer); +- memFree(fs, MEM_FWD_SERVER); ++ delete fs; + fs = psstate->servers; + } + } +@@ -377,7 +377,7 @@ + + psstate->servers = fs->next; + cbdataReferenceDone(fs->_peer); +- memFree(fs, MEM_FWD_SERVER); ++ delete fs; + + // see if more paths can be found + peerSelectDnsPaths(psstate); +@@ -772,7 +772,6 @@ + peerSelectInit(void) + { + memset(&PeerStats, '\0', sizeof(PeerStats)); +- memDataInit(MEM_FWD_SERVER, "FwdServer", sizeof(FwdServer), 0); + } + + static void +@@ -934,12 +933,10 @@ + static void + peerAddFwdServer(FwdServer ** FSVR, CachePeer * p, hier_code code) + { +- FwdServer *fs = (FwdServer *)memAllocate(MEM_FWD_SERVER); + debugs(44, 5, "peerAddFwdServer: adding " << + (p ? p->host : "DIRECT") << " " << + hier_code_str[code] ); +- fs->_peer = cbdataReference(p); +- fs->code = code; ++ FwdServer *fs = new FwdServer(p, code); + + while (*FSVR) + FSVR = &(*FSVR)->next; + diff --git a/src/patches/squid/squid-3.5-14061.patch b/src/patches/squid/squid-3.5-14061.patch new file mode 100644 index 0000000..0985db5 --- /dev/null +++ b/src/patches/squid/squid-3.5-14061.patch @@ -0,0 +1,237 @@ +------------------------------------------------------------ +revno: 14061 +revision-id: squid3@treenet.co.nz-20160618133607-yt9vr8gjdrctcqd1 +parent: squid3@treenet.co.nz-20160618114803-m7riuy90mrdlxw1f +author: Alex Rousskov rousskov@measurement-factory.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Sun 2016-06-19 01:36:07 +1200 +message: + Fixed ConnStateData::In::maybeMakeSpaceAvailable() logic. + + This change fixes logic bugs that mostly affect performance: In micro- + tests, this change gives 10% performance improvement. + + maybeMakeSpaceAvailable() is called with an essentially random in.buf. + The method must prepare in.buf for the next network read. The old code + was not doing that [well enough], leading to performance problems. + + In some environments, in.buf often ends up having tiny space exceeding 2 + bytes (e.g., 6 bytes). This happens, for example, when Squid creates and + parses a fake CONNECT request. The old code often left such tiny in.bufs + "as is" because we tried to ensure that we have at least 2 bytes to read + instead of trying to provide a reasonable number of buffer space for the + next network read. Tiny buffers naturally result in tiny network reads, + which are very inefficient, especially for non-incremental parsers. + + I have removed the explicit "2 byte" space checks: Both the new and the + old code do not _guarantee_ that at least 2 bytes of buffer space are + always available, and the caller does not check that condition either. + If some other code relies on it, more fixes will be needed (but this + change is not breaking that guarantee -- either it was broken earlier or + was never fully enforced). In practice, only buffers approaching + Config.maxRequestBufferSize limit may violate this guarantee AFAICT, and + those buffers ought to be rare, so the bug, if any, remains unnoticed. + + Another subtle maybeMakeSpaceAvailable() problem was that the code + contained its own buffer capacity increase algorithm (n^2 growth). + However, increasing buffer capacity exponentially does not make much + sense because network read sizes are not going to increase + exponentially. Also, memAllocStringmemAllocate() overwrites n^2 growth + with its own logic. Besides, it is buffer _space_, not the total + capacity that should be increased. More work is needed to better match + Squid buffer size for from-user network reads with the TCP stack buffers + and traffic patterns. + + Both the old and the new code reallocate in.buf MemBlobs. However, the + new code leaves "reallocate or memmove" decision to the new + SBuf::reserve(), opening the possibility for future memmove + optimizations that SBuf/MemBlob do not currently support. + + It is probably wrong that in.buf points to an essentially random MemBlob + outside ConnStateData control but this change does not attempt to fix that. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20160618133607-yt9vr8gjdrctcqd1 +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: 86f65c860a5470008ab241b44a72d4cd35418e73 +# timestamp: 2016-06-18 13:50:58 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20160618114803-\ +# m7riuy90mrdlxw1f +# +# Begin patch +=== modified file 'src/SBuf.cc' +--- src/SBuf.cc 2016-01-01 00:14:27 +0000 ++++ src/SBuf.cc 2016-06-18 13:36:07 +0000 +@@ -162,6 +162,29 @@ + cow(minCapacity); + } + ++SBuf::size_type ++SBuf::reserve(const SBufReservationRequirements &req) ++{ ++ debugs(24, 8, id << " was: " << off_ << '+' << len_ << '+' << spaceSize() << ++ '=' << store_->capacity); ++ ++ const bool mustRealloc = !req.allowShared && store_->LockCount() > 1; ++ ++ if (!mustRealloc && spaceSize() >= req.minSpace) ++ return spaceSize(); // the caller is content with what we have ++ ++ /* only reallocation can make the caller happy */ ++ ++ if (!mustRealloc && len_ >= req.maxCapacity) ++ return spaceSize(); // but we cannot reallocate ++ ++ const size_type newSpace = std::min(req.idealSpace, maxSize - len_); ++ reserveCapacity(std::min(len_ + newSpace, req.maxCapacity)); ++ debugs(24, 7, id << " now: " << off_ << '+' << len_ << '+' << spaceSize() << ++ '=' << store_->capacity); ++ return spaceSize(); // reallocated and probably reserved enough space ++} ++ + char * + SBuf::rawSpace(size_type minSpace) + { + +=== modified file 'src/SBuf.h' +--- src/SBuf.h 2016-01-01 00:14:27 +0000 ++++ src/SBuf.h 2016-06-18 13:36:07 +0000 +@@ -75,6 +75,7 @@ + }; + + class CharacterSet; ++class SBufReservationRequirements; + + /** + * A String or Buffer. +@@ -424,6 +425,12 @@ + */ + void reserveCapacity(size_type minCapacity); + ++ /** Accommodate caller's requirements regarding SBuf's storage if possible. ++ * ++ * \return spaceSize(), which may be zero ++ */ ++ size_type reserve(const SBufReservationRequirements &requirements); ++ + /** slicing method + * + * Removes SBuf prefix and suffix, leaving a sequence of 'n' +@@ -617,6 +624,24 @@ + SBuf& lowAppend(const char * memArea, size_type areaSize); + }; + ++/// Named SBuf::reserve() parameters. Defaults ask for and restrict nothing. ++class SBufReservationRequirements ++{ ++public: ++ typedef SBuf::size_type size_type; ++ ++ SBufReservationRequirements() : idealSpace(0), minSpace(0), maxCapacity(SBuf::maxSize), allowShared(true) {} ++ ++ /* ++ * Parameters are listed in the reverse order of importance: Satisfaction of ++ * the lower-listed requirements may violate the higher-listed requirements. ++ */ ++ size_type idealSpace; ///< if allocating anyway, provide this much space ++ size_type minSpace; ///< allocate if spaceSize() is smaller ++ size_type maxCapacity; ///< do not allocate more than this ++ bool allowShared; ///< whether sharing our storage with others is OK ++}; ++ + /// ostream output operator + inline std::ostream & + operator <<(std::ostream& os, const SBuf& S) + +=== modified file 'src/client_side.cc' +--- src/client_side.cc 2016-06-15 22:08:16 +0000 ++++ src/client_side.cc 2016-06-18 13:36:07 +0000 +@@ -2351,26 +2351,24 @@ + return result; + } + +-bool ++/// Prepare inBuf for I/O. This method balances several conflicting desires: ++/// 1. Do not read too few bytes at a time. ++/// 2. Do not waste too much buffer space. ++/// 3. Do not [re]allocate or memmove the buffer too much. ++/// 4. Obey Config.maxRequestBufferSize limit. ++void + ConnStateData::In::maybeMakeSpaceAvailable() + { +- if (buf.spaceSize() < 2) { +- const SBuf::size_type haveCapacity = buf.length() + buf.spaceSize(); +- if (haveCapacity >= Config.maxRequestBufferSize) { +- debugs(33, 4, "request buffer full: client_request_buffer_max_size=" << Config.maxRequestBufferSize); +- return false; +- } +- if (haveCapacity == 0) { +- // haveCapacity is based on the SBuf visible window of the MemBlob buffer, which may fill up. +- // at which point bump the buffer back to default. This allocates a new MemBlob with any un-parsed bytes. +- buf.reserveCapacity(CLIENT_REQ_BUF_SZ); +- } else { +- const SBuf::size_type wantCapacity = min(static_castSBuf::size_type(Config.maxRequestBufferSize), haveCapacity*2); +- buf.reserveCapacity(wantCapacity); +- } +- debugs(33, 2, "growing request buffer: available=" << buf.spaceSize() << " used=" << buf.length()); +- } +- return (buf.spaceSize() >= 2); ++ // The hard-coded parameters are arbitrary but seem reasonable. ++ // A careful study of Squid I/O and parsing patterns is needed to tune them. ++ SBufReservationRequirements requirements; ++ requirements.minSpace = 1024; // smaller I/Os are not worth their overhead ++ requirements.idealSpace = CLIENT_REQ_BUF_SZ; // we expect few larger I/Os ++ requirements.maxCapacity = Config.maxRequestBufferSize; ++ requirements.allowShared = true; // allow because inBuf is used immediately ++ buf.reserve(requirements); ++ if (!buf.spaceSize()) ++ debugs(33, 4, "request buffer full: client_request_buffer_max_size=" << Config.maxRequestBufferSize); + } + + void + +=== modified file 'src/client_side.h' +--- src/client_side.h 2016-01-01 00:14:27 +0000 ++++ src/client_side.h 2016-06-18 13:36:07 +0000 +@@ -195,10 +195,11 @@ + // Client TCP connection details from comm layer. + Comm::ConnectionPointer clientConnection; + +- struct In { ++ class In { ++ public: + In(); + ~In(); +- bool maybeMakeSpaceAvailable(); ++ void maybeMakeSpaceAvailable(); + + ChunkedCodingParser *bodyParser; ///< parses chunked request body + SBuf buf; + +=== modified file 'src/tests/stub_SBuf.cc' +--- src/tests/stub_SBuf.cc 2016-01-01 00:14:27 +0000 ++++ src/tests/stub_SBuf.cc 2016-06-18 13:36:07 +0000 +@@ -53,6 +53,7 @@ + void SBuf::forceSize(size_type newSize) STUB + const char* SBuf::c_str() STUB_RETVAL("") + void SBuf::reserveCapacity(size_type minCapacity) STUB ++SBuf::size_type SBuf::reserve(const SBufReservationRequirements &) STUB_RETVAL(0) + SBuf& SBuf::chop(size_type pos, size_type n) STUB_RETVAL(*this) + SBuf& SBuf::trim(const SBuf &toRemove, bool atBeginning, bool atEnd) STUB_RETVAL(*this) + SBuf SBuf::substr(size_type pos, size_type n) const STUB_RETVAL(*this) + +=== modified file 'src/tests/stub_client_side.cc' +--- src/tests/stub_client_side.cc 2016-01-01 00:14:27 +0000 ++++ src/tests/stub_client_side.cc 2016-06-18 13:36:07 +0000 +@@ -80,7 +80,7 @@ + bool ConnStateData::serveDelayedError(ClientSocketContext *context) STUB_RETVAL(false) + #endif + +-bool ConnStateData::In::maybeMakeSpaceAvailable() STUB_RETVAL(false) ++void ConnStateData::In::maybeMakeSpaceAvailable() STUB + + void setLogUri(ClientHttpRequest * http, char const *uri, bool cleanUrl) STUB + const char *findTrailingHTTPVersion(const char *uriAndHTTPVersion, const char *end) STUB_RETVAL(NULL) +