Hi Roy,

On Sun, Mar 27, 2011 at 01:31:25PM -0400, Roy Smith wrote:
> I'm trying to modify haproxy-1.4.11 (on Ubuntu) to do some additional 
> logging.  I've added to http_sess_log(), some experimental code:
> 
> --- a/src/proto_http.c        Sat Mar 26 12:38:10 2011 -0400
> +++ b/src/proto_http.c        Sat Mar 26 19:18:30 2011 -0400
> @@ -1081,6 +1081,7 @@
>       static char tmpline[MAX_SYSLOG_LEN];
>       int t_request;
>       int hdr;
> +     struct hdr_ctx ctx;
> 
>       /* if we don't want to log normal traffic, return now */
>       err = (s->flags & (SN_ERR_MASK | SN_REDISP)) ||
> @@ -1149,6 +1150,14 @@
>                                 '#', url_encode_map, uri);
>               *(h++) = '"';
>       }
> +
> +     if (http_find_header("X-Unique-ID", txn->req.sol, &txn->hdr_idx, &ctx)) 
> {
> +                // if (h < tmpline + ctx.vlen - 4) {
> +                //         memcpy(tmpline, ctx.val, ctx.vlen);
> +                //         h += ctx.vlen;
> +                // }
> +        }
> +
>       *h = '\0';
> 
>       svid = (tolog & LW_SVID) ?
> 
> when this code runs, I get a segfault as soon as it tries to log anything.  
> I'm obviously calling http_find_header() wrong, but I can't figure out  what 
> I should be doing.  When I look at the resulting core file with gdb, it shows 
> that txn->req.sol is not initialized.
> 
> #0  http_find_header2 (name=0x44d6af "X-Unique-ID", len=11, sol=0x1 <Address 
> 0x1 out of bounds>, idx=0x795960, ctx=0x7fff37575a80) at src/proto_http.c:513
> 513                   eol = sol + idx->v[cur_idx].len;
> 
> Is there something I need to be doing to initialize the sol element of the 
> request?


There are several things which cannot work for your use case.

1) the returned pointers are pointers to the data buffer. Thus, request
   headers can only be retrieved during the request processing, and
   response headers can only be retrieved during response processing.
   outside of these periods, you may find anything in the buffers.

2) the headers are "indexed", in fact they're linked in a list of relative
   pointers and sizes pointer to by txn->hdr_idx. As you can see, there is
   only one list per transaction, because this list takes some space, and
   we never have to process request and response headers at the same time.
   So what you'd find will be indexes on the response headers at the end
   of a normally processed session.

3) the buffers' "sol" pointer normally points to the first line of request
   or response during parsing. Once headers are parsed, we expect to possibly
   find chunked-encoded data which also need to be parsed and also require
   several pointers to be maintained. So at this point, the "sol" pointer
   is initialized to the beginning of the body, prepared to point to the
   beginning of any chunk size.

Your segfault is very likely caused by this sol pointer being much advanced
in the buffer, and your indexes referencing large relative positions, causing
and out-of-bounds on the buffer when checking whether the header you're looking
for is present or not.

If you need to log some request data, you have to do that during the request
processing, and copy them somewhere in the session. You should probably use
the header capture for that, they'll do that for free. Alternatively, you may
add a fixed size string to the session struct and use it for your needs.

Regards,
Willy


Reply via email to