Update on ICAP integration proposal: Working implementation of SSLproxy (icap branch) & icapsuricata (libsuricata service)

First API issue with libsuricata: When including <suricata/stream-tcp.h> (to call StreamTcpInlineMode()) alongside standard system networking headers (or frameworks like c-icap that pull them in implicitly), the compiler throws hard redeclaration errors.

Specifically, the TcpState enum in stream-tcp-private.h redefines globally scoped symbols that clash directly with standard definitions in <netinet/tcp.h>:

/* Conflicts with /usr/include/netinet/tcp.h */
enum TcpState {
    TCP_NONE = 0,
    // TCP_LISTEN = 1,
    TCP_SYN_SENT = 2,
    TCP_SYN_RECV = 3,
    TCP_ESTABLISHED = 4,
    ...
};

Because these are exposed in the flat namespace, it prevents external proxy or server applications from compiling cleanly if they manage network sockets directly.

As a temporary workaround in icapsuricata, I’ve managed to bypass this by sandboxing the header inclusion with preprocessor macro masking right before pulling in the Suricata headers:

// Temporarily rename conflicting symbols to protect them from netinet/tcp.h
#define TCP_SYN_SENT    SURI_TCP_SYN_SENT
#define TCP_SYN_RECV    SURI_TCP_SYN_RECV
#define TCP_ESTABLISHED SURI_TCP_ESTABLISHED
#define TCP_FIN_WAIT1   SURI_TCP_FIN_WAIT1
#define TCP_FIN_WAIT2   SURI_TCP_FIN_WAIT2
#define TCP_TIME_WAIT   SURI_TCP_TIME_WAIT
#define TCP_LAST_ACK    SURI_TCP_LAST_ACK
#define TCP_CLOSE_WAIT  SURI_TCP_CLOSE_WAIT
#define TCP_CLOSING     SURI_TCP_CLOSING
#define TCP_CLOSED      SURI_TCP_CLOSED

#include <suricata/stream-tcp.h>

// Restore standard definitions for the rest of the codebase, not used in icapsuricata
#undef TCP_SYN_SENT
#undef TCP_SYN_RECV
#undef TCP_ESTABLISHED
#undef TCP_FIN_WAIT1
#undef TCP_FIN_WAIT2
#undef TCP_TIME_WAIT
#undef TCP_LAST_ACK
#undef TCP_CLOSE_WAIT
#undef TCP_CLOSING
#undef TCP_CLOSED

Moving forward with a public libsuricata API definition, it would be amazing if internal state enums like this were either hidden entirely from the public-facing headers, prefixed (e.g., SURICATA_TCP_ESTABLISHED), or guarded with an #ifndef _NETINET_TCP_H check to ensure frictionless embedding! (P.S.: I have Suricata 8.0.4)