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-minandpacket-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, andResumein 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:
| Field | Type | Description |
|---|---|---|
name | string | User-chosen node name. Must be unique inside the config file. |
type | string | Must be exactly "JunkDatagramSender". |
settings | object | Optional settings object. Empty settings use defaults. |
next | string | Optional in node metadata, but normally set to the next tunnel that receives upstream payloads. |
Settings
| Setting | Type | Default | Description |
|---|---|---|---|
packet-count-perline-min | integer | 1 | Minimum number of junk payloads generated for each trigger. Negative values are clamped to 0. |
packet-count-perline-max | integer | 1 | Maximum 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-times | integer | 1 | Number 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-protocols | array of strings | all implemented protocols | Protocol 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-ms | integer | 0 | 0 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 name | Accepted aliases |
|---|---|
dns | none |
dhcp | none |
ntp | none |
quic-http3 | quic, http3, http/3, quic/http3 |
rtp-rtcp-srtp | rtp, rtcp, srtp |
stun-turn-ice | stun, turn, ice |
mdns | none |
snmp | none |
syslog | none |
ipsec-nat-t | ipsec-natt, natt |
sip | none |
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 name | Notes |
|---|---|
tftp | generator placeholder only |
ssdp | generator placeholder only |
radius | generator placeholder only |
gtp-u / gtpu | generator placeholder only |
game-udp-protocols / game-udp / game | generator placeholder only |
coap | generator placeholder only |
Generated Payload Types
The implemented modules generate valid-looking UDP application payloads, not UDP/IP headers:
| Protocol | Generated shape |
|---|---|
dns | DNS query payloads, sometimes with EDNS(0)-style data. |
dhcp | DHCPv4 client-message payloads. |
ntp | NTP client request payloads. |
quic-http3 | QUIC Initial-like payloads with HTTP/3 ALPN data. |
rtp-rtcp-srtp | RTP media, RTCP control, and SRTP-shaped payloads. |
stun-turn-ice | STUN, TURN, and ICE connectivity or relay-control payloads. |
mdns | Multicast DNS query and announcement payloads. |
snmp | SNMP v1/v2c manager request payloads. |
syslog | RFC3164/RFC5424-style syslog messages. |
ipsec-nat-t | NAT-T keepalive, IKEv2, and ESP-in-UDP-shaped payloads. |
sip | SIP 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 callback | Behavior |
|---|---|
upstream Init | Initializes line state, then forwards Init to next. |
upstream Payload | Sends configured junk batch if triggers remain, then forwards the real payload to next. |
upstream Est / Pause / Resume | Forwards to next. |
upstream Finish | Destroys local line state, then forwards Finish to next. |
downstream Init | Initializes line state, then forwards Init to the previous node. |
downstream Payload | Forwards unchanged to the previous node. |
downstream Est / Pause / Resume | Forwards to the previous node. |
downstream Finish | Destroys 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: 0makes the node pass traffic through.packet-count-perline-max: 0makes the node pass traffic through.selected-protocols: []makes the node pass traffic through and logs a warning.keep-sending-max-msschedules 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.