fix: add status field to service list/detail APIs, unify observeStats retry pattern, fix router bugs

- api: add fillServiceStatus helper and call it from getServiceList/getService
  so status field appears in service list and detail API responses
- observeStats: unify retry pattern across all 9 handlers (http, http2, masque,
  relay, router, socks4, socks5, tungo, tunnel) — buffer events on failure,
  continue to skip fresh collection, clear on success; fix event-loss bug
  where interim events were dropped during retry cycles
- handler/router: check WriteTo/Write return errors in associate.go and
  entrypoint.go; fix DelConnector and ConnectorPool.Del using RLock instead
  of Lock (write under read lock); remove unused fields t and cancel
This commit is contained in:
ginuerzh
2026-06-03 22:12:08 +08:00
parent 785d52da31
commit 95874c53f5
14 changed files with 150 additions and 103 deletions
+15 -5
View File
@@ -52,7 +52,9 @@ func (h *routerHandler) handleAssociate(ctx context.Context, conn net.Conn, netw
if !rid.Equal(routerID) {
resp.Status = relay.StatusHostUnreachable
resp.WriteTo(conn)
if _, werr := resp.WriteTo(conn); werr != nil {
log.Error(werr)
}
err := fmt.Errorf("no route to host %s", host)
log.Error(err)
return err
@@ -62,7 +64,9 @@ func (h *routerHandler) handleAssociate(ctx context.Context, conn net.Conn, netw
uuid, err := uuid.NewRandom()
if err != nil {
resp.Status = relay.StatusInternalServerError
resp.WriteTo(conn)
if _, werr := resp.WriteTo(conn); werr != nil {
log.Error(werr)
}
return
}
connectorID := relay.NewConnectorID(uuid[:])
@@ -72,7 +76,9 @@ func (h *routerHandler) handleAssociate(ctx context.Context, conn net.Conn, netw
ID: connectorID,
},
)
resp.WriteTo(conn)
if _, werr := resp.WriteTo(conn); werr != nil {
log.Error(werr)
}
conn = &packetConn{conn}
@@ -203,7 +209,9 @@ func (h *routerHandler) handlePacket(ctx context.Context, data []byte, routerID
if c := h.pool.Get(routerID, route.Gateway); c != nil {
if w := c.Writer(); w != nil {
w.Write(data)
if _, werr := w.Write(data); werr != nil {
log.Error(werr)
}
}
return nil
}
@@ -231,7 +239,9 @@ func (h *routerHandler) handlePacket(ctx context.Context, data []byte, routerID
req.WriteTo(&buf)
buf.Write(data)
h.epConn.WriteTo(buf.Bytes(), raddr)
if _, werr := h.epConn.WriteTo(buf.Bytes(), raddr); werr != nil {
log.Error(werr)
}
return nil
}
+3 -1
View File
@@ -48,7 +48,9 @@ func (h *routerHandler) handleEntrypoint(log logger.Logger) error {
if c := h.pool.Get(routerID, gateway); c != nil {
if w := c.Writer(); w != nil {
w.Write(buf[nn:])
if _, werr := w.Write(buf[nn:]); werr != nil {
log.Error(werr)
}
}
}
+10 -5
View File
@@ -273,17 +273,22 @@ func (h *routerHandler) observeStats(ctx context.Context) {
for {
select {
case <-ticker.C:
// Try to flush any buffered events from a previous failed attempt.
if len(events) > 0 {
if err := h.options.Observer.Observe(ctx, events); err == nil {
events = nil
if err := h.options.Observer.Observe(ctx, events); err != nil {
continue
}
break
}
// Collect and send fresh events.
evs := h.stats.Events()
if err := h.options.Observer.Observe(ctx, evs); err != nil {
events = evs
if len(evs) > 0 {
if err := h.options.Observer.Observe(ctx, evs); err != nil {
events = evs
continue
}
}
events = nil
case <-ctx.Done():
return
+4 -13
View File
@@ -1,10 +1,8 @@
package router
import (
"context"
"io"
"sync"
"time"
"github.com/go-gost/core/logger"
"github.com/go-gost/relay"
@@ -76,7 +74,6 @@ type Router struct {
node string
id relay.TunnelID
connectors map[string][]*Connector
t time.Time
close chan struct{}
mu sync.RWMutex
}
@@ -86,7 +83,6 @@ func NewRouter(node string, rid relay.TunnelID) *Router {
node: node,
id: rid,
connectors: make(map[string][]*Connector),
t: time.Now(),
close: make(chan struct{}),
}
return r
@@ -139,8 +135,8 @@ func (r *Router) GetConnector(host string) *Connector {
}
func (r *Router) DelConnector(host string, cid relay.ConnectorID) {
r.mu.RLock()
defer r.mu.RUnlock()
r.mu.Lock()
defer r.mu.Unlock()
connectors := r.connectors[host]
for i, c := range connectors {
@@ -174,7 +170,6 @@ type ConnectorPool struct {
node string
routers map[relay.TunnelID]*Router
mu sync.RWMutex
cancel context.CancelFunc
}
func NewConnectorPool(node string) *ConnectorPool {
@@ -219,8 +214,8 @@ func (p *ConnectorPool) Del(rid relay.TunnelID, host string, cid relay.Connector
return
}
p.mu.RLock()
defer p.mu.RUnlock()
p.mu.Lock()
defer p.mu.Unlock()
r := p.routers[rid]
if r == nil {
@@ -235,10 +230,6 @@ func (p *ConnectorPool) Close() error {
return nil
}
if p.cancel != nil {
p.cancel()
}
p.mu.Lock()
defer p.mu.Unlock()