Bgp4Client
Bgp4Client is a layer-4 stream tunnel that wraps upstream payloads in
BGP-like frames and unwraps downstream frames produced by Bgp4Server.
It is intended to be paired with Bgp4Server:
TcpListener -> Bgp4Client -> ... -> Bgp4Server -> TcpConnector
In a real deployment, the ... is usually a transport path between the two
sides, such as TCP, TLS, mux, reverse, or another WaterWall chain segment.
Bgp4Client does not implement real BGP routing, BGP peering, route exchange,
or BGP authentication. It only uses a BGP-like frame shape as stream
camouflage/framing.
What It Does
- Initializes one per-line read stream and first-frame state during upstream
init. - On the first upstream payload, prepends a synthetic BGP OPEN body before the application bytes.
- Wraps upstream payloads as BGP-like frames.
- Chooses a random non-OPEN BGP type for later upstream payload frames.
- Parses downstream BGP-like frames from a stream buffer.
- Strips downstream frame metadata and forwards the recovered payload to the previous tunnel.
- Closes both directions when it receives malformed framed data.
Bgp4Client is a normal stream tunnel. It does not create network sockets and
does not create or destroy packet lines.
Configuration Example
Client side:
{
"name": "bgp4-client",
"type": "Bgp4Client",
"settings": {
"password": "compat-value"
},
"next": "transport-out"
}
Paired server side:
{
"name": "bgp4-server",
"type": "Bgp4Server",
"settings": {
"password": "compat-value"
},
"next": "target"
}
The password field is accepted for compatibility with the old configuration
shape, but it is not used for encryption or authentication in the current
protocol logic.
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 "Bgp4Client". |
next | string | The next stream node that receives wrapped frames. |
Optional Settings
| Setting | Type | Default | Description |
|---|---|---|---|
password | string | "passwd" | Compatibility field. It is hashed during setup but the hash is not used by current framing logic. |
No other settings are currently parsed.
Frame Format
All upstream payloads are wrapped as:
16-byte marker | 2-byte body length | 1-byte BGP type | body
Field details:
| Field | Value |
|---|---|
| marker | Sixteen bytes of 0xff. |
| body length | Big-endian uint16_t. Covers the type byte plus body bytes. |
| BGP type | 1 for the first OPEN frame; random 2 through 5 for later payload frames. |
| body | Tunneled payload, or synthetic OPEN body plus tunneled payload for the first upstream frame. |
Supported type values used by the implementation:
| Type | Name |
|---|---|
1 | OPEN |
2 | UPDATE |
3 | NOTIFICATION |
4 | KEEPALIVE |
5 | ROUTE-REFRESH |
The frame length is not the standard BGP message length. In this tunnel it is the older WaterWall contract: type byte plus body bytes, excluding the 16-byte marker and 2-byte length field.
First Upstream Payload
Bgp4Client does not send a standalone OPEN frame during init. Instead, the
first upstream payload is framed as BGP type 1 and the client prepends a
synthetic OPEN body before the application bytes.
Synthetic OPEN fields:
| Field | Behavior |
|---|---|
| version | Always 4. |
| AS number | Random uint16_t generated when the tunnel instance is created. |
| hold time | 90 seconds. |
| router id | Random value generated when the tunnel instance is created. |
| optional parameter length | Random length from 3 through 10 bytes. |
| optional parameter bytes | Random bytes in the range 0 through 199. |
After this first frame, open_sent is set for the line. Later upstream payloads
are wrapped without the synthetic OPEN prefix and use a random non-OPEN type.
Because Bgp4Server expects tunneled application data after the OPEN prefix,
the first OPEN frame must carry payload bytes after the synthetic OPEN body.
Downstream Parsing
Downstream bytes are accumulated in a buffer_stream_t.
For each complete downstream frame, Bgp4Client:
- Verifies that the first 16 bytes are all
0xff. - Reads the 2-byte body length.
- Rejects frames whose body length is not larger than the 1-byte type field.
- Waits until the full frame is buffered.
- Strips marker, length, and type.
- Rejects frames with no remaining payload.
- Sends the recovered payload downstream to the previous tunnel.
If the frame is incomplete, parsing waits for more bytes. If the buffered data grows beyond the current maximum buffered threshold, the line is closed.
Limits
| Limit | Value | Notes |
|---|---|---|
| Maximum body length | 65535 bytes | Includes the 1-byte type. |
| Maximum ordinary payload body | 65534 bytes | Payload plus type must fit in 65535. |
| Maximum buffered read bytes | about 131106 bytes | Two maximum-size framed messages. |
| Required left padding | 39 bytes | Enough for frame prefix plus largest synthetic OPEN prefix. |
If an upstream payload cannot fit into one BGP-like frame, it is refused and no wrapped frame is forwarded.
Data Flow
Upstream direction:
previous node -> Bgp4Client wraps -> next node
Downstream direction:
next node -> Bgp4Client unwraps -> previous node
Bgp4Client expects Bgp4Server on the opposite side. A non-matching peer that
does not produce the expected frame shape will cause protocol errors.
Lifecycle Behavior
On upstream init, Bgp4Client initializes its line state and forwards
upstream init to the next tunnel.
On downstream est, it forwards downstream est to the previous tunnel.
On upstream payload, it wraps and forwards to the next tunnel. On downstream payload, it buffers, parses, unwraps, and forwards recovered payloads to the previous tunnel.
On upstream finish, it destroys its own line state and forwards upstream
finish to the next tunnel. On downstream finish, it destroys its own line
state and forwards downstream finish to the previous tunnel.
On malformed framed data, Bgp4Client destroys local state and closes both
directions in middle-tunnel order: upstream finish first, then downstream
finish.
Pause and resume are forwarded directionally:
| Callback | Forwarded to |
|---|---|
| upstream pause/resume | next tunnel upstream |
| downstream pause/resume | previous tunnel downstream |
Notes and Caveats
Bgp4Clientrequires a pairedBgp4Serverfor useful operation.passwordis not a security feature in the current implementation.- The BGP-like length field excludes the marker and length bytes.
- The first OPEN frame is sent only when the first upstream payload arrives.
- Upstream
estand downstreaminitare disabled callbacks. - This node is a layer-4 stream tunnel, not a packet tunnel.