Skip to main content

BlackHole

BlackHole is a terminal sink adapter. It is placed at the end of a chain and consumes upstream traffic from the previous node without creating a socket, connecting to a remote peer, or forwarding payload to another node.

It supports two behaviors:

  • passive mode accepts the line, reports downstream Est to the previous side, and silently drops upstream payload
  • active mode immediately sends downstream Finish to the previous side during upstream Init

Because BlackHole is an adapter, downstream callbacks are not part of its valid runtime surface. Do not place another node after it.

What It Does​

  • Can be used as the last node in a chain.
  • Rejects configuration with a next node.
  • Drops every upstream payload buffer it receives.
  • Recycles dropped payload buffers with lineReuseBuffer().
  • Does not prepend, frame, encrypt, decode, or rewrite payload.
  • Does not allocate per-line tunnel state.
  • Does not require extra left padding.
  • Does not create or destroy packet lines.

Typical Placement​

Terminal passive drop point:

TcpListener -> BlackHole

UDP chain test:

UdpListener -> BlackHole

Policy or test chains can use BlackHole when accepted traffic should be consumed or rejected at the chain end.

BlackHole is not a middle tunnel. For a chain such as TcpListener -> BlackHole -> TcpConnector, use another policy or routing tunnel instead.

Configuration Example​

Passive mode:

{
"name": "dropper",
"type": "BlackHole",
"settings": {
"mode": "passive"
}
}

Active mode:

{
"name": "rejector",
"type": "BlackHole",
"settings": {
"mode": "active"
}
}

Required Fields​

Top-level fields:

FieldTypeDescription
namestringUser-chosen node name. Must be unique inside the config file.
typestringMust be exactly "BlackHole".
settingsobjectMust contain mode.

Required settings fields:

FieldTypeDescription
modestringSelects passive payload dropping or active connection finishing.

mode is required. The current implementation does not provide a default.

Optional Fields​

There are no optional settings fields.

Do not configure a node-level next field. BlackHole is a chain-end adapter.

Mode Reference​

Passive Mode​

Accepted values:

ValueMeaning
passiveCanonical passive mode name.
dropAlias for passive mode.
packet-dropAlias for passive mode. The node still behaves as the same payload sink; it does not become a packet tunnel.
silentAlias for passive mode.
calmAlias for passive mode.

In passive mode:

  • upstream Init sends downstream Est to the previous side
  • upstream payload is dropped and recycled
  • upstream Est, Finish, Pause, and Resume are no-ops
  • downstream callbacks are disabled by the adapter edge

Passive mode does not close the line by itself. It consumes payload until the previous side closes the line.

Active Mode​

Accepted values:

ValueMeaning
activeCanonical active mode name.
closeAlias for active mode.
aggressiveAlias for active mode.
killAlias for active mode.
kill-connectionAlias for active mode.

In active mode:

  • upstream Init sends downstream Finish to the previous side and returns immediately
  • upstream payload is still dropped and recycled if any payload reaches the node
  • downstream callbacks are disabled by the adapter edge

This behaves like an immediate connection reject at the end of the chain.

Payload Handling​

Upstream payload calls lineReuseBuffer() on the received buffer and returns.

No payload bytes cross the node. Since no header is prepended and no frame is allocated, BlackHole has required_padding_left = 0.

Lifecycle Behavior​

BlackHole follows downstream-end adapter direction rules:

Callback directionBehavior
upstream Init in passive modeSends tunnelPrevDownStreamEst().
upstream Init in active modeSends tunnelPrevDownStreamFinish().
upstream payloadRecycles the buffer with lineReuseBuffer().
upstream Est / Finish / Pause / ResumeNo-op.
downstream callbacksInvalid for this adapter edge and blocked by adapterCreate().

It never calls tunnelNextUpStream*() because there is no next node.

Notes and Caveats​

  • BlackHole is layer-agnostic in node metadata, but it does not transform between stream and packet semantics.
  • It is not useful for chains that need an application response, because payload never passes through it.
  • Passive mode can leave the previous side open indefinitely if that side keeps the line open.
  • Active mode is best used as a deliberate reject or kill endpoint.
  • The node has no protocol settings, credentials, remote address, port, or framing options.

Node Metadata​

Source-backed metadata:

PropertyValue
node flagskNodeFlagChainEnd | kNodeFlagNoChain | kNodeFlagSupportsSplice
can_have_prevtrue
can_have_nextfalse
layer_groupkNodeLayerAnything
layer_group_prev_nodekNodeLayerAnything
layer_group_next_nodekNodeLayerNone
required_padding_left0 bytes

Splice support​

The upstream sink recycles input, discarding any remaining private-pipe body. Healthy empty pipes may remain cached for reuse. Passive mode still consumes data; active mode closes during Init and does not accept later payload on that closed normal line. There is no downstream payload handler.

Ordinary fallback buffers remain accepted. Splice requires a supported Linux build, misc.splice enabled, no packet nodes, and support from every node in the finalized expanded/merged chain. The capability flag does not bypass these checks. No performance improvement is promised without measurement.

Packet configurations of this dual-layer node still do not enable splice.