Skip to main content

JunkDatagramSender

JunkDatagramSender is a composable middle tunnel that injects generated UDP-like datagram payloads before early upstream payloads on each line.

It is meant for camouflage and protocol-noise experiments around UDP-style paths. The node does not modify the real payload. Instead, when an upstream payload arrives, it may first send a random batch of generated junk payloads to next, then forward the real payload unchanged.

JunkDatagramSender is a normal tunnel with per-line state. It is not a socket adapter, does not create or destroy line_t objects, and is not a raw IPv4 packet tunnel.

Typical Placement

UDP-style path:

UdpListener -> JunkDatagramSender -> UdpConnector

With other datagram-preserving nodes:

UdpListener -> JunkDatagramSender -> EncryptionClient -> UdpConnector

Use it where one WaterWall payload is expected to behave like one datagram. In ordinary TCP stream paths, the junk payloads become extra stream bytes, which is usually not what an application protocol expects.

What It Does

  • Initializes a per-line remaining trigger counter from resend-again-times.
  • Sends junk only when upstream payload callbacks arrive.
  • Sends junk before the real upstream payload.
  • Sends a random number of junk payloads between packet-count-perline-min and packet-count-perline-max.
  • Picks each junk payload's protocol generator randomly from selected-protocols.
  • Can schedule one delayed duplicate of each generated junk payload.
  • Forwards the real upstream payload unchanged after the junk batch.
  • Forwards downstream payloads unchanged.
  • Passes Est, Pause, and Resume in the same direction unchanged.
  • Destroys its local line state before forwarding directional Finish.

If junk generation or forwarding closes the line before the real payload is forwarded, the node recycles the real payload buffer and returns.

Configuration Example

{
"name": "junk",
"type": "JunkDatagramSender",
"settings": {
"packet-count-perline-min": 2,
"packet-count-perline-max": 5,
"resend-again-times": 2,
"selected-protocols": [
"dns",
"ntp",
"quic-http3",
"rtp-rtcp-srtp"
],
"keep-sending-max-ms": 1500
},
"next": "udp-out"
}

With default settings, the first upstream payload on each line triggers one generated junk payload, then the real payload is forwarded.

Required Fields

Top-level fields:

FieldTypeDescription
namestringUser-chosen node name. Must be unique inside the config file.
typestringMust be exactly "JunkDatagramSender".
settingsobjectOptional settings object. Empty settings use defaults.
nextstringOptional in node metadata, but normally set to the next tunnel that receives upstream payloads.

Settings

SettingTypeDefaultDescription
packet-count-perline-mininteger1Minimum number of junk payloads generated for each trigger. Negative values are clamped to 0.
packet-count-perline-maxinteger1Maximum number of junk payloads generated for each trigger. Negative values are clamped to 0; values above 256 are clamped to 256. If lower than the minimum, it is clamped up to the minimum.
resend-again-timesinteger1Number of upstream payload callbacks that trigger junk sending on each line. 0 disables junk sending. Negative values are clamped to 0; values above 256 are clamped to 256.
selected-protocolsarray of stringsall implemented protocolsProtocol generators eligible for random selection. If omitted, all implemented generators are used. An empty array is accepted but makes the node pass traffic through without junk.
keep-sending-max-msinteger00 disables delayed duplicate sends. When greater than 0, each generated junk payload is duplicated once and scheduled with a random delay from 1 to this value in milliseconds. Negative values disable delayed sends.

Trigger Behavior

resend-again-times counts upstream payload callbacks, not individual bytes and not connection attempts.

For example:

{
"packet-count-perline-min": 2,
"packet-count-perline-max": 4,
"resend-again-times": 3
}

On each line, the first three upstream payload callbacks each trigger a random batch of 2 to 4 junk payloads. The fourth and later upstream payloads are forwarded without adding more junk.

No junk is sent during Init by itself. The node waits until a real upstream payload arrives.

Protocol Selection

Accepted canonical protocol names:

