From 332a3a1cd09f47458d4cc465b1afe9a430660d64 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Fri, 26 Apr 2024 20:56:56 +0800 Subject: [PATCH] add p2p option for tun handler --- handler/tun/handler.go | 18 ------------------ handler/tun/metadata.go | 17 ++++++----------- handler/tun/server.go | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/handler/tun/handler.go b/handler/tun/handler.go index 445190e..2f87ffb 100644 --- a/handler/tun/handler.go +++ b/handler/tun/handler.go @@ -12,7 +12,6 @@ import ( "github.com/go-gost/core/handler" "github.com/go-gost/core/hop" md "github.com/go-gost/core/metadata" - "github.com/go-gost/core/router" tun_util "github.com/go-gost/x/internal/util/tun" "github.com/go-gost/x/registry" "github.com/songgao/water/waterutil" @@ -109,23 +108,6 @@ func (h *tunHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler. return h.handleServer(ctx, conn, config, log) } -func (h *tunHandler) findRouteFor(ctx context.Context, dst net.IP, router router.Router) net.Addr { - if v, ok := h.routes.Load(ipToTunRouteKey(dst)); ok { - return v.(net.Addr) - } - - if router == nil { - return nil - } - - if route := router.GetRoute(ctx, dst); route != nil && route.Gateway != nil { - if v, ok := h.routes.Load(ipToTunRouteKey(route.Gateway)); ok { - return v.(net.Addr) - } - } - return nil -} - var mIPProts = map[waterutil.IPProtocol]string{ waterutil.HOPOPT: "HOPOPT", waterutil.ICMP: "ICMP", diff --git a/handler/tun/metadata.go b/handler/tun/metadata.go index 5abb881..0c173eb 100644 --- a/handler/tun/metadata.go +++ b/handler/tun/metadata.go @@ -16,28 +16,23 @@ type metadata struct { bufferSize int keepAlivePeriod time.Duration passphrase string + p2p bool } func (h *tunHandler) parseMetadata(md mdata.Metadata) (err error) { - const ( - bufferSize = "bufferSize" - keepAlive = "keepAlive" - keepAlivePeriod = "ttl" - passphrase = "passphrase" - ) - - h.md.bufferSize = mdutil.GetInt(md, bufferSize) + h.md.bufferSize = mdutil.GetInt(md, "tun.bufsize", "bufsize", "buffersize") if h.md.bufferSize <= 0 { h.md.bufferSize = defaultBufferSize } - if mdutil.GetBool(md, keepAlive) { - h.md.keepAlivePeriod = mdutil.GetDuration(md, keepAlivePeriod) + if mdutil.GetBool(md, "tun.keepalive", "keepalive") { + h.md.keepAlivePeriod = mdutil.GetDuration(md, "tun.ttl", "ttl") if h.md.keepAlivePeriod <= 0 { h.md.keepAlivePeriod = defaultKeepAlivePeriod } } - h.md.passphrase = mdutil.GetString(md, passphrase) + h.md.passphrase = mdutil.GetString(md, "tun.token", "token", "passphrase") + h.md.p2p = mdutil.GetBool(md, "tun.p2p", "p2p") return } diff --git a/handler/tun/server.go b/handler/tun/server.go index 64c9b8e..ad22d20 100644 --- a/handler/tun/server.go +++ b/handler/tun/server.go @@ -10,6 +10,7 @@ import ( "github.com/go-gost/core/common/bufpool" "github.com/go-gost/core/logger" + "github.com/go-gost/core/router" tun_util "github.com/go-gost/x/internal/util/tun" "github.com/songgao/water/waterutil" "golang.org/x/net/ipv4" @@ -203,11 +204,13 @@ func (h *tunHandler) transportServer(ctx context.Context, tun io.ReadWriter, con return nil } - if addr := h.findRouteFor(ctx, dst, config.Router); addr != nil { - log.Debugf("find route: %s -> %s", dst, addr) + if !h.md.p2p { + if addr := h.findRouteFor(ctx, dst, config.Router); addr != nil { + log.Debugf("find route: %s -> %s", dst, addr) - _, err := conn.WriteTo(b[:n], addr) - return err + _, err := conn.WriteTo(b[:n], addr) + return err + } } if _, err := tun.Write(b[:n]); err != nil { @@ -231,6 +234,9 @@ func (h *tunHandler) transportServer(ctx context.Context, tun io.ReadWriter, con } func (h *tunHandler) updateRoute(ip net.IP, addr net.Addr, log logger.Logger) { + if h.md.p2p { + ip = net.IPv6zero + } rkey := ipToTunRouteKey(ip) if actual, loaded := h.routes.LoadOrStore(rkey, addr); loaded { if actual.(net.Addr).String() != addr.String() { @@ -242,3 +248,25 @@ func (h *tunHandler) updateRoute(ip net.IP, addr net.Addr, log logger.Logger) { log.Debugf("new route: %s -> %s", ip, addr) } } + +func (h *tunHandler) findRouteFor(ctx context.Context, dst net.IP, router router.Router) net.Addr { + if h.md.p2p { + dst = net.IPv6zero + router = nil + } + + if v, ok := h.routes.Load(ipToTunRouteKey(dst)); ok { + return v.(net.Addr) + } + + if router == nil { + return nil + } + + if route := router.GetRoute(ctx, dst); route != nil && route.Gateway != nil { + if v, ok := h.routes.Load(ipToTunRouteKey(route.Gateway)); ok { + return v.(net.Addr) + } + } + return nil +}