On Sun, Mar 27, 2011 at 07:05:00PM +0200, Willy Tarreau wrote:
> On Sun, Mar 27, 2011 at 06:47:26AM -0700, Johannes Smith wrote:
> > I noticed differences in the log of version 1.4 and 1.5-dev4 regarding the 
> > number of retries:
> >  
> > 1.4: NAME1 NAME2/<NOSRV> -1/-1/-1/-1/10521 400 187 - - CR-- 18/5/0/0/0 0/0 
> > {||} 
> > "<BADREQ>"
> > 1.5: NAME1 NAME2/<NOSRV> -1/-1/-1/-1/10521 400 180 - - CR-- 
> > 10/3/0/0/4294967286 
> > 0/0 {||} "<BADREQ>"
> >  
> > Retries shouldn't be that large?
> 
> Huh ! that's pretty bad, it became negative (-10 here). What is particularly
> strange is that it should have remained at its initialization value since the
> request was rejected. At the moment, I failed to reproduce it, but it's
> possible that I missed an initializer somewhere, I will check that.

Ah, I finally got it. It happens when a previous session's conn_retries count
is left uninitialized when logging a bad request.

You can use the attached patch if you want, though you can wait for 1.5-dev5
as this is harmless.

Regards,
Willy

>From 0b3a4115431e47845f9a6dd1f75e000f88f75be7 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <[email protected]>
Date: Sun, 27 Mar 2011 19:16:56 +0200
Subject: [BUG] session: conn_retries was not always initialized

Johannes Smith reported some wrong retries count in logs associated with bad
requests. The cause was that the conn_retries field in the stream interface
was only initialized when attempting to connect, but is used when logging,
possibly with an uninitialized value holding last connection's conn_retries.
This could have been avoided by making use of a stream interface initializer.

This bug is 1.5-specific.
---
 src/proto_http.c |    1 +
 src/session.c    |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/src/proto_http.c b/src/proto_http.c
index 30177ee..ef6f46e 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -3987,6 +3987,7 @@ void http_end_txn_clean_session(struct session *s)
        s->req->cons->state     = s->req->cons->prev_state = SI_ST_INI;
        s->req->cons->fd        = -1; /* just to help with debugging */
        s->req->cons->err_type  = SI_ET_NONE;
+       s->req->cons->conn_retries = 0;  /* used for logging too */
        s->req->cons->err_loc   = NULL;
        s->req->cons->exp       = TICK_ETERNITY;
        s->req->cons->flags     = SI_FL_NONE;
diff --git a/src/session.c b/src/session.c
index 24df936..d673aaa 100644
--- a/src/session.c
+++ b/src/session.c
@@ -188,6 +188,7 @@ int session_accept(struct listener *l, int cfd, struct 
sockaddr_storage *addr)
        s->si[1].owner     = t;
        s->si[1].state     = s->si[1].prev_state = SI_ST_INI;
        s->si[1].err_type  = SI_ET_NONE;
+       s->si[1].conn_retries = 0;  /* used for logging too */
        s->si[1].err_loc   = NULL;
        s->si[1].connect   = NULL;
        s->si[1].release   = NULL;
-- 
1.7.2.1.45.g54fbc

Reply via email to