Add wifi_ssid and wifi_bssid route and DNS rules

This commit is contained in:
世界
2023-11-24 20:58:07 +08:00
parent f0571b4122
commit 253976d6c0
12 changed files with 161 additions and 0 deletions

View File

@@ -86,6 +86,8 @@ type Router struct {
clashServer adapter.ClashServer
v2rayServer adapter.V2RayServer
platformInterface platform.Interface
needWIFIState bool
wifiState adapter.WIFIState
}
func NewRouter(
@@ -116,6 +118,7 @@ func NewRouter(
defaultMark: options.DefaultMark,
pauseManager: pause.ManagerFromContext(ctx),
platformInterface: platformInterface,
needWIFIState: hasRule(options.Rules, isWIFIRule) || hasDNSRule(dnsOptions.Rules, isWIFIDNSRule),
}
router.dnsClient = dns.NewClient(dns.ClientOptions{
DisableCache: dnsOptions.DNSClientOptions.DisableCache,
@@ -328,6 +331,11 @@ func NewRouter(
service.ContextWith[serviceNTP.TimeService](ctx, timeService)
router.timeService = timeService
}
if platformInterface != nil && router.interfaceMonitor != nil && router.needWIFIState {
router.interfaceMonitor.RegisterCallback(func(_ int) {
router.updateWIFIState()
})
}
return router, nil
}
@@ -468,6 +476,9 @@ func (r *Router) Start() error {
r.geositeCache = nil
r.geositeReader = nil
}
if r.needWIFIState {
r.updateWIFIState()
}
for i, rule := range r.rules {
err := rule.Start()
if err != nil {
@@ -940,6 +951,10 @@ func (r *Router) Rules() []adapter.Rule {
return r.rules
}
func (r *Router) WIFIState() adapter.WIFIState {
return r.wifiState
}
func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor {
return r.networkMonitor
}
@@ -1019,3 +1034,14 @@ func (r *Router) ResetNetwork() error {
}
return nil
}
func (r *Router) updateWIFIState() {
if r.platformInterface == nil {
return
}
state := r.platformInterface.ReadWIFIState()
if state != r.wifiState {
r.wifiState = state
r.logger.Info("updated WIFI state: SSID=", state.SSID, ", BSSID=", state.BSSID)
}
}

View File

@@ -307,3 +307,11 @@ func isProcessDNSRule(rule option.DefaultDNSRule) bool {
func notPrivateNode(code string) bool {
return code != "private"
}
func isWIFIRule(rule option.DefaultRule) bool {
return len(rule.WIFISSID) > 0 || len(rule.WIFIBSSID) > 0
}
func isWIFIDNSRule(rule option.DefaultDNSRule) bool {
return len(rule.WIFISSID) > 0 || len(rule.WIFIBSSID) > 0
}

View File

@@ -184,6 +184,16 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.WIFISSID) > 0 {
item := NewWIFISSIDItem(router, options.WIFISSID)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.WIFIBSSID) > 0 {
item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
return rule, nil
}

View File

@@ -180,6 +180,16 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.WIFISSID) > 0 {
item := NewWIFISSIDItem(router, options.WIFISSID)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.WIFIBSSID) > 0 {
item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
return rule, nil
}

View File

@@ -0,0 +1,39 @@
package route
import (
"strings"
"github.com/sagernet/sing-box/adapter"
F "github.com/sagernet/sing/common/format"
)
var _ RuleItem = (*WIFIBSSIDItem)(nil)
type WIFIBSSIDItem struct {
bssidList []string
bssidMap map[string]bool
router adapter.Router
}
func NewWIFIBSSIDItem(router adapter.Router, bssidList []string) *WIFIBSSIDItem {
bssidMap := make(map[string]bool)
for _, bssid := range bssidList {
bssidMap[bssid] = true
}
return &WIFIBSSIDItem{
bssidList,
bssidMap,
router,
}
}
func (r *WIFIBSSIDItem) Match(metadata *adapter.InboundContext) bool {
return r.bssidMap[r.router.WIFIState().BSSID]
}
func (r *WIFIBSSIDItem) String() string {
if len(r.bssidList) == 1 {
return F.ToString("wifi_bssid=", r.bssidList[0])
}
return F.ToString("wifi_bssid=[", strings.Join(r.bssidList, " "), "]")
}

View File

@@ -0,0 +1,39 @@
package route
import (
"strings"
"github.com/sagernet/sing-box/adapter"
F "github.com/sagernet/sing/common/format"
)
var _ RuleItem = (*WIFISSIDItem)(nil)
type WIFISSIDItem struct {
ssidList []string
ssidMap map[string]bool
router adapter.Router
}
func NewWIFISSIDItem(router adapter.Router, ssidList []string) *WIFISSIDItem {
ssidMap := make(map[string]bool)
for _, ssid := range ssidList {
ssidMap[ssid] = true
}
return &WIFISSIDItem{
ssidList,
ssidMap,
router,
}
}
func (r *WIFISSIDItem) Match(metadata *adapter.InboundContext) bool {
return r.ssidMap[r.router.WIFIState().SSID]
}
func (r *WIFISSIDItem) String() string {
if len(r.ssidList) == 1 {
return F.ToString("wifi_ssid=", r.ssidList[0])
}
return F.ToString("wifi_ssid=[", strings.Join(r.ssidList, " "), "]")
}