mirror of
https://github.com/go-gost/x.git
synced 2026-10-19 16:16:32 +00:00
8787aff1084d4abb49e7c660286260d2f64227c7
p2p.go was a complete engine with nothing driving it: no handler.Handler, so no GOST service could reach the hub and a spoke's registration frame had no path to one at all. NewP2PHandler takes the tun device conn and an auther, builds the peerTable (no TTL — a stream close says a peer is gone outright, where a socket peer has only silence to guess from), the peerRouter and the p2pHub, and starts the device reader. Handle installs one accepted stream under its remote address — the peer key the p2p host stamped on it, replacing whatever a reconnect left behind — and feeds its datagrams to the hub until the read fails. Teardown is peerGone and nothing else: it reclaims a peer's routes only while that stream still holds its key, so a stale stream ending cannot cut off the live connection its peer already replaced it with. ownNets comes off the device conn's context, the two steps server.go's Handle already uses, because a nil answer silently disables the self-route guard. Handle returns the read error unwrapped. io.EOF, net.ErrClosed and context.Canceled are what isServerError calls an ordinary end, so a peer reconnecting would otherwise land in someone's error log. The p2p half of the compat suite now runs against the real handler and the real hub rather than reporting itself unavailable: the same six assertions, the same two cases skipped without an auther. A second p2p case covers the reconnect, which is the only way the suite would notice a peerGone that dropped routes unconditionally — a hub that did so passes every shared case.
x
The implementation layer for the GOST proxy framework. Every interface defined in core/ is implemented here — handlers, listeners, dialers, connectors, plus config parsing, registries, and all cross-cutting concerns.
Package layout
| Directory | Purpose |
|---|---|
handler/ |
Protocol handlers (http, socks4/5, ss, ssh, tunnel, tun, dns, redirect, etc.) |
listener/ |
Protocol listeners (tcp, tls, ws, http2/3, quic, kcp, icmp, tun, udp, etc.) |
dialer/ |
Outbound dialers (tcp, tls, ws, http2/3, quic, grpc, ssh, wg, kcp, icmp, etc.) |
connector/ |
Destination connectors (http, socks4/5, ss, ssh, relay, tunnel, direct, etc.) |
config/ |
Config struct, YAML/JSON parsing, and service construction |
registry/ |
Typed global registries for all component types |
service/ |
Accept loop wiring listener + handler |
chain/ |
Multi-hop forwarding chain and route implementation |
router/ |
Route table router (destination-based routing) |
hop/ |
Node group with load-balanced selection |
selector/ |
Load-balancing strategies (round-robin, random, weighted, hash) |
auth/, bypass/, admission/ |
Authentication, bypass rules, admission control |
resolver/, hosts/ |
DNS resolution and host mapping |
limiter/ |
Traffic, connection, and rate limiters |
recorder/, observer/ |
Traffic recording and observability |
ingress/, sd/, routing/ |
Ingress control, service discovery, routing rules |
logger/, metrics/, api/ |
Logging, Prometheus metrics, Web API |
metadata/, ctx/ |
Metadata key-value system and context propagation |
internal/ |
Shared internals — not importable externally |
Component pattern
Every handler, listener, dialer, and connector follows the same pattern: init() registers a constructor into a global registry, the constructor takes functional options, and Init(metadata.Metadata) extracts typed configuration from the metadata key-value map.
See CLAUDE.md for detailed architecture and conventions.
Languages
Go
100%