fix bug

Kim committed Mar 18, 2026 at 11:56 UTC d1da145c8e82d6ae133a5df8f028985da30514af
2 files changed +20 -15
cmd/portal-tunnel/main.go
+3
@@ -244,6 +244,9 @@ func runTunnel(
244 // UDP is best-effort — attach to existing lease, log and continue if it fails.
245 if capabilities.SupportsDatagram() && !capabilities.SupportsStream() {
246 runErr := runUDPBestEffort(ctx, exposure, target)
247 + if errors.Is(runErr, context.Canceled) {
248 + runErr = nil
249 + }
250 closeErr := exposure.Close()
251 if runErr != nil && stop != nil {
252 stop()
portal/server.go
+17 -15
@@ -19,7 +19,7 @@ import (
19 "golang.org/x/sync/errgroup"
20
21 "github.com/gosuda/portal/v2/portal/acme"
22 - portaldatagram "github.com/gosuda/portal/v2/portal/datagram"
22 + "github.com/gosuda/portal/v2/portal/datagram"
23 "github.com/gosuda/portal/v2/portal/keyless"
24 "github.com/gosuda/portal/v2/portal/policy"
25 "github.com/gosuda/portal/v2/types"
@@ -42,7 +42,7 @@ const (
42 )
43
44 type quicSNIRoute struct {
45 - flowMux *portaldatagram.FlowMux
45 + flowMux *datagram.FlowMux
46 lastSeen time.Time
47 }
48
@@ -74,7 +74,7 @@ type Server struct {
74 cancel context.CancelFunc
75 group *errgroup.Group
76 registry *leaseRegistry
77 - ports *portaldatagram.PortAllocator
77 + ports *datagram.PortAllocator
78 cfg ServerConfig
79 rootHost string
80 shutdownOnce sync.Once
@@ -105,7 +105,7 @@ func NewServer(cfg ServerConfig) (*Server, error) {
105 }
106
107 registry := newLeaseRegistry(policy.NewRuntime())
108 - ports := portaldatagram.NewPortAllocator(cfg.UDPPortMin, cfg.UDPPortMax, 5*time.Minute)
108 + ports := datagram.NewPortAllocator(cfg.UDPPortMin, cfg.UDPPortMax, 5*time.Minute)
109
110 s := &Server{
111 cfg: cfg,
@@ -404,7 +404,7 @@ func (s *Server) resolveStreamBroker(serverName string) (*streamBroker, error) {
404 return streamBroker, nil
405 }
406
407 -func (s *Server) resolveDatagramFlowMux(serverName string) (*portaldatagram.FlowMux, error) {
407 +func (s *Server) resolveDatagramFlowMux(serverName string) (*datagram.FlowMux, error) {
408 if serverName == s.rootHost {
409 return nil, errors.New("root host does not accept datagram routes")
410 }
@@ -609,18 +609,20 @@ func (s *Server) runQUICSNIRouter(conn net.PacketConn) error {
609
610 func (s *Server) handleQUICSNIPacket(packet []byte, srcAddr net.Addr, now time.Time) {
611 cacheKey := srcAddr.String()
612 - flowMux, ok := s.lookupQUICSNIRoute(cacheKey, now)
613 - if !ok {
614 - serverName, err := portaldatagram.ParseQUICInitialSNI(packet)
615 - if err != nil || serverName == "" {
616 - return
617 - }
618 -
612 + serverName, err := datagram.ParseQUICInitialSNI(packet)
613 + var flowMux *datagram.FlowMux
614 + if err == nil && serverName != "" {
615 flowMux, err = s.resolveDatagramFlowMux(utils.NormalizeHostname(serverName))
616 if err != nil || flowMux == nil {
617 return
618 }
619 s.storeQUICSNIRoute(cacheKey, flowMux, now)
620 + } else {
621 + var ok bool
622 + flowMux, ok = s.lookupQUICSNIRoute(cacheKey, now)
623 + if !ok {
624 + return
625 + }
626 }
627
628 udpAddr, ok := srcAddr.(*net.UDPAddr)
@@ -640,7 +642,7 @@ func (s *Server) handleQUICSNIPacket(packet []byte, srcAddr net.Addr, now time.T
642 }
643 }
644
643 -func (s *Server) lookupQUICSNIRoute(key string, now time.Time) (*portaldatagram.FlowMux, bool) {
645 +func (s *Server) lookupQUICSNIRoute(key string, now time.Time) (*datagram.FlowMux, bool) {
646 s.quicSNIMu.Lock()
647 defer s.quicSNIMu.Unlock()
648
@@ -659,7 +661,7 @@ func (s *Server) lookupQUICSNIRoute(key string, now time.Time) (*portaldatagram.
661 return route.flowMux, true
662 }
663
662 -func (s *Server) storeQUICSNIRoute(key string, flowMux *portaldatagram.FlowMux, now time.Time) {
664 +func (s *Server) storeQUICSNIRoute(key string, flowMux *datagram.FlowMux, now time.Time) {
665 s.quicSNIMu.Lock()
666 s.quicSNIRoutes[key] = quicSNIRoute{
667 flowMux: flowMux,
@@ -685,7 +687,7 @@ func (s *Server) cleanupQUICSNIRoutes(now time.Time) {
687 }
688 }
689
688 -func (s *Server) clearQUICSNIRoutesForFlowMux(flowMux *portaldatagram.FlowMux) {
690 +func (s *Server) clearQUICSNIRoutesForFlowMux(flowMux *datagram.FlowMux) {
691 if flowMux == nil {
692 return
693 }