Retry over a direct connection if we can't get a cert via a relay

This is temporary and only to provide compatibility with servers not
running the latest version of encrypted-dns-server.
This commit is contained in:
Frank Denis 2019-10-20 12:26:12 +02:00
parent f9c244db10
commit 535bce308c
2 changed files with 62 additions and 43 deletions

View File

@ -180,6 +180,15 @@ func packTxtString(s string) ([]byte, error) {
}
func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr) (*dns.Msg, time.Duration, error) {
response, ttl, err := _dnsExchange(proxy, proto, query, serverAddress, relayUDPAddr, relayTCPAddr)
if err != nil && relayUDPAddr != nil {
dlog.Warnf("Unable to get a certificate via relay [%v], retrying over a direct connection", relayUDPAddr.IP)
response, ttl, err = _dnsExchange(proxy, proto, query, serverAddress, nil, nil)
}
return response, ttl, err
}
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" {

View File

@ -225,6 +225,55 @@ func fetchServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew
return ServerInfo{}, errors.New("Unsupported protocol")
}
func route(proxy *Proxy, name string) (*net.UDPAddr, *net.TCPAddr, error) {
routes := proxy.routes
if routes == nil {
return nil, nil, nil
}
relayNames, ok := (*routes)[name]
if !ok {
return nil, nil, nil
}
var relayName string
if len(relayNames) > 0 {
candidate := rand.Intn(len(relayNames))
relayName = relayNames[candidate]
}
var relayCandidateStamp *stamps.ServerStamp
if len(relayName) == 0 {
return nil, nil, fmt.Errorf("Route declared for [%v] but an empty relay list", name)
} 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,
Proto: stamps.StampProtoTypeDNSCryptRelay,
}
} else {
for _, registeredServer := range proxy.registeredServers {
if registeredServer.name == relayName {
relayCandidateStamp = &registeredServer.stamp
}
}
}
if relayCandidateStamp == nil {
return nil, nil, fmt.Errorf("Undefined relay [%v] for server [%v]", relayName, name)
}
if relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCrypt ||
relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCryptRelay {
relayUDPAddr, err := net.ResolveUDPAddr("udp", relayCandidateStamp.ServerAddrStr)
if err != nil {
return nil, nil, err
}
relayTCPAddr, err := net.ResolveTCPAddr("tcp", relayCandidateStamp.ServerAddrStr)
if err != nil {
return nil, nil, err
}
return relayUDPAddr, relayTCPAddr, nil
}
return nil, nil, fmt.Errorf("Invalid relay [%v] for server [%v]", relayName, name)
}
func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew bool) (ServerInfo, error) {
if len(stamp.ServerPk) != ed25519.PublicKeySize {
serverPk, err := hex.DecodeString(strings.Replace(string(stamp.ServerPk), ":", "", -1))
@ -234,49 +283,10 @@ 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
}
var relayUDPAddr *net.UDPAddr
var relayTCPAddr *net.TCPAddr
var err error
routes := proxy.routes
if routes != nil {
if relayNames, ok := (*routes)[name]; ok {
var relayName string
if len(relayNames) > 0 {
candidate := rand.Intn(len(relayNames))
relayName = relayNames[candidate]
}
var relayCandidateStamp *stamps.ServerStamp
if len(relayName) == 0 {
dlog.Errorf("Route declared for [%v] but an empty relay list", name)
} 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,
Proto: stamps.StampProtoTypeDNSCryptRelay,
}
} else {
for _, registeredServer := range proxy.registeredServers {
if registeredServer.name == relayName {
relayCandidateStamp = &registeredServer.stamp
}
}
}
if relayCandidateStamp != nil &&
(relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCrypt ||
relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCryptRelay) {
relayUDPAddr, err = net.ResolveUDPAddr("udp", relayCandidateStamp.ServerAddrStr)
if err != nil {
return ServerInfo{}, err
}
relayTCPAddr, err = net.ResolveTCPAddr("tcp", relayCandidateStamp.ServerAddrStr)
if err != nil {
return ServerInfo{}, err
}
} else {
dlog.Errorf("Invalid relay [%v] for server [%v]", relayName, name)
}
}
relayUDPAddr, relayTCPAddr, err := route(proxy, name)
if err != nil {
dlog.Error(err)
return ServerInfo{}, err
}
certInfo, rtt, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew, relayUDPAddr, relayTCPAddr)
if err != nil {