github.com/go-graphite/carbonapi@v0.17.0/internal/dns/dns.go (about) 1 package dns 2 3 import ( 4 "context" 5 "net" 6 "time" 7 8 "github.com/lomik/zapwriter" 9 "github.com/rs/dnscache" 10 "go.uber.org/zap" 11 ) 12 13 var ( 14 resolver *dnscache.Resolver 15 ) 16 17 func GetDialContextWithTimeout(dialTimeout, keepaliveTimeout time.Duration) func(ctx context.Context, network string, addr string) (conn net.Conn, err error) { 18 logger := zapwriter.Logger("dns") 19 dialer := net.Dialer{ 20 Timeout: dialTimeout, 21 KeepAlive: keepaliveTimeout, 22 } 23 if resolver == nil { 24 logger.Debug("no caching dns initialized, will return typical DialContext") 25 return (&dialer).DialContext 26 } 27 28 logger.Debug("returning caching DialContext") 29 return func(ctx context.Context, network string, addr string) (conn net.Conn, err error) { 30 host, port, err := net.SplitHostPort(addr) 31 if err != nil { 32 return nil, err 33 } 34 ips, err := resolver.LookupHost(ctx, host) 35 if err != nil { 36 return nil, err 37 } 38 for _, ip := range ips { 39 conn, err = dialer.DialContext(ctx, network, net.JoinHostPort(ip, port)) 40 if err == nil { 41 break 42 } 43 } 44 return 45 } 46 } 47 48 func UseDNSCache(dnsRefreshTime time.Duration) { 49 logger := zapwriter.Logger("dns") 50 resolver = &dnscache.Resolver{} 51 52 // Periodically refresh cache 53 go func() { 54 ticker := time.NewTicker(dnsRefreshTime) 55 defer ticker.Stop() 56 for range ticker.C { 57 logger.Debug("cache refreshed") 58 resolver.Refresh(true) 59 } 60 }() 61 62 logger.Debug("caching dns resolver initialized", 63 zap.Duration("refreshTime", dnsRefreshTime), 64 ) 65 }