Also, no code shuffling which should normally have been done with namespace.
Config children are currently too intwined with UserRequest children and
helper management. Logic changes are required before that can be done.
ConnStateData::flags.readMoreRequests, do_next_read variables, and
ClientSocketContext::mayUseConnection() methods were used (or unused!)
incorrectly or inconsistently.
This change removes all do_next_read variables to simplify the state. Instead,
the renamed ConnStateData::flags.readMore indicates whether client_side.cc
should call comm_read. The mayUseConnection() methods are now used to indicate
whether the next client-sent byte (buffered or read) should be reserved for
the current request rather than being interpreted as the beginning of the next
request.
Portability Fix: getrlimit() / setrlimit() incompatible type 'struct rlimit'
On Linux (at least) with large file support but not full 64-bit environment.
The getrlimt / setrlimit are #define'd to getrlimite64 / setrlimit64
BUT, the struct rlimit internal fields are updated to 64-bit types individually
instead of a matching #define to struct rlimit64 as a whole.
One can only assume that GCC is casting to void* or some such major voodoo
which hides this type collision.
ICC: support 64-bit environments dirent definitions
struct dirent is not consistently defined for 32-bit and 64-bit enabled
environments. Provide a dirent_t type defined appropriate to the environment
for use instead.
This npending test bug was preventing any poll() errors from being
noticed and displayed. Possibly leading to some of the weird hanging
reports we have been unable to replicate.
Alex Rousskov [Wed, 6 Apr 2011 16:25:36 +0000 (10:25 -0600)]
Fixed chunked request forwarding in ICAP REQMOD presence.
ICAP prohibits forwarding of hop-by-hop headers in HTTP headers. If the virgin
request has a "Transfer-Encoding: chunked" header, the ICAP server will not
receive it. Thus, when the ICAP server responds with a 200 OK and what it
thinks is a copy of the HTTP request, the adapted request will be missing the
Transfer-Encoding header.
One the server side, Squid used to test whether the request had a
Transfer-Encoding header to determine whether request chunking is needed when
talking to the next HTTP hop. That test would fail in ICAP REQMOD presence.
This change implements a more direct/robust check: if we do not know the
request content length, we chunk the request.
We also no longer forward the Content-Length header if we are chunking. It
should not really be there in most cases, but an explicit check is safer and
may also prevent request smuggling attacks via Connection: Content-Length
tricks.
Portability: Provide stdio wrappers for 64-bit in cstdio C++ builds
stdio.h in that case on provides fgetpos64, fopen64 if
__USE_FILE_OFFSET64 is defined. It then checks whether a gcc-specific
__REDIRECT macro is available (defined in sys/cdefs.h, depending on
__GNUC__ begin available).
If it is not available, it does a preprocessor #define.
Which <cstdio> undefines, with this comment:
"// Get rid of those macros defined in <stdio.h> in lieu of real functions.".
When it does a namespace redirection ("namespace std { using ::fgetpos; }")
it goes blam, as fgetpos64 is available, while fgetpos is not.
To fix it, we need to supply global functions matching those
signatures (not macros).
Enable string mempools to work correctly during initialization phase
Makes string mempools work before Mem::Init() was called, as may happen
during global variable initialization or early main.cc processing. If
needed, strings allocated before the Mem::Init() call are given an extra
buffer space to make sure the allocated buffer size will not match any
string pool size during deallocation.
Shortcomings: We now waste RAM on buffer increase for early allocated
strings unless they are already bigger than the maximum supported string
pool size. Statistics for early allocations are broken. Non-string
mempools still do not support early allocations.
Alex Rousskov [Tue, 5 Apr 2011 21:39:53 +0000 (15:39 -0600)]
Fixed %dt logging in the presence of REQMOD.
We use LogEntry::request to save a virgin request for future logging. However,
when that request is adapted and replaced, the adapted request has all the
stats while the saved virgin request lacks them. We have already copied error
details from the adapted to logged/virgin request. Now we copy the DNS wait
time (%dt) as well.
TODO: Move statistics to a stand-alone history object that adapted and
virgin requests can share. Longer term, we should separate HttpRequest
from Master Transaction so that we can store virgin request details without
implicitly storing not-yet-collected master transaction stats.
Display ERROR in cache.log for invalid configured paths
The validator that checks system paths for files and directories in the
configuration file sends error messages to stderr. It should send them to
cache.log for the admin to see easily.
Also, this makes the error display as FATAL ERROR when using -k parse to
indicate that it is fatal to the startup. Other management signals where
it is not necessarily fatal will only display as an ERROR.
Within reason. Check that at least the port matches. That gives us some
small measure of reason to believe its the same protocol inside or the
same app being CONNECTed to.
Alex Rousskov [Fri, 1 Apr 2011 14:47:51 +0000 (08:47 -0600)]
Optimization (performance regression fix): Use bigger buffer for server reads.
Change the server read buffer limits to 16KB minimum and 256KB maximum.
Used to be: 2KB and 2GB. And before r9766: 4KB and SQUID_TCP_SO_RCVBUF.
Trunk r9766 (Remove limit on HTTP headers read) made the default HTTP
server read buffer size 2KB instead of 4KB, visibly slowing down Squid
when kernel network buffers are full and can sustain larger Squid reads.
Doing up to twice as many network reads is expensive (and probably not
just because of the extra system call overheads).
We never grow that buffer size if the _parser_ does not need a bigger
buffer: Even if the HTTP client is slower than the server, the buffer
stays small because it gives all the data to Store and Store eventually
just stalls reading via delayAwareRead() and read_ahead_gap. The
situation may be different with RESPMOD, but if the adaptation service
is fast, the buffer would still not grow.
This change does not reset the minimum buffer size to the old 4KB
default because memory is much cheaper compared to the days where that
default was set. 8KB may have worked too, but with 12KB median typical
response size a larger buffer may be a good idea for a busy Squid. More
performance work is needed to find the optimal value (which could depend
on the environment).
This change does not set the maximum buffer size to the current 2GB
limit because we have not tested how header and chunking parsers would
cope with malicious messages trying to run Squid out of RAM; and also
because no good parser should need that much lookahead space. Is 256KB
enough for all legitimate real-world response headers? We do not know.
It is tempting to use Config.tcpRcvBufsz or SQUID_TCP_SO_RCVBUF to find
the right minimum or maximum buffer size, but those parameters deal with
low-level TCP buffering aspects while this buffer deals with HTTP
parsing.
Alex Rousskov [Fri, 1 Apr 2011 14:39:24 +0000 (08:39 -0600)]
Log all transactions including those with uncertain status or no sent response.
Excluding those transactions from access log hides valuable information.
For example, it hides certain aborted client transactions which sometimes
indicate Squid bugs or configuration problems that the administrator can fix.
It also leads to wrong statistics reporting if the reporting tools are based
on access logs information.
The change just removes the logging guard and adds debugging. The logging
code itself is unchanged except for indenting.
Dmitry Kurochkin [Wed, 30 Mar 2011 20:50:00 +0000 (14:50 -0600)]
Do not send signals from the master process to parent on shutdown.
Trunk r11330 introduced a bug: When running in non-daemon mode, Squid
sends SIGUSR1 signal to the parent process on shutdown. This results in
shell (at least zsh) exit when Squid is interrupted with C-c. The patch
adds a check to prevent the master process from killing it's parent on
shutdown.
Dmitry Kurochkin [Wed, 30 Mar 2011 19:39:14 +0000 (13:39 -0600)]
If a worker process crashes during shutdown, dump core and prevent restarts.
Before the change, if a worker process crashes during shutdown, death()
handler would exit with code 1, and master process would restart the
worker. Now workers send SIGUSR1 to master when shutting down. When
master process gets the SIGUSR1 signal, it stops restarting workers.
SIGUSR1 is already used for log rotation, but it is fine to use SIGUSR1
for master process shutdown notifications because master is never
responsible for both log rotation and kid restarts.
Terminate with abort(3) instead of exit(3) to leave a core dump if Squid
worker crashes during shutdown.
Also the patch fixes potential infinite loop in master process. Master
used to finish only when all kids exited with success, or all kids are
hopeless, or all kids were killed by a signal, but when some kids are
hopeless and others were killed, the master process would not exit.
After the change, master exits when there are no running kids and no
kids should be restarted.
Alex Rousskov [Wed, 30 Mar 2011 18:14:08 +0000 (12:14 -0600)]
Better reporting of REQMOD failures during body processing.
When REQMOD body processing fails, the server-side needs to abort the
in-progress transaction. Use HTTP 500 (Internal Server Error) instead of 502
(Bad Gateway) status code and a new custom error detail for this case.
There is no perfect status code for ICAP errors because some view ICAP
processing as an integral part of the proxy (closer to the internal
proxy code) and some treat it as an external entity (closer to an
"upstream" web server).
Nevertheless, 502 (Bad Gateway) feels like a worse fit because from web
user and traffic flow point of views ICAP is less of a "gateway" or
"upstream" server than it is an "internally" used auxiliary service.
When both status codes were used, we have received reasonable complaints
about 502 responses but not (IIRC) about 500 responses.
Using custom error detail is better than errno in this context because
errno is often not set for ICAP errors and because by the time we
generate an error, the errno value is likely to be from a different
system call error anyway.
Alex Rousskov [Wed, 30 Mar 2011 18:07:38 +0000 (12:07 -0600)]
Instead of exiting, disable optional eCAP services that fail initialization.
Report all service initialization failures but mark optional services
down instead of killing Squid by propagating the failure to the Squid
core. An initialization failure of an optional (bypass=1) service
should not lead to Squid quitting because, according to squid.conf, such
a service may be replaced by other services (using adaptation sets) or
simply ignored.
Initialization failures of essential services still lead to fatal
errors, but they are now reported better.
Ecap services should indicate failures by throwing an exception. Squid
reports exception details using std::exception::what() method if
possible.
Alex Rousskov [Wed, 30 Mar 2011 17:43:55 +0000 (11:43 -0600)]
Support dynamic adaptation plans that cover multiple vectoring points.
The dynamic adaptation plan is specified using X-Next-Services ICAP
header or eCAP meta-info, as usual. A REQMOD adaptation service may
construct an adaptation plan that starts with REQMOD and ends with
RESPMOD. Multiple adaptations may be planned at each point.
The natural transaction handling order must be preserved: the plan
cannot go from RESPMOD back to REQMOD.
Adaptation::History object is used to keep future plan steps when
crossing vectoring points.
Amos Jeffries [Mon, 28 Mar 2011 10:51:53 +0000 (04:51 -0600)]
SourceLayout: (Bug 3170) namespace for Auth::Scheme and children
Also,
* fix digest shutdown process so AuthDigestConfig does the config cleanup
and Auth::Digest::Scheme does the scheme termination
* fix all schemes shutdown to silence scheme messages (partial bug 3170)
Amos Jeffries [Mon, 28 Mar 2011 04:02:03 +0000 (22:02 -0600)]
SourceLayout: build auth sub-libraries in abstraction
This changes the building process for auth sub-libraries:
libbasic.la, libdigest.la, libnegotiate.la, libntlm.la
making them build from their own Makefiles.
That allows each sub-dir to be automatically included (or not) to the main
auth/libauth.la library.
TODO: (no necessarily in this order)
* split out the classes into their own compile units (files)
* add namespace Auth and per-protocol child areas
* de-duplicate the repetitive code back into the parent classes
Amos Jeffries [Sat, 26 Mar 2011 02:03:49 +0000 (15:03 +1300)]
Cleanup: make clientParseRequest() a member of ConnStateData
This allows the HttpParser to also become a member field and persistent
across all requests on the connection instead of newely allocated on
the stack for every read cycle.
That in turn allows the parser to retain state for efficient 'trickle'
parsing across multiple read cycles.
For now the old behaviour of reset on every read is retained in order to
prevent this shuffling from causing behaviour changes. That negates most
of the actual performance gains (for now).
Marco Beck [Fri, 25 Mar 2011 11:47:08 +0000 (00:47 +1300)]
Regression fix: Replacing reply headers
Restores the functionality to replace reply headers as found in Squid 2.
header_replace worked for both request and reply headers back then.
The creation of request_header_access and reply_header_access altered
replace_headers to only work on requests. It should have received this
name split back then.
Alex Rousskov [Thu, 24 Mar 2011 15:48:34 +0000 (09:48 -0600)]
Bug 3173: Assertion bodyPipe!=NULL on SslBump CONNECT response writing failure
Do not call ConnStateData::startClosing() when we fail to write our CONNECT
response while bumping a connection. startClosing() can only be used when we
handle response bodies. Just close the connection, in hope that the connection
close handler kicks in and cleans up.
Amos Jeffries [Thu, 24 Mar 2011 14:00:41 +0000 (03:00 +1300)]
Regression fix: upgrade existing icons
This adds an automatic upgrade to move the old pre-3.2.0.5 icons into the
new icons area.
This also retains any local customizations that may have been done,
ie. new icons added outside Squid.
Alex Rousskov [Wed, 23 Mar 2011 00:32:37 +0000 (18:32 -0600)]
Made cache.log less noisy about usually benign events outside of admin control.
Raised reporting level from 1 to 2 for 'statusIfComplete: Request not yet
fully sent' and 'clientProcessRequest: Invalid Request' messages after
observing important information drowning in their noise on busy proxies.
Alex Rousskov [Wed, 23 Mar 2011 00:18:28 +0000 (18:18 -0600)]
Propagate details of ICAP errors happened after adapted HTTP header creation.
We used to update the virgin HTTP request with error details even after REQMOD
resulted in creation of a new/adapted HTTP request object. When the client
side replaced the old/virgin request headers with the new adapted request
object, the error details were lost and %err_detail was not logged to the
transaction log.
This is one more place where a Master Transaction object (with a shared error
detail field) should be extracted from the HttpRequest and persist throughout
the HTTP transaction lifetime.
Not all time-based options should accept milliseconds
After last changes, squid accepts "millisecond" units for all time-based
options, silently rounding millisecond-based values down if they are not
supported. We should not allow millisecond units for options that do not
support millisecond.
This patch add the allowMsec parameter to parseTimeLine function to allow/deny
the use of milliseconds.
Bug Fix: Squid may crash, when accessing an SSL certificate with errors
This is a security bug.
The bug report is:
When accessing a revoked certificate (i.e., X509_V_ERR_CERT_REVOKED) Squid
crashes. In ssl/ErrorDetail.cc:223 the detailed message is left blank if the
error is not specifically handled by Squid and the errorpage.cc:1193 assertion
fails while trying to convert the message.
This patch:
- Handle inside ErrorState::Convert the cases where the ErrorDetail return
blank error detail string
- Use a default detail error message in ssl::ErrorDetail, for the cases
where the detail error is not defined in TheSslDetailMap.
- If a name for the ssl::ErrorDetail error code is not defined return the
numeric error code when the "%err_name" formating code used
Convert dns_timeout and dns_retransmit_interval configuration options to use millisecond resolution.
One second resolution is too coarse for small timeouts in delay-sensitive
environments, especially when a retransmit, bypass, or another corrective
action is available and is likely to produce a positive outcome. In DNS world
specifically, most timeouts are measured in milliseconds.
Alex Rousskov [Fri, 11 Mar 2011 22:22:13 +0000 (15:22 -0700)]
Fixed propagation of eCAP transaction meta-information to core Squid
by synchronizing the history of the virgin and eCAP-adapted/cloned request.
If the request history is created after the request got cloned, the cloned
request will have no history unless we explicitly import the newly created
history. Hopefully, it is not possible for the cloned request to get its own,
diverging history before the import (we check and throw if that happens).
This is one more example why a MasterTransaction class (with history) needs
to be extracted and separated from the HttpRequest class.
Alex Rousskov [Fri, 11 Mar 2011 21:41:33 +0000 (14:41 -0700)]
Report eCAP service [re]start to cache.log by default.
Reporting eCAP services may be important, especially since we have no other
interface to detect their presence and since folks will have to deal with
rogue services eventually.
Also raised eCAP service configuration notice level to 2.
Amos Jeffries [Fri, 11 Mar 2011 15:11:11 +0000 (08:11 -0700)]
Expand Makefile sources macros
Expand several macros used in earlier attempts to omtimize the Makefile
content. With the SourceLayout and modular changes underway these are
proving to be more of a problem than they are worth.
At some future time when the convenience libraries are settled it may be
worth revisiting some shared lists. But not yet.
Apply uri_whitespace before logging malformed requests
This patch try to implement the first option from those described at the
squid-dev thread with subject "Request URI logging for malformed requests":
http://www.squid-cache.org/mail-archive/squid-dev/201101/0004.html
Currently the logged URI set using the setLogUri method (in client_side.cc and
client_side_reply.cc files). Also the setLogUri called at least two times for
every normal request. Moreover the setLogUri always check if the URI contains
characters which must escaped which in the case of normal requests it is not
needed because urlCanonicalClean always used before pass the URI to setLogUri.
This patch:
- add a parameter to the setLogUri to say if the URI must cleaned and the
uri_whitespace filtering must applied.
- Remove the setLogUri call from the parseHttpRequest.
- Call in all cases (HTTP request error or not) the setLogUri in
clientProcessRequest
- In the case the URL is not a valid HTTP request applies the uri_whitespace
filtering.
- In the case the URI is valid the uri_whitespace filtering is not required
because it is already applied by the urpParse function.