IpOverrider
IpOverrider rewrites source and destination IP addresses inside raw packet
payloads.
It is a layer-3 packet tunnel. It does not create sockets, does not create normal connection lines, and does not buffer packets. It only inspects packets that already flow through a packet-oriented WaterWall chain and rewrites configured IPv4 header fields in place.
Typical Placement
Packet-chain examples:
TunDevice -> IpOverrider -> RawSocket
TunDevice -> WireGuardDevice -> IpOverrider -> UdpStatelessSocket
Use it anywhere in a packet chain where packets should leave the node with a different source or destination IP address.
What It Does
- Rewrites upstream IPv4 source addresses when configured.
- Rewrites upstream IPv4 destination addresses when configured.
- Rewrites downstream IPv4 source addresses when configured.
- Rewrites downstream IPv4 destination addresses when configured.
- Uses one node-level
only120gate for the complete rewrite action. - Uses one node-level
chancegate for the complete rewrite action. - Supports one IPv4 address or a non-empty IPv4 address array per rule.
- Updates IPv4 header and TCP/UDP pseudo-header checksums incrementally after an IPv4 rewrite.
- Forwards upstream packets to
nextand downstream packets to the previous node.
A single IpOverrider instance can replace several older chained
IpOverrider nodes because it can hold separate rules for both directions and
both IP fields.
Configuration Example
New multi-rule format:
{
"name": "ip-rewrite",
"type": "IpOverrider",
"settings": {
"up": {
"source-ip": {
"ipv4": "10.0.0.10"
},
"dest-ip": {
"ipv4": "198.51.100.10"
}
},
"down": {
"source-ip": {
"ipv4": "203.0.113.10"
},
"dest-ip": {
"ipv4": "10.0.0.20"
}
}
},
"next": "next-packet-node"
}
IPv4 array example:
{
"name": "source-pool",
"type": "IpOverrider",
"settings": {
"up": {
"source-ip": {
"ipv4": ["10.0.0.10", "10.0.0.11", "10.0.0.12"]
}
}
},
"next": "next-packet-node"
}
Legacy Configuration Example
The old single-rule format is still accepted:
{
"name": "ip-rewrite-old",
"type": "IpOverrider",
"settings": {
"direction": "up",
"mode": "dest-ip",
"ipv4": "198.51.100.10"
},
"next": "next-packet-node"
}
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 "IpOverrider". |
settings | object | Required. Must contain at least one rewrite rule. |
next | string | Required for normal upstream forwarding. |
IpOverrider must also have a previous packet node in useful chain layouts.
New Multi-Rule Format
The current preferred format uses up and/or down objects:
| Rule path | Meaning |
|---|---|
settings.up.source-ip | Rewrite the IPv4 source address on upstream packets. |
settings.up.dest-ip | Rewrite the IPv4 destination address on upstream packets. |
settings.down.source-ip | Rewrite the IPv4 source address on downstream packets. |
settings.down.dest-ip | Rewrite the IPv4 destination address on downstream packets. |
At least one of those rule objects must be present. If either up or down
exists, the parser uses the new format and does not treat the object as legacy
settings.
Each present rule object must contain ipv4 or ipv6.
Node Options
chance and only120 belong directly inside the root settings object,
alongside up and down:
| Field | Type | Default | Description |
|---|---|---|---|
chance | integer percent, 0 through 100 | 100 | Probability that the node's complete rewrite action applies to an eligible packet. |
only120 | boolean | false | Restricts the complete rewrite action to IPv4 packets whose total IP length is 120 bytes or less. |
Do not place either option inside source-ip or dest-ip. Per-rule chance
and only120 values in the new format are rejected; move them to
settings.chance and settings.only120.
Rule Address Fields
| Field | Type | Description |
|---|---|---|
ipv4 | string or array of strings | Replacement IPv4 address or a non-empty list of replacement IPv4 addresses. Values must be plain IPv4 addresses, not CIDR ranges or hostnames. |
ipv6 | string | Parsed and stored, but IPv6 rewriting is disabled in the current runtime path. |
If ipv4 is an array, each packet that applies the rule uses the next address
from that array in round-robin order. The cursor is per rule.
If both ipv4 and ipv6 are present in one rule, ipv4 is used because the
parser checks ipv4 first.
Legacy Format
The legacy format defines one rule directly inside settings:
| Field | Type | Description |
|---|---|---|
direction | string | Must be "up" or "down". |
mode | string | Must be "source-ip" or "dest-ip". |
ipv4 / ipv6 | string, or IPv4 array for ipv4 | Replacement address for the selected rule. |
chance | integer percent | Node-level packet chance, with the same 0 through 100 range and default as the new format. |
only120 | boolean | Node-level IPv4 packet-length gate, with the same false default and 120-byte threshold as the new format. |
Use the new format for new configs because it can represent up to four rules in
one node. In the legacy format, both chance and only120 are already at the
root of settings; because the format has only one rule, the new shared-gate
behavior is otherwise equivalent.
chance
chance controls how often the complete node action runs. It is evaluated once
per eligible packet, not separately for each source or destination rule:
100always applies the configured rules.0always forwards the packet unchanged.- Values from
1through99are percentages.
This example rewrites both upstream fields together for approximately 25 percent of eligible packets. When the chance does not happen, neither field is changed:
{
"name": "probabilistic-ip-rewrite",
"type": "IpOverrider",
"settings": {
"chance": 25,
"up": {
"source-ip": {
"ipv4": "10.0.0.10"
},
"dest-ip": {
"ipv4": "198.51.100.10"
}
}
},
"next": "next-packet-node"
}
only120
only120 is a size gate for the complete node action. When it is true, all
configured rewrites run together for IPv4 packets whose total IP length is
120 bytes or less. Larger IPv4 packets are forwarded unchanged.
{
"name": "small-packet-ip-rewrite",
"type": "IpOverrider",
"settings": {
"only120": true,
"up": {
"source-ip": {
"ipv4": "10.0.0.10"
},
"dest-ip": {
"ipv4": "198.51.100.10"
}
}
},
"next": "next-packet-node"
}
Combining only120 and chance
For each packet, the node evaluates its root-level gates before running any rewrite rule:
- When
only120is enabled, an IPv4 packet with a total IP length greater than120skips the complete node action. - Otherwise,
settings.chanceis evaluated exactly once. If it does not happen, the complete node action is skipped. - When both gates pass, all configured source and destination rules for the packet direction are evaluated.
When either gate skips the node action, the packet is forwarded unchanged, IPv4 address-array cursors are not advanced, and this node does not request checksum recalculation.
Direction Behavior
Upstream payload:
- evaluates the node-level
only120andchancegates - when both pass, checks
up.source-ipandup.dest-ip - forwards the packet with
tunnelNextUpStreamPayload()
Downstream payload:
- evaluates the node-level
only120andchancegates - when both pass, checks
down.source-ipanddown.dest-ip - forwards the packet with
tunnelPrevDownStreamPayload()
If no rule exists for the packet direction, the packet passes through unchanged.
IpOverrider does not terminate the chain and does not hold packets.
Checksum Behavior
When an IPv4 address is rewritten, IpOverrider updates the IPv4 header checksum
incrementally in place. For TCP and enabled UDP packets, it also applies the
corresponding IPv4 pseudo-header checksum delta. A disabled (zero) UDP checksum
remains zero. The node does not request a full-packet checksum recalculation for
its own rewrite, and preserves any pre-existing checksum recalculation request.
Packet-Line Semantics
IpOverrider is a pure packet tunnel:
- it has no per-connection lifecycle
- it does not create or destroy lines
- packet payload callbacks are the intended runtime path
- normal stream-style
Finish,Pause,Resume, andEstcallbacks are invalid for normal use
The implementation does not allocate per-line state for packet lines.
Limits and Padding
| Value | Size |
|---|---|
required_padding_left | 0 bytes |
chance range | 0 through 100 |
only120 threshold | IPv4 total length <= 120 bytes |
The node rewrites existing header fields in place and does not need left padding.
Notes and Caveats
- The current runtime rewrite path only modifies IPv4 packet headers.
- IPv6 values are parsed and stored, but the IPv6 rewrite block is disabled in source today.
ipv4values must be literal IPv4 addresses. CIDR ranges and hostnames are rejected.- Source IP spoofing only works if your network and datacenter allow packets with that rewritten source address. Many providers drop such traffic.
IpOverriderchanges IP addresses only; it does not rewrite TCP or UDP ports.