traffic.md RawHistoryFolder

Traffic Plane Configuration

Gordon models network listeners as a traffic graph: entrypoints receive packets or connections, routers select a service, and services resolve to backends.

Smart TCP Edge Entrypoint

Public application traffic is normally exposed with a smart_tcp entrypoint. The conventional route-capable entrypoint name is edge, but Gordon does not require that name or assign a built-in public port. When exactly one route-capable smart_tcp or tls_mux entrypoint exists, app HTTP hosts use it even if it has a custom name. Choose the address that matches your deployment, firewall, and container mapping:

[entrypoints.edge]
address = ":443"
protocol = "smart_tcp"
trusted_cidrs = []

Do not treat entrypoints.edge.address as an HTTP port or an HTTPS port. It is one TCP socket that sniffs each new connection and dispatches the original byte stream.

Supported entrypoint protocols are smart_tcp, tls_mux, tcp, and udp. smart_tcp is the primary public edge model; tls_mux can also serve app HTTP hosts through TLS fallback, tcp and udp are for explicit L4 services, and UDP remains separate from the TCP entrypoint.

Smart TCP Dispatch Order

For each accepted connection on a smart_tcp entrypoint Gordon:

  1. Applies entrypoint-wide trusted_cidrs to the peer socket IP.
  2. Rejects PROXY protocol v1 and v2 prefixes. PROXY headers are not trusted or parsed.
  3. Peeks a minimal prefix and replays the bytes to the selected handler/backend.
  4. Dispatches cleartext HTTP/1.x and h2c prior-knowledge to Gordon's HTTP handler.
  5. Dispatches TLS ClientHello traffic by SNI:
    • matching TLS passthrough router -> raw TCP backend without TLS termination;
    • no passthrough match -> normal Gordon HTTPS fallback.
  6. Dispatches unknown non-HTTP/non-TLS bytes only to an explicit raw fallback router, after raw-fallback source policy allows it.
  7. Refuses the connection when no deterministic handler or allowed fallback exists.

Malformed HTTP-looking or TLS-looking traffic is rejected instead of bypassing to raw fallback.

Standalone and Network Services

Standalone services are Gordon-managed containers that L4 routers can target with service:<service>:<port-name>. Define them under [[services]] when Gordon should own the container lifecycle.

[[services]]
name = "rust"
image = "registry.example.com:5000/rust:latest"
enabled = true

[[services.ports]]
name = "game"
container = 28015
protocol = "udp"
publish = "127.0.0.1:38015"

[entrypoints.rust]
address = "0.0.0.0:28015"
protocol = "udp"

[[traffic.udp.routers]]
name = "rust-game"
entrypoint = "rust"
service = "service:rust:game"

Network services describe manually managed non-HTTP backends that L4 routers can target.

[[network_services]]
name = "postgres"

[[network_services.ports]]
name = "db"
container = 5432
protocol = "tcp"

Service references use:

  • route:<domain> for app HTTP hosts from ACTIVE state (merged with installation external routes)
  • external_route:<domain> for configured external HTTP routes
  • network_service:<service>:<port-name> for manually managed TCP, UDP, and TLS passthrough backends
  • service:<service>:<port-name> for Gordon-managed standalone service backends

static:<name> is reserved and currently unsupported.

TLS Passthrough on Smart TCP

TLS passthrough routers run on smart_tcp or tls_mux entrypoints and route by ClientHello SNI without terminating TLS.

[entrypoints.edge]
address = ":443"
protocol = "smart_tcp"

[[traffic.tls.routers]]
name = "raw-tls"
entrypoint = "edge"
sni = "raw.example.com"
service = "network_service:raw:tls"

Exact SNI matches win over wildcard matches. Ambiguous wildcard overlaps and HTTP-host/TLS-passthrough conflicts on the same smart TCP entrypoint are rejected at validation time. App HTTPS hosts that do not match a passthrough SNI use Gordon's normal HTTPS fallback and certificate selection.

Raw TCP Fallback

Raw fallback is disabled by default. Unknown non-HTTP/non-TLS bytes reach a TCP backend only when the smart TCP entrypoint explicitly names one TCP router as raw_fallback and the source policy allows the peer socket IP.

[entrypoints.edge]
address = ":443"
protocol = "smart_tcp"
raw_fallback = "ssh-fallback"
raw_fallback_trusted_cidrs = ["100.64.0.0/10"]

[[traffic.tcp.routers]]
name = "ssh-fallback"
entrypoint = "edge"
service = "network_service:ssh:ssh"

