Commit Graph

3 Commits

Author SHA1 Message Date
Aurelien DARRAGON
afd5f5d671 DEV: h2: fix h2-tracer.lua nil value index
Nick Ramirez reported the following error while testing the h2-tracer.lua
script:

  Lua filter 'h2-tracer' : [state-id 0] runtime error: /etc/haproxy/h2-tracer.lua:227: attempt to index a nil value (field '?') from /etc/haproxy/h2-tracer.lua:227: in function line 109.

It is caused by h2ff indexing with an out of bound value. Indeed, h2ff
is indexed with the frame type, which can potentially be > 9 (not common
nor observed during Willy's tests), while h2ff only defines indexes from
0 to 9.

The fix was provided by Willy, it consists in skipping h2ff indexing if
frame type is > 9. It was confirmed that doing so fixes the error.
2025-04-08 17:44:41 +02:00
Willy Tarreau
af5c07eee9 DEV: h2: fix flags for the continuation frame
It's flag 2 (end of headers) that's defined there, not 3 (padded).
2025-02-18 14:17:17 +01:00
Willy Tarreau
607aa57b2e DEV: h2: add a Lua-based HTTP/2 connection tracer
The following config is sufficient to trace H2 exchanges between a client
and a server:

   global
       lua-load "dev/h2/h2-tracer.lua"

   listen h2_sniffer
       mode tcp
       bind :8002
       filter lua.h2-tracer #hex
       server s1 127.0.0.1:8003

The commented "hex" argument will also display full frames in hex (not
recommended). The connections are prefixed with a 3-hex digit number in
order to also support a bit of multiplexing without impacting the reading
too much. The screen is split in two, with the request on the left and
the response on the right. Here's an example of what it does between an
haproxy backend and an haproxy frontend both in H2, when submitted a
curl request for /?s=30k handled by httpterm:

  [001] ### req start
  [001] [PREFACE len=24]
  [001] [SETTINGS sid=0 len=24 (bytes=24)]
  [001]                                          | ### res start
  [001]                                          | [SETTINGS sid=0 len=18 (bytes=27)]
  [001]                                          | [SETTINGS ACK sid=0 len=0 (bytes=0)]
  [001] [SETTINGS ACK sid=0 len=0 (bytes=56)]
  [001] [HEADERS EH+ES sid=1 len=47 (bytes=47)]
  [001]                                          | [HEADERS EH sid=1 len=101 (bytes=15351)]
  [001]                                          | [DATA sid=1 len=15126 (bytes=15241)]
  [001]                                          | [DATA sid=1 len=1258 (bytes=106)]
  [001]                                          |                  ... -106 = 1152
  [001]                                          |                    ... -1152 = 0
  [001] [WINDOW_UPDATE sid=1 len=4 (bytes=43)]
  [001] [WINDOW_UPDATE sid=0 len=4 (bytes=30)]
  [001] [WINDOW_UPDATE sid=1 len=4 (bytes=17)]
  [001] [WINDOW_UPDATE sid=0 len=4 (bytes=4)]
  [001]                                          | [DATA ES sid=1 len=14336 (bytes=14336)]
  [001] [WINDOW_UPDATE sid=0 len=4 (bytes=4)]
  [001] ### req end: 31080 bytes total
  [001]                                          | [GOAWAY sid=0 len=8 (bytes=8)]
  [001]                                          | ### res end: 31097 bytes total

It deserves some improvements. For instance at the moment it does not
verify the preface, any 24 bytes will work. It does not perform any
protocol validation either. Detecting some issues such as out-of-sequence
frames could be helpful. But it already helps as-is.
2025-02-18 09:26:15 +01:00