Files
godoxy/agent/pkg/agent/stream/common.go
yusing fe619f1dd9 feat(agent): agent stream tunneling with TLS and dTLS (UDP); combined agent APIs
- Add `StreamPort` configuration to agent configuration and environment variables
- Implement TCP and UDP stream client support in agent package
- Update agent verification to test stream connectivity (TCP/UDP)
- Add `/info` endpoint to agent HTTP handler for version, name, runtime, and stream port
- Remove /version, /name, /runtime APIs, replaced by /info
- Update agent compose template to expose stream port for TCP and UDP
- Update agent creation API to optionally specify stream port (defaults to port + 1)
- Modify `StreamRoute` to pass agent configuration to stream implementations
- Update `TCPTCPStream` and `UDPUDPStream` to use agent stream tunneling when agent is configured
- Add support for both direct connections and agent-tunneled connections in stream routes

This enables agents to handle TCP and UDP route tunneling, expanding the proxy capabilities beyond HTTP-only connections.
2026-01-07 00:44:12 +08:00

58 lines
1.3 KiB
Go

package stream
import (
"net"
"time"
"github.com/puzpuzpuz/xsync/v4"
"github.com/yusing/goutils/synk"
)
const (
dialTimeout = 10 * time.Second
readDeadline = 10 * time.Second
)
var sizedPool = synk.GetSizedBytesPool()
type CreateConnFunc[Conn net.Conn] func(host, port string) (Conn, error)
type ConnectionManager[Conn net.Conn] struct {
m *xsync.Map[string, Conn]
createConnection CreateConnFunc[Conn]
}
func NewConnectionManager[Conn net.Conn](createConnection CreateConnFunc[Conn]) *ConnectionManager[Conn] {
return &ConnectionManager[Conn]{
m: xsync.NewMap[string, Conn](),
createConnection: createConnection,
}
}
func (c *ConnectionManager[Conn]) GetOrCreateDestConnection(clientConn net.Conn, host, port string) (ret Conn, connErr error) {
clientKey := clientConn.RemoteAddr().String()
ret, _ = c.m.LoadOrCompute(clientKey, func() (conn Conn, cancel bool) {
conn, connErr = c.createConnection(host, port)
if connErr != nil {
cancel = true
}
return
})
return
}
func (c *ConnectionManager[Conn]) DeleteDestConnection(clientConn net.Conn) {
clientKey := clientConn.RemoteAddr().String()
conn, loaded := c.m.LoadAndDelete(clientKey)
if loaded {
conn.Close()
}
}
func (c *ConnectionManager[Conn]) CloseAllConnections() {
for _, conn := range c.m.Range {
conn.Close()
}
c.m.Clear()
}