Use raw_fallback_trusted_cidrs for private raw fallback exposure. To expose raw fallback publicly, acknowledge it explicitly:

[entrypoints.edge]
address = ":443"
protocol = "smart_tcp"
raw_fallback = "public-raw"
allow_public_raw_fallback = true

trusted_cidrs and raw_fallback_trusted_cidrs both use the peer socket IP. They do not use X-Forwarded-For.

TCP Routers

Plain TCP entrypoints support one TCP router per entrypoint. TCP routers on a smart_tcp entrypoint are valid only when referenced by that entrypoint's raw_fallback.

[entrypoints.postgres]
address = "0.0.0.0:5432"
protocol = "tcp"
trusted_cidrs = ["100.64.0.0/10"]

[traffic.tcp]
dial_timeout = "10s"
idle_timeout = "5m"
drain_timeout = "30s"
max_connections = 1024

[[traffic.tcp.routers]]
name = "postgres"
entrypoint = "postgres"
service = "network_service:postgres:db"

If max_connections is omitted or set to 0, Gordon applies the safe runtime default of 1024 active connections per entrypoint.

UDP Routers

UDP is not sniffed or unified into smart TCP. Use a separate UDP entrypoint:

[entrypoints.game]
address = "0.0.0.0:7777"
protocol = "udp"

[traffic.udp]
idle_timeout = "30s"
drain_timeout = "30s"
max_sessions = 4096

[[traffic.udp.routers]]
name = "game"
entrypoint = "game"
service = "network_service:game:game"

UDP sessions are keyed by client address and expire after idle_timeout. If max_sessions is omitted or set to 0, Gordon applies the safe runtime default of 4096 active sessions per entrypoint.

