Files
sing-box-extended-mirror/route/network_environment.go
T

85 lines
2.3 KiB
Go

package route
import (
"hash/fnv"
"net/netip"
"slices"
"strings"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common"
)
func (r *NetworkManager) NetworkEnvironment() uint64 {
r.stateAccess.RLock()
defer r.stateAccess.RUnlock()
return r.networkEnvironment
}
func (r *NetworkManager) postUpdateNetworkEnvironment() {
r.environmentUpdateAccess.Lock()
defer r.environmentUpdateAccess.Unlock()
if r.environmentUpdateTimer == nil {
r.environmentUpdateTimer = time.AfterFunc(time.Second, r.updateNetworkEnvironment)
} else {
r.environmentUpdateTimer.Reset(time.Second)
}
}
func (r *NetworkManager) updateNetworkEnvironment() {
r.environmentUpdateAccess.Lock()
defer r.environmentUpdateAccess.Unlock()
if r.environmentUpdateTimer != nil {
r.environmentUpdateTimer.Stop()
}
var defaultInterface *adapter.NetworkInterface
if r.interfaceMonitor != nil {
defaultInterface = r.DefaultNetworkInterface()
}
var environment []string
if defaultInterface != nil {
gateways := defaultInterface.Gateways
if len(gateways) == 0 {
gateways = systemGateways(defaultInterface.Interface.Index)
}
gateways = common.Uniq(gateways)
slices.SortFunc(gateways, netip.Addr.Compare)
for _, gateway := range gateways {
environment = append(environment, "gateway:"+gateway.String())
}
wifiState := r.WIFIState()
if wifiState.SSID != "" {
environment = append(environment, "ssid:"+wifiState.SSID)
} else if len(gateways) > 0 {
hardwareAddresses := systemNeighborHardwareAddresses(defaultInterface.Interface.Index, gateways)
for _, gateway := range gateways {
hardwareAddress := hardwareAddresses[gateway]
if len(hardwareAddress) > 0 {
environment = append(environment, "gateway_mac:"+hardwareAddress.String())
}
}
}
}
var environmentHash uint64
if len(environment) > 0 {
digest := fnv.New64a()
for _, entry := range environment {
digest.Write([]byte(entry))
digest.Write([]byte{0})
}
environmentHash = digest.Sum64()
}
r.stateAccess.Lock()
changed := environmentHash != r.networkEnvironment
r.networkEnvironment = environmentHash
r.stateAccess.Unlock()
if changed {
if len(environment) > 0 {
r.logger.Info("updated network environment: ", strings.Join(environment, ", "))
} else {
r.logger.Info("updated network environment: empty")
}
}
}