Support relaying for certificates retrieval

This commit is contained in:
Frank Denis 2019-10-19 23:50:05 +02:00
parent d6b63aaf15
commit ff13c813e4
2 changed files with 24 additions and 18 deletions

View File

@ -21,7 +21,7 @@ type CertInfo struct {
ForwardSecurity bool 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 { if len(pk) != ed25519.PublicKeySize {
return CertInfo{}, 0, errors.New("Invalid public key length") 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 := new(dns.Msg)
query.SetQuestion(providerName, dns.TypeTXT) 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 { if err != nil {
dlog.Noticef("[%s] TIMEOUT", *serverName) dlog.Noticef("[%s] TIMEOUT", *serverName)
return CertInfo{}, 0, err return CertInfo{}, 0, err
@ -179,7 +179,7 @@ func packTxtString(s string) ([]byte, error) {
return msg, nil 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 packet []byte
var rtt time.Duration var rtt time.Duration
if proto == "udp" { if proto == "udp" {
@ -203,8 +203,13 @@ func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress strin
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
upstreamAddr := udpAddr
if relayUDPAddr != nil {
proxy.prepareForRelay(udpAddr.IP, udpAddr.Port, &binQuery)
upstreamAddr = relayUDPAddr
}
now := time.Now() now := time.Now()
pc, err := net.DialUDP("udp", nil, udpAddr) pc, err := net.DialUDP("udp", nil, upstreamAddr)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }

View File

@ -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)) dlog.Warnf("Public key [%s] shouldn't be hex-encoded any more", string(stamp.ServerPk))
stamp.ServerPk = 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 relayUDPAddr *net.UDPAddr
var relayTCPAddr *net.TCPAddr var relayTCPAddr *net.TCPAddr
var err error
routes := proxy.routes routes := proxy.routes
if routes != nil { if routes != nil {
if relayNames, ok := (*routes)[name]; ok { if relayNames, ok := (*routes)[name]; ok {
@ -259,8 +248,8 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp
var relayCandidateStamp *stamps.ServerStamp var relayCandidateStamp *stamps.ServerStamp
if len(relayName) == 0 { if len(relayName) == 0 {
dlog.Errorf("Route declared for [%v] but an empty relay list", name) dlog.Errorf("Route declared for [%v] but an empty relay list", name)
} else if stamp, err = stamps.NewServerStampFromString(relayName); err == nil { } else if relayStamp, err := stamps.NewServerStampFromString(relayName); err == nil {
relayCandidateStamp = &stamp relayCandidateStamp = &relayStamp
} else if _, err := net.ResolveUDPAddr("udp", relayName); err == nil { } else if _, err := net.ResolveUDPAddr("udp", relayName); err == nil {
relayCandidateStamp = &stamps.ServerStamp{ relayCandidateStamp = &stamps.ServerStamp{
ServerAddrStr: relayName, 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{ return ServerInfo{
Proto: stamps.StampProtoTypeDNSCrypt, Proto: stamps.StampProtoTypeDNSCrypt,
MagicQuery: certInfo.MagicQuery, MagicQuery: certInfo.MagicQuery,