source
1# Traffic Plane Configuration
2
3Gordon models network listeners as a traffic graph: entrypoints receive packets or connections, routers select a service, and services resolve to backends.
4
5## Smart TCP Edge Entrypoint
6
7Public application traffic is normally exposed with a `smart_tcp` entrypoint. The conventional route-capable entrypoint name is `edge`, but Gordon does not require that name or assign a built-in public port. When exactly one route-capable `smart_tcp` or `tls_mux` entrypoint exists, app HTTP hosts use it even if it has a custom name. Choose the address that matches your deployment, firewall, and container mapping:
8
9```toml
10[entrypoints.edge]
11address = ":443"
12protocol = "smart_tcp"
13trusted_cidrs = []
14```
15
16Do not treat `entrypoints.edge.address` as an HTTP port or an HTTPS port. It is one TCP socket that sniffs each new connection and dispatches the original byte stream.
17
18Supported entrypoint protocols are `smart_tcp`, `tls_mux`, `tcp`, and `udp`. `smart_tcp` is the primary public edge model; `tls_mux` can also serve app HTTP hosts through TLS fallback, `tcp` and `udp` are for explicit L4 services, and UDP remains separate from the TCP entrypoint.
19
20## Smart TCP Dispatch Order
21
22For each accepted connection on a `smart_tcp` entrypoint Gordon:
23
241. Applies entrypoint-wide `trusted_cidrs` to the peer socket IP.
252. Rejects PROXY protocol v1 and v2 prefixes. PROXY headers are not trusted or parsed.
263. Peeks a minimal prefix and replays the bytes to the selected handler/backend.
274. Dispatches cleartext HTTP/1.x and h2c prior-knowledge to Gordon's HTTP handler.
285. Dispatches TLS ClientHello traffic by SNI:
29   - matching TLS passthrough router -> raw TCP backend without TLS termination;
30   - no passthrough match -> normal Gordon HTTPS fallback.
316. Dispatches unknown non-HTTP/non-TLS bytes only to an explicit raw fallback router, after raw-fallback source policy allows it.
327. Refuses the connection when no deterministic handler or allowed fallback exists.
33
34Malformed HTTP-looking or TLS-looking traffic is rejected instead of bypassing to raw fallback.
35
36## Standalone and Network Services
37
38Standalone services are Gordon-managed containers that L4 routers can target with `service:<service>:<port-name>`. Define them under `[[services]]` when Gordon should own the container lifecycle.
39
40```toml
41[[services]]
42name = "rust"
43image = "registry.example.com:5000/rust:latest"
44enabled = true
45
46[[services.ports]]
47name = "game"
48container = 28015
49protocol = "udp"
50publish = "127.0.0.1:38015"
51
52[entrypoints.rust]
53address = "0.0.0.0:28015"
54protocol = "udp"
55
56[[traffic.udp.routers]]
57name = "rust-game"
58entrypoint = "rust"
59service = "service:rust:game"
60```
61
62Network services describe manually managed non-HTTP backends that L4 routers can target.
63
64```toml
65[[network_services]]
66name = "postgres"
67
68[[network_services.ports]]
69name = "db"
70container = 5432
71protocol = "tcp"
72```
73
74Service references use:
75
76- `route:<domain>` for app HTTP hosts from ACTIVE state (merged with installation external routes)
77- `external_route:<domain>` for configured external HTTP routes
78- `network_service:<service>:<port-name>` for manually managed TCP, UDP, and TLS passthrough backends
79- `service:<service>:<port-name>` for Gordon-managed standalone service backends
80
81`static:<name>` is reserved and currently unsupported.
82
83## TLS Passthrough on Smart TCP
84
85TLS passthrough routers run on `smart_tcp` or `tls_mux` entrypoints and route by ClientHello SNI without terminating TLS.
86
87```toml
88[entrypoints.edge]
89address = ":443"
90protocol = "smart_tcp"
91
92[[traffic.tls.routers]]
93name = "raw-tls"
94entrypoint = "edge"
95sni = "raw.example.com"
96service = "network_service:raw:tls"
97```
98
99Exact SNI matches win over wildcard matches. Ambiguous wildcard overlaps and HTTP-host/TLS-passthrough conflicts on the same smart TCP entrypoint are rejected at validation time. App HTTPS hosts that do not match a passthrough SNI use Gordon's normal HTTPS fallback and certificate selection.
100
101## Raw TCP Fallback
102
103Raw fallback is disabled by default. Unknown non-HTTP/non-TLS bytes reach a TCP backend only when the smart TCP entrypoint explicitly names one TCP router as `raw_fallback` and the source policy allows the peer socket IP.
104
105```toml
106[entrypoints.edge]
107address = ":443"
108protocol = "smart_tcp"
109raw_fallback = "ssh-fallback"
110raw_fallback_trusted_cidrs = ["100.64.0.0/10"]
111
112[[traffic.tcp.routers]]
113name = "ssh-fallback"
114entrypoint = "edge"
115service = "network_service:ssh:ssh"
116```
117
118Use `raw_fallback_trusted_cidrs` for private raw fallback exposure. To expose raw fallback publicly, acknowledge it explicitly:
119
120```toml
121[entrypoints.edge]
122address = ":443"
123protocol = "smart_tcp"
124raw_fallback = "public-raw"
125allow_public_raw_fallback = true
126```
127
128`trusted_cidrs` and `raw_fallback_trusted_cidrs` both use the peer socket IP. They do not use `X-Forwarded-For`.
129
130## TCP Routers
131
132Plain TCP entrypoints support one TCP router per entrypoint. TCP routers on a `smart_tcp` entrypoint are valid only when referenced by that entrypoint's `raw_fallback`.
133
134```toml
135[entrypoints.postgres]
136address = "0.0.0.0:5432"
137protocol = "tcp"
138trusted_cidrs = ["100.64.0.0/10"]
139
140[traffic.tcp]
141dial_timeout = "10s"
142idle_timeout = "5m"
143drain_timeout = "30s"
144max_connections = 1024
145
146[[traffic.tcp.routers]]
147name = "postgres"
148entrypoint = "postgres"
149service = "network_service:postgres:db"
150```
151
152If `max_connections` is omitted or set to `0`, Gordon applies the safe runtime default of `1024` active connections per entrypoint.
153
154## UDP Routers
155
156UDP is not sniffed or unified into smart TCP. Use a separate UDP entrypoint:
157
158```toml
159[entrypoints.game]
160address = "0.0.0.0:7777"
161protocol = "udp"
162
163[traffic.udp]
164idle_timeout = "30s"
165drain_timeout = "30s"
166max_sessions = 4096
167
168[[traffic.udp.routers]]
169name = "game"
170entrypoint = "game"
171service = "network_service:game:game"
172```
173
174UDP sessions are keyed by client address and expire after `idle_timeout`. If `max_sessions` is omitted or set to `0`, Gordon applies the safe runtime default of `4096` active sessions per entrypoint.
175
176## Related
177
178- [Server Settings](./server.md)
179- [App Manifest](./apps.md)
180- [Standalone Services](./services.md)
181- [CLI traffic status](../cli/daemon.md#gordon-daemon-traffic)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close