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:
@@ -109,6 +109,7 @@ func (l *tunListener) parseMetadata(md mdata.Metadata) (err error) {
|
|||||||
if config.Router == nil && len(l.routes) > 0 {
|
if config.Router == nil && len(l.routes) > 0 {
|
||||||
config.Router = xrouter.NewRouter(
|
config.Router = xrouter.NewRouter(
|
||||||
xrouter.RoutesOption(l.routes),
|
xrouter.RoutesOption(l.routes),
|
||||||
|
xrouter.NoSysRouteOption(),
|
||||||
xrouter.LoggerOption(logger.Default().WithFields(map[string]any{
|
xrouter.LoggerOption(logger.Default().WithFields(map[string]any{
|
||||||
"kind": "router",
|
"kind": "router",
|
||||||
"router": "@internal",
|
"router": "@internal",
|
||||||
|
|||||||
+16
-2
@@ -22,6 +22,7 @@ type options struct {
|
|||||||
redisLoader loader.Loader
|
redisLoader loader.Loader
|
||||||
httpLoader loader.Loader
|
httpLoader loader.Loader
|
||||||
period time.Duration
|
period time.Duration
|
||||||
|
noSysRoute bool
|
||||||
logger logger.Logger
|
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.
|
// LoggerOption sets the logger for the router.
|
||||||
func LoggerOption(logger logger.Logger) Option {
|
func LoggerOption(logger logger.Logger) Option {
|
||||||
return func(opts *options) {
|
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))
|
p.options.logger.Debugf("load items %d", len(routes))
|
||||||
|
|
||||||
if err := p.setSysRoutes(routes...); err != nil {
|
if !p.options.noSysRoute {
|
||||||
p.options.logger.Error(err)
|
if err := p.setSysRoutes(routes...); err != nil {
|
||||||
|
p.options.logger.Error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
|
|||||||
Reference in New Issue
Block a user