mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 00:21:30 +00:00
Add wifi_ssid
and wifi_bssid
route and DNS rules
This commit is contained in:
parent
f0571b4122
commit
253976d6c0
|
@ -41,6 +41,7 @@ type Router interface {
|
||||||
NetworkMonitor() tun.NetworkUpdateMonitor
|
NetworkMonitor() tun.NetworkUpdateMonitor
|
||||||
InterfaceMonitor() tun.DefaultInterfaceMonitor
|
InterfaceMonitor() tun.DefaultInterfaceMonitor
|
||||||
PackageManager() tun.PackageManager
|
PackageManager() tun.PackageManager
|
||||||
|
WIFIState() WIFIState
|
||||||
Rules() []Rule
|
Rules() []Rule
|
||||||
|
|
||||||
ClashServer() ClashServer
|
ClashServer() ClashServer
|
||||||
|
@ -78,3 +79,8 @@ type DNSRule interface {
|
||||||
type InterfaceUpdateListener interface {
|
type InterfaceUpdateListener interface {
|
||||||
InterfaceUpdated()
|
InterfaceUpdated()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WIFIState struct {
|
||||||
|
SSID string
|
||||||
|
BSSID string
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ type PlatformInterface interface {
|
||||||
UsePlatformInterfaceGetter() bool
|
UsePlatformInterfaceGetter() bool
|
||||||
GetInterfaces() (NetworkInterfaceIterator, error)
|
GetInterfaces() (NetworkInterfaceIterator, error)
|
||||||
UnderNetworkExtension() bool
|
UnderNetworkExtension() bool
|
||||||
|
ReadWIFIState() *WIFIState
|
||||||
ClearDNSCache()
|
ClearDNSCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +39,15 @@ type NetworkInterface struct {
|
||||||
Addresses StringIterator
|
Addresses StringIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WIFIState struct {
|
||||||
|
SSID string
|
||||||
|
BSSID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWIFIState(wifiSSID string, wifiBSSID string) *WIFIState {
|
||||||
|
return &WIFIState{wifiSSID, wifiBSSID}
|
||||||
|
}
|
||||||
|
|
||||||
type NetworkInterfaceIterator interface {
|
type NetworkInterfaceIterator interface {
|
||||||
Next() *NetworkInterface
|
Next() *NetworkInterface
|
||||||
HasNext() bool
|
HasNext() bool
|
||||||
|
|
|
@ -23,6 +23,7 @@ type Interface interface {
|
||||||
Interfaces() ([]NetworkInterface, error)
|
Interfaces() ([]NetworkInterface, error)
|
||||||
UnderNetworkExtension() bool
|
UnderNetworkExtension() bool
|
||||||
ClearDNSCache()
|
ClearDNSCache()
|
||||||
|
ReadWIFIState() adapter.WIFIState
|
||||||
process.Searcher
|
process.Searcher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,14 @@ func (w *platformInterfaceWrapper) ClearDNSCache() {
|
||||||
w.iif.ClearDNSCache()
|
w.iif.ClearDNSCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *platformInterfaceWrapper) ReadWIFIState() adapter.WIFIState {
|
||||||
|
wifiState := w.iif.ReadWIFIState()
|
||||||
|
if wifiState == nil {
|
||||||
|
return adapter.WIFIState{}
|
||||||
|
}
|
||||||
|
return (adapter.WIFIState)(*wifiState)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *platformInterfaceWrapper) DisableColors() bool {
|
func (w *platformInterfaceWrapper) DisableColors() bool {
|
||||||
return runtime.GOOS != "android"
|
return runtime.GOOS != "android"
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,8 @@ type DefaultRule struct {
|
||||||
User Listable[string] `json:"user,omitempty"`
|
User Listable[string] `json:"user,omitempty"`
|
||||||
UserID Listable[int32] `json:"user_id,omitempty"`
|
UserID Listable[int32] `json:"user_id,omitempty"`
|
||||||
ClashMode string `json:"clash_mode,omitempty"`
|
ClashMode string `json:"clash_mode,omitempty"`
|
||||||
|
WIFISSID Listable[string] `json:"wifi_ssid,omitempty"`
|
||||||
|
WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"`
|
||||||
Invert bool `json:"invert,omitempty"`
|
Invert bool `json:"invert,omitempty"`
|
||||||
Outbound string `json:"outbound,omitempty"`
|
Outbound string `json:"outbound,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,8 @@ type DefaultDNSRule struct {
|
||||||
UserID Listable[int32] `json:"user_id,omitempty"`
|
UserID Listable[int32] `json:"user_id,omitempty"`
|
||||||
Outbound Listable[string] `json:"outbound,omitempty"`
|
Outbound Listable[string] `json:"outbound,omitempty"`
|
||||||
ClashMode string `json:"clash_mode,omitempty"`
|
ClashMode string `json:"clash_mode,omitempty"`
|
||||||
|
WIFISSID Listable[string] `json:"wifi_ssid,omitempty"`
|
||||||
|
WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"`
|
||||||
Invert bool `json:"invert,omitempty"`
|
Invert bool `json:"invert,omitempty"`
|
||||||
Server string `json:"server,omitempty"`
|
Server string `json:"server,omitempty"`
|
||||||
DisableCache bool `json:"disable_cache,omitempty"`
|
DisableCache bool `json:"disable_cache,omitempty"`
|
||||||
|
|
|
@ -86,6 +86,8 @@ type Router struct {
|
||||||
clashServer adapter.ClashServer
|
clashServer adapter.ClashServer
|
||||||
v2rayServer adapter.V2RayServer
|
v2rayServer adapter.V2RayServer
|
||||||
platformInterface platform.Interface
|
platformInterface platform.Interface
|
||||||
|
needWIFIState bool
|
||||||
|
wifiState adapter.WIFIState
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRouter(
|
func NewRouter(
|
||||||
|
@ -116,6 +118,7 @@ func NewRouter(
|
||||||
defaultMark: options.DefaultMark,
|
defaultMark: options.DefaultMark,
|
||||||
pauseManager: pause.ManagerFromContext(ctx),
|
pauseManager: pause.ManagerFromContext(ctx),
|
||||||
platformInterface: platformInterface,
|
platformInterface: platformInterface,
|
||||||
|
needWIFIState: hasRule(options.Rules, isWIFIRule) || hasDNSRule(dnsOptions.Rules, isWIFIDNSRule),
|
||||||
}
|
}
|
||||||
router.dnsClient = dns.NewClient(dns.ClientOptions{
|
router.dnsClient = dns.NewClient(dns.ClientOptions{
|
||||||
DisableCache: dnsOptions.DNSClientOptions.DisableCache,
|
DisableCache: dnsOptions.DNSClientOptions.DisableCache,
|
||||||
|
@ -328,6 +331,11 @@ func NewRouter(
|
||||||
service.ContextWith[serviceNTP.TimeService](ctx, timeService)
|
service.ContextWith[serviceNTP.TimeService](ctx, timeService)
|
||||||
router.timeService = timeService
|
router.timeService = timeService
|
||||||
}
|
}
|
||||||
|
if platformInterface != nil && router.interfaceMonitor != nil && router.needWIFIState {
|
||||||
|
router.interfaceMonitor.RegisterCallback(func(_ int) {
|
||||||
|
router.updateWIFIState()
|
||||||
|
})
|
||||||
|
}
|
||||||
return router, nil
|
return router, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,6 +476,9 @@ func (r *Router) Start() error {
|
||||||
r.geositeCache = nil
|
r.geositeCache = nil
|
||||||
r.geositeReader = nil
|
r.geositeReader = nil
|
||||||
}
|
}
|
||||||
|
if r.needWIFIState {
|
||||||
|
r.updateWIFIState()
|
||||||
|
}
|
||||||
for i, rule := range r.rules {
|
for i, rule := range r.rules {
|
||||||
err := rule.Start()
|
err := rule.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -940,6 +951,10 @@ func (r *Router) Rules() []adapter.Rule {
|
||||||
return r.rules
|
return r.rules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Router) WIFIState() adapter.WIFIState {
|
||||||
|
return r.wifiState
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor {
|
func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor {
|
||||||
return r.networkMonitor
|
return r.networkMonitor
|
||||||
}
|
}
|
||||||
|
@ -1019,3 +1034,14 @@ func (r *Router) ResetNetwork() error {
|
||||||
}
|
}
|
||||||
return nil
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -307,3 +307,11 @@ func isProcessDNSRule(rule option.DefaultDNSRule) bool {
|
||||||
func notPrivateNode(code string) bool {
|
func notPrivateNode(code string) bool {
|
||||||
return code != "private"
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -184,6 +184,16 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt
|
||||||
rule.items = append(rule.items, item)
|
rule.items = append(rule.items, item)
|
||||||
rule.allItems = append(rule.allItems, 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
|
return rule, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,16 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
|
||||||
rule.items = append(rule.items, item)
|
rule.items = append(rule.items, item)
|
||||||
rule.allItems = append(rule.allItems, 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
|
return rule, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
39
route/rule_item_wifi_bssid.go
Normal file
39
route/rule_item_wifi_bssid.go
Normal 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, " "), "]")
|
||||||
|
}
|
39
route/rule_item_wifi_ssid.go
Normal file
39
route/rule_item_wifi_ssid.go
Normal 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, " "), "]")
|
||||||
|
}
|
Loading…
Reference in a new issue