From ec41202b3c20fefff497a7b29090050ef6af810a Mon Sep 17 00:00:00 2001 From: root Date: Wed, 4 Feb 2026 23:10:56 +0000 Subject: [PATCH] fix(gost): use chain.NewNode() to properly initialize marker for failover When creating temporary Node instances with struct literals like &chain.Node{Addr: host}, the marker field was not initialized. Only chain.NewNode() properly initializes marker = selector.NewFailMarker(). Without a valid marker: - Failed nodes cannot be marked (marker.Mark() is no-op on nil) - Subsequent selections cannot filter out failed nodes - Failover mechanism completely fails Fixed locations: - sniffer.go dial(): &chain.Node{Addr: host} -> chain.NewNode("", host) - sniffer.go dialTLS(): &chain.Node{Addr: host} -> chain.NewNode("", host) - local/handler.go: target := &chain.Node{} -> var target *chain.Node - remote/handler.go: &chain.Node{Addr: host} -> chain.NewNode("", host) --- go-gost/x/handler/forward/local/handler.go | 2 +- go-gost/x/handler/forward/remote/handler.go | 4 +--- go-gost/x/internal/util/forwarder/sniffer.go | 8 ++------ 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/go-gost/x/handler/forward/local/handler.go b/go-gost/x/handler/forward/local/handler.go index 4f7881b..b1e47bf 100644 --- a/go-gost/x/handler/forward/local/handler.go +++ b/go-gost/x/handler/forward/local/handler.go @@ -195,7 +195,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand for attempt := 0; attempt < maxRetries; attempt++ { // Select a target node, excluding previously tried nodes selectCtx := ctxvalue.ContextWithExcludeNodes(ctx, triedNodes) - target := &chain.Node{} + var target *chain.Node if h.hop != nil { target = h.hop.Select(selectCtx, hop.ProtocolSelectOption(proto), diff --git a/go-gost/x/handler/forward/remote/handler.go b/go-gost/x/handler/forward/remote/handler.go index 35f604a..bad9d2e 100644 --- a/go-gost/x/handler/forward/remote/handler.go +++ b/go-gost/x/handler/forward/remote/handler.go @@ -225,9 +225,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand selectCtx := ctxvalue.ContextWithExcludeNodes(ctx, triedNodes) var target *chain.Node if host != "" { - target = &chain.Node{ - Addr: host, - } + target = chain.NewNode("", host) } if h.hop != nil { target = h.hop.Select(selectCtx, diff --git a/go-gost/x/internal/util/forwarder/sniffer.go b/go-gost/x/internal/util/forwarder/sniffer.go index 4d9c153..8623c2e 100644 --- a/go-gost/x/internal/util/forwarder/sniffer.go +++ b/go-gost/x/internal/util/forwarder/sniffer.go @@ -263,9 +263,7 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho // Select a node, excluding previously tried nodes selectCtx := ctxvalue.ContextWithExcludeNodes(ctx, triedNodes) - node = &chain.Node{ - Addr: host, - } + node = chain.NewNode("", host) if ho.Hop != nil { node = ho.Hop.Select(selectCtx, hop.ClientIPSelectOption(net.ParseIP(ro.ClientIP)), @@ -903,9 +901,7 @@ func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) ( node = nil if host != "" { - node = &chain.Node{ - Addr: host, - } + node = chain.NewNode("", host) } if ho.Hop != nil { node = ho.Hop.Select(selectCtx,