Canonical nameAccepted aliases
dnsnone
dhcpnone
ntpnone
quic-http3quic, http3, http/3, quic/http3
rtp-rtcp-srtprtp, rtcp, srtp
stun-turn-icestun, turn, ice
mdnsnone
snmpnone
syslognone
ipsec-nat-tipsec-natt, natt
sipnone

Use "all" inside selected-protocols to explicitly enable every implemented generator:

{
"selected-protocols": ["all"]
}

Protocol names are matched case-insensitively by the current implementation, even though lowercase names are the documented form.

Disabled Protocol Names

The following names exist only as disabled placeholders. If any of them are listed in selected-protocols, startup fails:

Disabled nameNotes
tftpgenerator placeholder only
ssdpgenerator placeholder only
radiusgenerator placeholder only
gtp-u / gtpugenerator placeholder only
game-udp-protocols / game-udp / gamegenerator placeholder only
coapgenerator placeholder only

Generated Payload Types

The implemented modules generate valid-looking UDP application payloads, not UDP/IP headers:

ProtocolGenerated shape
dnsDNS query payloads, sometimes with EDNS(0)-style data.
dhcpDHCPv4 client-message payloads.
ntpNTP client request payloads.
quic-http3QUIC Initial-like payloads with HTTP/3 ALPN data.
rtp-rtcp-srtpRTP media, RTCP control, and SRTP-shaped payloads.
stun-turn-iceSTUN, TURN, and ICE connectivity or relay-control payloads.
mdnsMulticast DNS query and announcement payloads.
snmpSNMP v1/v2c manager request payloads.
syslogRFC3164/RFC5424-style syslog messages.
ipsec-nat-tNAT-T keepalive, IKEv2, and ESP-in-UDP-shaped payloads.
sipSIP request and response payloads.

The node passes generator arguments with a default target range of 12 to 1200 bytes. Individual generators may still choose fixed sizes where the protocol shape requires it.

Direction Behavior

Incoming callbackBehavior
upstream InitInitializes line state, then forwards Init to next.
upstream PayloadSends configured junk batch if triggers remain, then forwards the real payload to next.
upstream Est / Pause / ResumeForwards to next.
upstream FinishDestroys local line state, then forwards Finish to next.
downstream InitInitializes line state, then forwards Init to the previous node.
downstream PayloadForwards unchanged to the previous node.
downstream Est / Pause / ResumeForwards to the previous node.
downstream FinishDestroys local line state, then forwards Finish to the previous node.

The source contains a downstream junk direction helper, but the active payload path only triggers junk on upstream payload callbacks.

Line Safety

JunkDatagramSender stores only one per-line field:

remaining_resend_again_times

During upstream payload handling, the node locks the line while sending the junk batch. Delayed duplicate payloads are scheduled with lineScheduleDelayedTaskWithBuf(), so the line scheduler holds the temporary line reference and releases the duplicated buffer if the line is already closed when the timer runs.

The node does not call lineDestroy(). It only destroys its own line state before forwarding Finish.

Buffer And Padding Notes

JunkDatagramSender does not prepend bytes to the real payload and does not modify the real payload buffer. It allocates separate large buffers for generated junk payloads.

Node metadata sets:

required_padding_left = 0
layer_group = kNodeLayerAnything

Although the layer metadata is permissive, the generated data is UDP-like application payload data. Do not treat this node as an IPv4 packet mutator. For raw packet changes, use packet-oriented nodes such as IpManipulator or IpOverrider.

Practical Notes

  • resend-again-times: 0 makes the node pass traffic through.
  • packet-count-perline-max: 0 makes the node pass traffic through.
  • selected-protocols: [] makes the node pass traffic through and logs a warning.
  • keep-sending-max-ms schedules one delayed duplicate per generated junk payload; it does not keep generating forever.
  • Delayed duplicate ordering is not guaranteed by the line scheduler.
  • The node does not rewrite addresses, ports, checksums, or packet headers.
  • The generated payloads are camouflage noise, not encryption or authentication.