.. _param-imptcp-compression-mode:
.. _imptcp.parameter.input.compression-mode:

Compression.mode
================

.. index::
   single: imptcp; Compression.mode
   single: Compression.mode

.. summary-start

Selects decompression mode matching compression used by omfwd. Supports
auto-detection so a single listener accepts both compressed and plain peers.

.. summary-end

This parameter applies to :doc:`../../configuration/modules/imptcp`.

:Name: Compression.mode
:Scope: input
:Type: word
:Default: input=none
:Required?: no
:Introduced: at least 5.x, possibly earlier

Description
-----------
This is the counterpart to the compression modes set in
:doc:`omfwd <../../configuration/modules/omfwd>`.
``imptcp`` accepts the following values:

- ``none`` - do not attempt stream decompression.
- ``stream:always`` - treat the full TCP byte stream as a zlib-compressed
  stream generated by :doc:`omfwd <../../configuration/modules/omfwd>` with
  ``compression.mode="stream:always"``.
- ``stream:auto`` - sniff the first two bytes of each session, lock-in the
  verdict for the remainder of the connection. Lets a single listener
  accept compressed and plain peers simultaneously (staged client
  roll-out).

This receive path is a fixed-policy implementation:

- it uses streaming zlib decompression during normal receives,
- it performs a final decompression drain when the TCP session closes,
- it is compatible with sender-side
  ``compression.stream.flushOnTXEnd="on"`` and ``"off"``,
- it logs malformed or truncated compressed streams and closes the session.

``imptcp`` does not support the sender-side ``single`` compression mode here.

Accepted values
---------------
``none``
   No stream decompression. Per-message single-message compression (the
   legacy ``z``-prefixed payload) is still decoded by the parser stage.

``stream:always``
   Every accepted session is treated as a zlib stream (RFC 1950).
   Plain peers connecting to the listener will be rejected after the
   first failed ``inflate()`` call.

``stream:auto`` *(since v8.2606.0)*
   The first two bytes of each session are inspected to decide whether
   the peer is sending a zlib stream or plain syslog. Once the decision
   is made it is locked-in for the lifetime of the session, so the
   hot path stays branch-free after the initial probe.

   This is intended for staged client roll-outs where a single
   listener must accept both compressed and uncompressed peers while
   the fleet of senders (typically :doc:`omfwd <../../configuration/modules/omfwd>`)
   is migrated one peer at a time.

   **Detection rules.** A session is treated as compressed if and only
   if the first byte is ``0x78`` (zlib CMF for deflate, 32 KiB window -
   what ``omfwd`` emits via ``deflateInit()``), the two-byte FCHECK
   value is valid, and the FDICT bit is clear. Any other byte sequence
   selects the plain path; a plain syslog frame always starts with an
   ASCII digit (octet-counted framing) or ``<`` (non-transparent
   framing), so the test is conclusive for any rsyslog-to-rsyslog
   deployment and for every standard 3rd-party syslog sender we know
   of.

   **Caveats.**

   * Custom senders that emit raw deflate (RFC 1951, no zlib wrapper)
     are not detected. Use ``stream:always`` for those.
   * Senders that intentionally build a zlib stream with a non-default
     window size (CMF != ``0x78``) are not detected as compressed.
     This is a deliberate tightening of the probe to avoid false
     positives against octet-counted plain framing.
   * Detection is per session, never per message; flipping a peer
     between modes requires a new TCP connection.

Input usage
-----------
.. _param-imptcp-input-compression-mode:
.. _imptcp.parameter.input.compression-mode-usage:

.. code-block:: rsyslog

   input(type="imptcp" compression.mode="stream:auto")

See also
--------
See also :doc:`../../configuration/modules/imptcp`.
