fix(router): skip system route setup for TUN @internal router

When a TUN listener with `route=::/0` (or any route) creates its
fallback @internal router during parseMetadata/Init, the router
immediately calls setSysRoutes before the TUN device exists. This
causes an ENETUNREACH "no route to host" error logged by the kernel
because the gateway is unreachable at that point.

The system routes are correctly added later by the listener's own
addRoutes() after device creation. The @internal router only needs
in-memory routes for GetRoute lookups.

Add NoSysRouteOption which disables netlink route management while
keeping route data for in-memory queries. Use it in the TUN
listener's @internal router.

Fixes go-gost/x#48
This commit is contained in:
ginuerzh
2026-06-20 15:15:31 +08:00
parent 1d34d4543a
commit 66f502b153
2 changed files with 17 additions and 2 deletions
+16 -2
View File
@@ -22,6 +22,7 @@ type options struct {
redisLoader loader.Loader
httpLoader loader.Loader
period time.Duration
noSysRoute bool
logger logger.Logger
}
@@ -63,6 +64,17 @@ func HTTPLoaderOption(httpLoader loader.Loader) Option {
}
}
// NoSysRouteOption disables automatic system route management via netlink.
// When set, the router only maintains in-memory routes for GetRoute lookups
// and does not attempt to add or replace routes in the OS routing table.
// This is useful when another component (e.g. a TUN listener) manages system
// routes independently.
func NoSysRouteOption() Option {
return func(opts *options) {
opts.noSysRoute = true
}
}
// LoggerOption sets the logger for the router.
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
@@ -141,8 +153,10 @@ func (p *localRouter) reload(ctx context.Context) error {
p.options.logger.Debugf("load items %d", len(routes))
if err := p.setSysRoutes(routes...); err != nil {
p.options.logger.Error(err)
if !p.options.noSysRoute {
if err := p.setSysRoutes(routes...); err != nil {
p.options.logger.Error(err)
}
}
p.mu.Lock()