Skip to main content

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 only120 gate for the complete rewrite action.
  • Uses one node-level chance gate 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 next and 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:

FieldTypeDescription
namestringUser-chosen node name. Must be unique inside the config file.
typestringMust be exactly "IpOverrider".
settingsobjectRequired. Must contain at least one rewrite rule.
nextstringRequired 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 pathMeaning
settings.up.source-ipRewrite the IPv4 source address on upstream packets.
settings.up.dest-ipRewrite the IPv4 destination address on upstream packets.
settings.down.source-ipRewrite the IPv4 source address on downstream packets.
settings.down.dest-ipRewrite 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:

FieldTypeDefaultDescription
chanceinteger percent, 0 through 100100Probability that the node's complete rewrite action applies to an eligible packet.
only120booleanfalseRestricts 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

FieldTypeDescription
ipv4string or array of stringsReplacement IPv4 address or a non-empty list of replacement IPv4 addresses. Values must be plain IPv4 addresses, not CIDR ranges or hostnames.
ipv6stringParsed 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:

FieldTypeDescription
directionstringMust be "up" or "down".
modestringMust be "source-ip" or "dest-ip".
ipv4 / ipv6string, or IPv4 array for ipv4Replacement address for the selected rule.
chanceinteger percentNode-level packet chance, with the same 0 through 100 range and default as the new format.
only120booleanNode-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:

  • 100 always applies the configured rules.
  • 0 always forwards the packet unchanged.
  • Values from 1 through 99 are 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 only120 is enabled, an IPv4 packet with a total IP length greater than 120 skips the complete node action.
  • Otherwise, settings.chance is 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:

  1. evaluates the node-level only120 and chance gates
  2. when both pass, checks up.source-ip and up.dest-ip
  3. forwards the packet with tunnelNextUpStreamPayload()

Downstream payload:

  1. evaluates the node-level only120 and chance gates
  2. when both pass, checks down.source-ip and down.dest-ip
  3. 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, and Est callbacks are invalid for normal use

The implementation does not allocate per-line state for packet lines.

Limits and Padding

ValueSize
required_padding_left0 bytes
chance range0 through 100
only120 thresholdIPv4 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.
  • ipv4 values 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.
  • IpOverrider changes IP addresses only; it does not rewrite TCP or UDP ports.