feat: add stateless UDP forwarding mode (#853)

Add stateless=true metadata option to UDP listener/handler for raw
datagram forwarding without per-client session tracking, similar to
NGINX Stream Module behavior.

- udp.NewListener: add Stateless field to ListenConfig; branch in
  NewListener/Accept to skip connPool/listenLoop when stateless
- datagramConn: lightweight net.Conn+PacketConn wrapping a single
  UDP datagram — no channels, mutexes, or pool logic
- forward handler: add handleRawDatagram for single request-response
  cycle; extract dialTarget to share hop selection/dial/proxyproto
  preamble with handleRawForwarding

Usage: gost -L "udp://:10000/127.0.0.1:2000?stateless=true"
This commit is contained in:
ginuerzh
2026-06-05 23:26:03 +08:00
parent 5e3280d166
commit e45d9a8cc8
6 changed files with 213 additions and 11 deletions
+9
View File
@@ -36,6 +36,9 @@ type metadata struct {
privateKey crypto.PrivateKey
alpn string
mitmBypass bypass.Bypass
stateless bool
bufferSize int
}
func (h *forwardHandler) parseMetadata(md mdata.Metadata) (err error) {
@@ -70,5 +73,11 @@ func (h *forwardHandler) parseMetadata(md mdata.Metadata) (err error) {
h.md.alpn = mdutil.GetString(md, "mitm.alpn")
h.md.mitmBypass = registry.BypassRegistry().Get(mdutil.GetString(md, "mitm.bypass"))
h.md.stateless = mdutil.GetBool(md, "stateless")
h.md.bufferSize = mdutil.GetInt(md, "bufferSize", "readBufferSize", "udp.bufferSize")
if h.md.bufferSize <= 0 {
h.md.bufferSize = 4096
}
return
}