[client] Implement dns routes for Android (#3989)

This commit is contained in:
Viktor Liu
2025-07-04 16:43:11 +02:00
committed by GitHub
parent 8c09a55057
commit 77ec32dd6f
29 changed files with 2036 additions and 397 deletions

View File

@ -8,9 +8,11 @@ import (
"net/netip"
"net/url"
"runtime"
"slices"
"sync"
"time"
"github.com/google/uuid"
"github.com/hashicorp/go-multierror"
log "github.com/sirupsen/logrus"
"golang.org/x/exp/maps"
@ -24,6 +26,8 @@ import (
"github.com/netbirdio/netbird/client/internal/peer"
"github.com/netbirdio/netbird/client/internal/peerstore"
"github.com/netbirdio/netbird/client/internal/routemanager/client"
"github.com/netbirdio/netbird/client/internal/routemanager/common"
"github.com/netbirdio/netbird/client/internal/routemanager/fakeip"
"github.com/netbirdio/netbird/client/internal/routemanager/iface"
"github.com/netbirdio/netbird/client/internal/routemanager/notifier"
"github.com/netbirdio/netbird/client/internal/routemanager/refcounter"
@ -49,7 +53,7 @@ type Manager interface {
GetClientRoutesWithNetID() map[route.NetID][]*route.Route
SetRouteChangeListener(listener listener.NetworkChangeListener)
InitialRouteRange() []string
EnableServerRouter(firewall firewall.Manager) error
SetFirewall(firewall.Manager) error
Stop(stateManager *statemanager.Manager)
}
@ -63,6 +67,7 @@ type ManagerConfig struct {
InitialRoutes []*route.Route
StateManager *statemanager.Manager
DNSServer dns.Server
DNSFeatureFlag bool
PeerStore *peerstore.Store
DisableClientRoutes bool
DisableServerRoutes bool
@ -89,11 +94,13 @@ type DefaultManager struct {
// clientRoutes is the most recent list of clientRoutes received from the Management Service
clientRoutes route.HAMap
dnsServer dns.Server
firewall firewall.Manager
peerStore *peerstore.Store
useNewDNSRoute bool
disableClientRoutes bool
disableServerRoutes bool
activeRoutes map[route.HAUniqueID]client.RouteHandler
fakeIPManager *fakeip.Manager
}
func NewManager(config ManagerConfig) *DefaultManager {
@ -129,11 +136,31 @@ func NewManager(config ManagerConfig) *DefaultManager {
}
if runtime.GOOS == "android" {
cr := dm.initialClientRoutes(config.InitialRoutes)
dm.notifier.SetInitialClientRoutes(cr)
dm.setupAndroidRoutes(config)
}
return dm
}
func (m *DefaultManager) setupAndroidRoutes(config ManagerConfig) {
cr := m.initialClientRoutes(config.InitialRoutes)
routesForComparison := slices.Clone(cr)
if config.DNSFeatureFlag {
m.fakeIPManager = fakeip.NewManager()
id := uuid.NewString()
fakeIPRoute := &route.Route{
ID: route.ID(id),
Network: m.fakeIPManager.GetFakeIPBlock(),
NetID: route.NetID(id),
Peer: m.pubKey,
NetworkType: route.IPv4Network,
}
cr = append(cr, fakeIPRoute)
}
m.notifier.SetInitialClientRoutes(cr, routesForComparison)
}
func (m *DefaultManager) setupRefCounters(useNoop bool) {
m.routeRefCounter = refcounter.New(
@ -222,16 +249,16 @@ func (m *DefaultManager) initSelector() *routeselector.RouteSelector {
return routeselector.NewRouteSelector()
}
func (m *DefaultManager) EnableServerRouter(firewall firewall.Manager) error {
if m.disableServerRoutes {
// SetFirewall sets the firewall manager for the DefaultManager
// Not thread-safe, should be called before starting the manager
func (m *DefaultManager) SetFirewall(firewall firewall.Manager) error {
m.firewall = firewall
if m.disableServerRoutes || firewall == nil {
log.Info("server routes are disabled")
return nil
}
if firewall == nil {
return errors.New("firewall manager is not set")
}
var err error
m.serverRouter, err = server.NewRouter(m.ctx, m.wgInterface, firewall, m.statusRecorder)
if err != nil {
@ -299,17 +326,20 @@ func (m *DefaultManager) updateSystemRoutes(newRoutes route.HAMap) error {
}
for id, route := range toAdd {
handler := client.HandlerFromRoute(
route,
m.routeRefCounter,
m.allowedIPsRefCounter,
m.dnsRouteInterval,
m.statusRecorder,
m.wgInterface,
m.dnsServer,
m.peerStore,
m.useNewDNSRoute,
)
params := common.HandlerParams{
Route: route,
RouteRefCounter: m.routeRefCounter,
AllowedIPsRefCounter: m.allowedIPsRefCounter,
DnsRouterInterval: m.dnsRouteInterval,
StatusRecorder: m.statusRecorder,
WgInterface: m.wgInterface,
DnsServer: m.dnsServer,
PeerStore: m.peerStore,
UseNewDNSRoute: m.useNewDNSRoute,
Firewall: m.firewall,
FakeIPManager: m.fakeIPManager,
}
handler := client.HandlerFromRoute(params)
if err := handler.AddRoute(m.ctx); err != nil {
merr = multierror.Append(merr, fmt.Errorf("add route %s: %w", handler.String(), err))
continue
@ -517,6 +547,7 @@ func (m *DefaultManager) initialClientRoutes(initialRoutes []*route.Route) []*ro
for _, routes := range crMap {
rs = append(rs, routes...)
}
return rs
}