package app import ( "context" "fmt" "net" "time" dnsservice "dnsupdater/dns/service" "dnsupdater/ip" "dnsupdater/ip/resolver" ) // WAN_IFACE Name for the virtual WAN interface const WAN_IFACE = "wan" type App struct { cache *ip.Cache cacheDefaultCallback ip.CacheDefaultCallback // DNS service manager DnsServiceMgr *dnsservice.Manager } func makeCacheCallback(service resolver.Service) ip.CacheDefaultCallback { return func(name string) (net.IP, error) { if name == WAN_IFACE { ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() return service.Lookup(ctx) } return ip.GetInterfaceIP(name) } } func NewApp(config *Config) (*App, error) { dnsServiceMgr := dnsservice.NewManager() err := dnsServiceMgr.RegisterFromConfig(config.Providers) if err != nil { return nil, err } ipService := resolver.Get(config.Services.IPLookup) if ipService == nil { return nil, fmt.Errorf("failed to load lookup service: %s", config.Services.IPLookup) } return &App{ DnsServiceMgr: dnsServiceMgr, cache: ip.NewCache(), cacheDefaultCallback: makeCacheCallback(ipService), }, nil } func (a App) GetIP(iface_name string) (net.IP, error) { return a.cache.GetWithDefault(iface_name, a.cacheDefaultCallback) }