ConnectionFisherClient
ConnectionFisherClient is the client-side peer for
ConnectionFisherServer. For every incoming WaterWall line, it creates several
simultaneous child lines toward next, sends a fixed 5-byte probe on each one,
and keeps the first child line that receives the expected server reply.
This is useful when the outbound path is unstable or when you intentionally want
to race several connection attempts and keep the first path that proves it
reached a matching ConnectionFisherServer.
Typical Placement
Simple TCP layout:
TcpListener -> ConnectionFisherClient -> TcpConnector
TcpListener -> ConnectionFisherServer -> TcpConnector
With other stream tunnels in between:
TesterClient -> ConnectionFisherClient -> MuxClient -> MuxServer -> ConnectionFisherServer -> TesterServer
The client and server must be paired in the same logical stream path. Any intermediate tunnels must preserve the fixed probe bytes end to end.
What It Does
- Reads
settings.simultaneous-tries-perline. - Creates that many internal child lines for every upstream
Initon the main line. - Sends upstream
Inittonexton every child line. - Sends the fixed client probe
FISH?on every child line. - Waits for the fixed server reply
FISH!. - Buffers upstream payload on the main line while no child has been selected.
- Selects the first child that receives a valid reply.
- Closes all non-selected child lines.
- Flushes queued upstream payload to the selected child in order.
- Bridges downstream payload from the selected child back to the main line.
ConnectionFisherClient is a middle stream tunnel. It does not create sockets
directly and it does not create packet lines.
Configuration Example
{
"name": "fisher-client",
"type": "ConnectionFisherClient",
"settings": {
"simultaneous-tries-perline": 3
},
"next": "tcp-out"
}
Matching server side:
{
"name": "fisher-server",
"type": "ConnectionFisherServer",
"next": "service"
}
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 "ConnectionFisherClient". |
next | string | Required. The next stream node receives the internal candidate child lines. |
ConnectionFisherClient must also have a previous node in the chain. It is not
a chain head or chain end.
Optional Settings
| Setting | Type | Default | Description |
|---|---|---|---|
simultaneous-tries-perline | integer >= 1 | 2 | Number of candidate child lines created for each incoming main line. |
settings may be omitted. If present, values smaller than 1 are rejected.
Probe Exchange
The probe is fixed and has no configurable secret:
| Direction | Bytes | Meaning |
|---|---|---|
| client to server | FISH? | Sent by every child line immediately after child upstream Init. |
| server to client | FISH! | Required reply from ConnectionFisherServer. |
These markers only prove that the child line reached a matching
ConnectionFisherServer. They are not authentication, encryption, or traffic
integrity protection.
Line Model
ConnectionFisherClient uses two kinds of lines:
| Line | Purpose |
|---|---|
| main line | The original incoming line from the previous node. It stays on the previous side. |
| child lines | Internal candidate lines created by the client and sent only toward next. |
The original main line is never sent directly to next. Child lines are never
sent toward prev. After one child is selected, the tunnel manually bridges
payload, Est, Pause, Resume, and Finish between the main line and the
selected child.
Selection Flow
For each upstream Init on the main line:
- The main line state is initialized.
simultaneous-tries-perlinechild lines are created on the same worker.- Each child line is initialized toward
next. - Each child sends
FISH?. - The main line schedules a 5000 ms selection timeout.
- Upstream payload on the main line is queued until a child wins.
- The first child to receive
FISH!becomes the selected child. - Losing child lines are closed.
- Queued upstream payload is flushed to the selected child.
- Any extra downstream bytes already buffered after
FISH!are sent to the previous node as downstream payload.
If no child validates before the timeout, the main line is closed.
Buffering and Limits
| Limit | Value | Behavior |
|---|---|---|
| Selection timeout | 5000 ms | Main line closes if no child is selected in time. |
| Pending upstream payload | 1 MiB | Main line closes if queued upstream payload exceeds this while waiting for selection. |
| Child handshake buffer | 4096 bytes | Main line closes if a child accumulates too much non-selected handshake data. |
| Required left padding | 0 | The client does not prepend protocol headers to existing payload buffers. |
The FISH? probe is allocated as its own small buffer. User payload is queued
or forwarded as existing WaterWall buffers.
Lifecycle Behavior
Before selection:
- upstream payload from the main line is queued
- downstream payload from a child is treated as handshake data
- downstream
Estmarks the child established but is not forwarded to the main line unless that child is already selected - pause and resume are not reflected to the main line until a selected child is available
After selection:
- upstream payload on the main line is forwarded to the selected child with
tunnelNextUpStreamPayload - downstream payload on the selected child is forwarded to the previous node with
tunnelPrevDownStreamPayload - downstream
Estfrom the selected child is forwarded once to the previous node - pause and resume are bridged only across the selected child/main-line pair
If the selected child closes, the main line is closed. If every child closes before a winner is selected, the main line is also closed.
Notes and Caveats
- Use it with a matching
ConnectionFisherServer. - It is intended for stream-style chains, not packet-line chains.
- It creates multiple outbound candidate lines for each incoming line, so
increasing
simultaneous-tries-perlinealso increases connection load. - The probe is fixed and public; use TLS, encryption, authentication, or routing nodes around it when the path needs security.
- Upstream
Estand downstreamInitare disabled callbacks for this node.