github.com/MetalBlockchain/metalgo@v1.11.9/utils/dynamicip/opendns_resolver.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package dynamicip 5 6 import ( 7 "context" 8 "errors" 9 "net" 10 "net/netip" 11 12 "github.com/MetalBlockchain/metalgo/utils/ips" 13 ) 14 15 const openDNSUrl = "resolver1.opendns.com:53" 16 17 var ( 18 errOpenDNSNoIP = errors.New("openDNS returned no ip") 19 20 _ Resolver = (*openDNSResolver)(nil) 21 ) 22 23 // openDNSResolver resolves our public IP using openDNS 24 type openDNSResolver struct { 25 resolver *net.Resolver 26 } 27 28 func newOpenDNSResolver() Resolver { 29 return &openDNSResolver{ 30 resolver: &net.Resolver{ 31 PreferGo: true, 32 Dial: func(ctx context.Context, _, _ string) (net.Conn, error) { 33 d := net.Dialer{} 34 return d.DialContext(ctx, "udp", openDNSUrl) 35 }, 36 }, 37 } 38 } 39 40 func (r *openDNSResolver) Resolve(ctx context.Context) (netip.Addr, error) { 41 resolvedIPs, err := r.resolver.LookupIP(ctx, "ip", "myip.opendns.com") 42 if err != nil { 43 return netip.Addr{}, err 44 } 45 for _, ip := range resolvedIPs { 46 if addr, ok := ips.AddrFromSlice(ip); ok { 47 return addr, nil 48 } 49 } 50 return netip.Addr{}, errOpenDNSNoIP 51 }