RawSocket
RawSocket connects WaterWall to raw IPv4 packet capture and raw IPv4 packet
injection. It can capture packets from the host networking stack, forward those
packets into a layer-3 chain, and inject raw IP packets that come back from the
chain.
Older documentation may call this node RawDevice. The current node type is
RawSocket.
RawSocket is a layer-3 adapter, not a connection-oriented tunnel. Captured
packets are forwarded on worker packet lines, while payload arriving from either
chain direction is treated as a complete raw IP packet and written to the raw
output device.
Typical Placement
At the edge of a packet chain:
RawSocket -> PacketReceiver
PacketSender -> RawSocket
TunDevice -> IpManipulator -> RawSocket
With packet disguise nodes:
TunDevice -> PingClient -> RawSocket
RawSocket -> PingServer -> TunDevice
In first position, RawSocket forwards captured wrapped packets upstream into
PingServer. PingServer restores them toward TunDevice; plain packets captured
by TunDevice return downstream through PingServer for wrapping and raw
injection.
RawSocket can have a previous node, a next node, or both. The captured-packet
direction is selected at startup:
| Chain position | Captured IPv4 packets are forwarded to |
|---|---|
RawSocket is the last node in the chain | previous node, through downstream payload |
RawSocket is not the last node | next node, through upstream payload |
Payload that reaches RawSocket from either upstream or downstream is injected
through the same raw output device.
Configuration Example
{
"name": "raw-ip",
"type": "RawSocket",
"settings": {
"capture-device-name": "capture-in",
"raw-device-name": "raw-out",
"capture-filter-mode": "source-ip",
"capture-ips": [
"192.0.2.10",
"198.51.100.0/24"
],
"mark": 10
},
"next": "next-node-name"
}
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 "RawSocket". |
settings | object | Required because capture mode and capture ranges must be configured. |
Required settings fields:
| Setting | Type | Description |
|---|---|---|
capture-filter-mode | string | Capture filter mode. The parser recognizes "source-ip" and "dest-ip", but the current implementation only accepts "source-ip". |
capture-ips | array of strings | Non-empty array of IPv4 addresses or IPv4 CIDR ranges to capture. |
Each capture-ips item may be a single IPv4 address:
"192.0.2.10"
or an IPv4 CIDR range:
"198.51.100.0/24"
IPv6 values are rejected.
Optional Settings
| Setting | Type | Default | Description |
|---|---|---|---|
capture-device-name | string | unnamed-capture-device | Name passed to the capture-device backend. |
raw-device-name | string | unnamed-raw-device | Name passed to the raw-output backend. |
mark | integer | 0 | Firewall mark for the raw output device where the platform/backend supports it. |
Compatibility aliases:
| Alias | Meaning |
|---|---|
listen-ips | Accepted as an alias for capture-ips. |
capture-ip | Legacy single-string capture range. It is accepted as one /32-style entry; use capture-ips for new configs. |
Capture Path
During startup, RawSocket creates:
- a capture device using the configured IPv4 ranges
- a raw output device for packet injection
When the capture backend receives a packet:
RawSocketchecks whether the packet is IPv4.- Non-IPv4 packets are recycled and not forwarded.
- The worker packet line for that worker is fetched from the chain.
- The captured IPv4 packet is forwarded to the selected adjacent side.
The capture backend is expected to apply the configured IP filter. RawSocket
does not create a normal per-connection line for each packet.
Output Path
When upstream or downstream payload reaches RawSocket:
- The payload buffer is treated as a raw IP packet.
- If the line has
recalculate_checksumset and the packet is IPv4, WaterWall recalculates packet checksums before writing. - The packet is written through the raw output device.
- If the raw device is down or the write fails, the buffer is recycled.
Both upstream and downstream payload callbacks use this same write path.
Checksum Behavior
RawSocket respects packet-line checksum metadata from earlier packet nodes.
If line->recalculate_checksum is set and the payload is IPv4:
- full packet checksum recalculation is attempted
- the flag is cleared after recalculation
- fragmented IPv4 transport checksum details are handled by the shared checksum helper
This is useful after nodes such as IpManipulator or IpOverrider modify IPv4,
TCP, UDP, or ICMP fields and request checksum repair before final output.
Capture Filter Limits
The settings parser recognizes:
source-ip
dest-ip
Current behavior is stricter:
source-ipis accepteddest-ipfails tunnel creation with a message recommendingTunDevicefor outgoing capture-style use
On Linux, the NFQUEUE rules use --queue-bypass. If WaterWall is not listening
on the queue, matching packets continue through the host firewall instead of
being dropped by an absent queue. This is a fail-open availability policy:
packets are not captured or transformed while no listener exists. It does not
make queue overflow fail-open while WaterWall remains bound to the queue.
WaterWall avoids queue numbers already referenced by existing INPUT rules. A
terminal capture startup or rule-cleanup failure closes the queue promptly and
makes that capture-device object non-restartable, activating --queue-bypass
for any rule that could not be removed. The queue reader must report ready
before the first rule is installed and remains running throughout rule
insertion, rollback, and bring-down cleanup. Until every rule is installed and
the raw output device is ready, packets receive NF_ACCEPT and are not
dispatched into the chain. Capture then switches to drop-and-dispatch. Shutdown
deactivates capture before removing rules. An unexpected reader exit
deactivates capture and closes the queue immediately so remaining rules fail
open. While a reader thread is joinable, it owns the queue descriptor;
terminal cleanup requests closure, and the reader wrapper closes the queue only
after the routine has stopped using that descriptor.
Use TunDevice when you need virtual-interface behavior or routed outgoing
packet handling. Use RawSocket when you specifically need host-stack capture
plus raw IPv4 injection.
Direction And Lifecycle Behavior
| Callback | Behavior |
|---|---|
upstream Payload | Injects the payload through the raw output device. |
downstream Payload | Injects the payload through the raw output device. |
| captured packet callback | Forwards captured IPv4 on the worker packet line to the selected adjacent side. |
Init, Est, Pause, Resume, Finish | No-op. RawSocket is not connection-lifecycle driven. |
RawSocket is an adapter and does not destroy packet lines during normal
runtime. Worker packet lines are owned by the chain.
Node Metadata
Source-backed metadata:
| Property | Value |
|---|---|
| node flags | `kNodeFlagChainHead |
| adapter | true |
can_have_prev | true |
can_have_next | true |
layer_group | kNodeLayer3 |
layer_group_prev_node | kNodeLayerAnything |
layer_group_next_node | kNodeLayerAnything |
required_padding_left | 0 bytes |
The node does not prepend protocol headers and does not need left padding.
Practical Notes
- Run with the privileges required by the platform raw/capture backend.
- Configure
capture-ipsexplicitly; an empty array is rejected. - Prefer
capture-ipsover legacycapture-ip. - The current receive path forwards only IPv4 packets.
- Platform behavior depends on the available raw socket, capture, and firewall mark backend.