Encrypted TLS bypass dependency on stream.bypass

I’ve been messing around with bypassing TLS encrypted traffic with app-layer.protocols.tls.encryption-handling set to bypass and stream.bypass set to yes.
Some other threads on the topic:
Bypassing encrypted traffic does not seem to work - Help - Suricata
Stream bypass documentation note - Developers - Suricata
and my own: Bypass-mark/bypass-mask not working in NFQ mode - Help - Suricata

This works as documented, but I now have the unwanted side-effect where my other non-TLS streams are bypassed once I’ve reached the reassembly depth.
I looked at the code, and from what I could tell, there’s no real reason for this dependency, it’s a simple if: suricata/stream-tcp.c at master · OISF/suricata (github.com)

STREAMTCP_FLAG_BYPASS is only set by StreamTcpSetSessionBypassFlag
which is only called once in the entire codebase in the app-layer parser and only when APP_LAYER_PARSER_BYPASS_READY is set, which is only turned on when ssl_config.encrypt_mode is set to SSL_CNF_ENC_HANDLE_BYPASS, here and here.

In other words, there are no other flows that set STREAMTCP_FLAG_BYPASS as far as I can tell.

So my question is - why is this dependency here? Why not call PacketBypassCallback without asking if (StreamTcpBypassEnabled())?


What version are you using and how does your suricata.yaml look like for those tests?

I’m using Suricata 6.0.1.
The relevant parts of the config are:

  bypass: yes
  memcap: 64mb
  checksum-validation: yes
  inline: auto
    memcap: 256mb
    depth: 1mb
    toserver-chunk-size: 2560
    toclient-chunk-size: 2560
    randomize-chunk-size: yes

      enabled: yes
        dp: 443
      ja3-fingerprints: yes
      encryption-handling: bypass

But this doesn’t seem version related, it’s right there in the code and this behavior is explicitly documented (ignoring the documentation error calling it encrypt-handling instead of encryption-handling):

When encrypt-handling is set to bypass , all processing of this session is stopped. No further parsing and inspection happens. If stream.bypass is enabled this will lead to the flow being bypassed, either inside Suricata or by the capture method if it supports it and is configured for it.

The question is why? I don’t see any reason to couple these 2 features (not to say that there is no reason, just saying I don’t see it). The only reasoning I can think of is that it just follows the common coding pattern/convention where PacketBypassCallback(p) is called only if StreamTcpBypassEnabled() returns true, regardless of whether that’s an actual prerequisite.