[MEDIUM] session: better fix for connection to servers with closed input

The following patch fixed an issue but brought another one :
  296897 [MEDIUM] connect to servers even when the input has already been closed

The new issue is that when a connection is inspected and aborted using
TCP inspect rules, now it is sent to the server before being closed. So
that test is not satisfying. A probably better way is not to prevent a
connection from establishing if only BF_SHUTW_NOW is set but BF_SHUTW
is not. That way, the BF_SHUTW flag is not set if the request has any
data pending, which still fixes the stats issue, but does not let any
empty connection pass through.

Also, as a safety measure, we extend buffer_abort() to automatically
disable the BF_AUTO_CONNECT flag. While it appears to always be OK,
it is by pure luck, so better safe than sorry.
This commit is contained in:
Willy Tarreau 2010-03-21 23:25:09 +01:00
parent 4e1554c295
commit e45997661b
2 changed files with 4 additions and 5 deletions

View File

@ -204,6 +204,7 @@ static inline void buffer_shutw_now(struct buffer *buf)
static inline void buffer_abort(struct buffer *buf)
{
buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
buf->flags &= ~BF_AUTO_CONNECT;
}
/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack

View File

@ -1331,12 +1331,10 @@ resync_stream_interface:
/* first, let's check if the request buffer needs to shutdown(write), which may
* happen either because the input is closed or because we want to force a close
* once the server has begun to respond. Note that we only apply it once we're
* connected, so that we still support queuing of a request with input already
* closed.
* once the server has begun to respond.
*/
if (unlikely((s->req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK|BF_AUTO_CLOSE|BF_SHUTR)) ==
(BF_AUTO_CLOSE|BF_SHUTR) && s->req->cons->state >= SI_ST_EST))
(BF_AUTO_CLOSE|BF_SHUTR)))
buffer_shutw_now(s->req);
/* shutdown(write) pending */
@ -1358,7 +1356,7 @@ resync_stream_interface:
* - the BF_AUTO_CONNECT flag is set (active connection)
*/
if (s->req->cons->state == SI_ST_INI) {
if (!(s->req->flags & (BF_SHUTW|BF_SHUTW_NOW))) {
if (!(s->req->flags & BF_SHUTW)) {
if ((s->req->flags & (BF_AUTO_CONNECT|BF_OUT_EMPTY)) != BF_OUT_EMPTY) {
/* If we have a ->connect method, we need to perform a connection request,
* otherwise we immediately switch to the connected state.