diff --git a/dnscrypt-proxy/dnscrypt_certs.go b/dnscrypt-proxy/dnscrypt_certs.go index 67c42da9..89eec722 100644 --- a/dnscrypt-proxy/dnscrypt_certs.go +++ b/dnscrypt-proxy/dnscrypt_certs.go @@ -21,7 +21,7 @@ type CertInfo struct { ForwardSecurity bool } -func FetchCurrentDNSCryptCert(proxy *Proxy, serverName *string, proto string, pk ed25519.PublicKey, serverAddress string, providerName string, isNew bool) (CertInfo, int, error) { +func FetchCurrentDNSCryptCert(proxy *Proxy, serverName *string, proto string, pk ed25519.PublicKey, serverAddress string, providerName string, isNew bool, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr) (CertInfo, int, error) { if len(pk) != ed25519.PublicKeySize { return CertInfo{}, 0, errors.New("Invalid public key length") } @@ -33,7 +33,7 @@ func FetchCurrentDNSCryptCert(proxy *Proxy, serverName *string, proto string, pk } query := new(dns.Msg) query.SetQuestion(providerName, dns.TypeTXT) - in, rtt, err := dnsExchange(proxy, proto, query, serverAddress) + in, rtt, err := dnsExchange(proxy, proto, query, serverAddress, relayUDPAddr, relayTCPAddr) if err != nil { dlog.Noticef("[%s] TIMEOUT", *serverName) return CertInfo{}, 0, err @@ -179,7 +179,7 @@ func packTxtString(s string) ([]byte, error) { return msg, nil } -func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string) (*dns.Msg, time.Duration, error) { +func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr) (*dns.Msg, time.Duration, error) { var packet []byte var rtt time.Duration if proto == "udp" { @@ -203,8 +203,13 @@ func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress strin if err != nil { return nil, 0, err } + upstreamAddr := udpAddr + if relayUDPAddr != nil { + proxy.prepareForRelay(udpAddr.IP, udpAddr.Port, &binQuery) + upstreamAddr = relayUDPAddr + } now := time.Now() - pc, err := net.DialUDP("udp", nil, udpAddr) + pc, err := net.DialUDP("udp", nil, upstreamAddr) if err != nil { return nil, 0, err } diff --git a/dnscrypt-proxy/serversInfo.go b/dnscrypt-proxy/serversInfo.go index d984471a..cd4c8b17 100644 --- a/dnscrypt-proxy/serversInfo.go +++ b/dnscrypt-proxy/serversInfo.go @@ -234,20 +234,9 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp dlog.Warnf("Public key [%s] shouldn't be hex-encoded any more", string(stamp.ServerPk)) stamp.ServerPk = serverPk } - certInfo, rtt, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew) - if err != nil { - return ServerInfo{}, err - } - remoteUDPAddr, err := net.ResolveUDPAddr("udp", stamp.ServerAddrStr) - if err != nil { - return ServerInfo{}, err - } - remoteTCPAddr, err := net.ResolveTCPAddr("tcp", stamp.ServerAddrStr) - if err != nil { - return ServerInfo{}, err - } var relayUDPAddr *net.UDPAddr var relayTCPAddr *net.TCPAddr + var err error routes := proxy.routes if routes != nil { if relayNames, ok := (*routes)[name]; ok { @@ -259,8 +248,8 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp var relayCandidateStamp *stamps.ServerStamp if len(relayName) == 0 { dlog.Errorf("Route declared for [%v] but an empty relay list", name) - } else if stamp, err = stamps.NewServerStampFromString(relayName); err == nil { - relayCandidateStamp = &stamp + } else if relayStamp, err := stamps.NewServerStampFromString(relayName); err == nil { + relayCandidateStamp = &relayStamp } else if _, err := net.ResolveUDPAddr("udp", relayName); err == nil { relayCandidateStamp = &stamps.ServerStamp{ ServerAddrStr: relayName, @@ -289,6 +278,18 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp } } } + certInfo, rtt, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew, relayUDPAddr, relayTCPAddr) + if err != nil { + return ServerInfo{}, err + } + remoteUDPAddr, err := net.ResolveUDPAddr("udp", stamp.ServerAddrStr) + if err != nil { + return ServerInfo{}, err + } + remoteTCPAddr, err := net.ResolveTCPAddr("tcp", stamp.ServerAddrStr) + if err != nil { + return ServerInfo{}, err + } return ServerInfo{ Proto: stamps.StampProtoTypeDNSCrypt, MagicQuery: certInfo.MagicQuery,