Add auto_route and auto_detect_interface for linux
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/sagernet/sing-box/common/dialer"
|
||||
"github.com/sagernet/sing-box/common/geoip"
|
||||
"github.com/sagernet/sing-box/common/geosite"
|
||||
"github.com/sagernet/sing-box/common/iffmonitor"
|
||||
"github.com/sagernet/sing-box/common/sniff"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/dns"
|
||||
@@ -62,6 +63,9 @@ type Router struct {
|
||||
defaultTransport adapter.DNSTransport
|
||||
transports []adapter.DNSTransport
|
||||
transportMap map[string]adapter.DNSTransport
|
||||
|
||||
autoDetectInterface bool
|
||||
interfaceMonitor iffmonitor.InterfaceMonitor
|
||||
}
|
||||
|
||||
func NewRouter(ctx context.Context, logger log.Logger, options option.RouteOptions, dnsOptions option.DNSOptions) (*Router, error) {
|
||||
@@ -80,6 +84,7 @@ func NewRouter(ctx context.Context, logger log.Logger, options option.RouteOptio
|
||||
defaultDetour: options.Final,
|
||||
dnsClient: dns.NewClient(dnsOptions.DNSClientOptions),
|
||||
defaultDomainStrategy: C.DomainStrategy(dnsOptions.Strategy),
|
||||
autoDetectInterface: options.AutoDetectInterface,
|
||||
}
|
||||
for i, ruleOptions := range options.Rules {
|
||||
routeRule, err := NewRule(router, logger, ruleOptions)
|
||||
@@ -181,6 +186,14 @@ func NewRouter(ctx context.Context, logger log.Logger, options option.RouteOptio
|
||||
router.defaultTransport = defaultTransport
|
||||
router.transports = transports
|
||||
router.transportMap = transportMap
|
||||
|
||||
if options.AutoDetectInterface {
|
||||
monitor, err := iffmonitor.New(router.logger)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "create default interface monitor")
|
||||
}
|
||||
router.interfaceMonitor = monitor
|
||||
}
|
||||
return router, nil
|
||||
}
|
||||
|
||||
@@ -303,6 +316,12 @@ func (r *Router) Start() error {
|
||||
r.geositeCache = nil
|
||||
r.geositeReader = nil
|
||||
}
|
||||
if r.interfaceMonitor != nil {
|
||||
err := r.interfaceMonitor.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -321,6 +340,7 @@ func (r *Router) Close() error {
|
||||
}
|
||||
return common.Close(
|
||||
common.PtrOrNil(r.geoIPReader),
|
||||
r.interfaceMonitor,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -399,7 +419,7 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
||||
}
|
||||
|
||||
func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
if metadata.SniffEnabled {
|
||||
if metadata.SniffEnabled && metadata.Destination.Port == 443 {
|
||||
_buffer := buf.StackNewPacket()
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
@@ -417,9 +437,9 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
|
||||
metadata.Destination.Fqdn = metadata.Domain
|
||||
}
|
||||
if metadata.Domain != "" {
|
||||
r.logger.WithContext(ctx).Info("sniffed protocol: ", metadata.Protocol, ", domain: ", metadata.Domain)
|
||||
r.logger.WithContext(ctx).Info("sniffed packet protocol: ", metadata.Protocol, ", domain: ", metadata.Domain)
|
||||
} else {
|
||||
r.logger.WithContext(ctx).Info("sniffed protocol: ", metadata.Protocol)
|
||||
r.logger.WithContext(ctx).Info("sniffed packet protocol: ", metadata.Protocol)
|
||||
}
|
||||
}
|
||||
conn = bufio.NewCachedPacketConn(conn, buffer, originDestination)
|
||||
@@ -485,6 +505,24 @@ func (r *Router) matchDNS(ctx context.Context) adapter.DNSTransport {
|
||||
return r.defaultTransport
|
||||
}
|
||||
|
||||
func (r *Router) AutoDetectInterface() bool {
|
||||
return r.autoDetectInterface
|
||||
}
|
||||
|
||||
func (r *Router) DefaultInterfaceName() string {
|
||||
if r.interfaceMonitor == nil {
|
||||
return ""
|
||||
}
|
||||
return r.interfaceMonitor.DefaultInterfaceName()
|
||||
}
|
||||
|
||||
func (r *Router) DefaultInterfaceIndex() int {
|
||||
if r.interfaceMonitor == nil {
|
||||
return 0
|
||||
}
|
||||
return r.interfaceMonitor.DefaultInterfaceIndex()
|
||||
}
|
||||
|
||||
func hasGeoRule(rules []option.Rule, cond func(rule option.DefaultRule) bool) bool {
|
||||
for _, rule := range rules {
|
||||
switch rule.Type {
|
||||
|
||||
Reference in New Issue
Block a user