mirror of
https://github.com/DNSCrypt/dnscrypt-proxy.git
synced 2025-04-04 13:47:39 +03:00
Don't use distinct pointers for UDP and TCP relay addresses
This commit is contained in:
parent
ab8ebead34
commit
7f46f4820c
4 changed files with 53 additions and 41 deletions
|
@ -100,7 +100,7 @@ func (proxy *Proxy) Encrypt(serverInfo *ServerInfo, packet []byte, proto string)
|
|||
if proto == "udp" && serverInfo.knownBugs.fragmentsBlocked {
|
||||
paddedLength = MaxDNSUDPSafePacketSize
|
||||
}
|
||||
if serverInfo.RelayUDPAddr != nil && proto == "tcp" {
|
||||
if serverInfo.Relay != nil && proto == "tcp" {
|
||||
paddedLength = MaxDNSPacketSize
|
||||
}
|
||||
if QueryOverhead+len(packet)+1 > paddedLength {
|
||||
|
|
|
@ -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, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr, knownBugs ServerBugs) (CertInfo, int, bool, error) {
|
||||
func FetchCurrentDNSCryptCert(proxy *Proxy, serverName *string, proto string, pk ed25519.PublicKey, serverAddress string, providerName string, isNew bool, relay *DNSCryptRelay, knownBugs ServerBugs) (CertInfo, int, bool, error) {
|
||||
if len(pk) != ed25519.PublicKeySize {
|
||||
return CertInfo{}, 0, false, errors.New("Invalid public key length")
|
||||
}
|
||||
|
@ -34,18 +34,18 @@ func FetchCurrentDNSCryptCert(proxy *Proxy, serverName *string, proto string, pk
|
|||
query := dns.Msg{}
|
||||
query.SetQuestion(providerName, dns.TypeTXT)
|
||||
if !strings.HasPrefix(providerName, "2.dnscrypt-cert.") {
|
||||
if relayUDPAddr != nil && !proxy.anonDirectCertFallback {
|
||||
if relay != nil && !proxy.anonDirectCertFallback {
|
||||
dlog.Warnf("[%v] uses a non-standard provider name, enable direct cert fallback to use with a relay ('%v' doesn't start with '2.dnscrypt-cert.')", *serverName, providerName)
|
||||
} else {
|
||||
dlog.Warnf("[%v] uses a non-standard provider name ('%v' doesn't start with '2.dnscrypt-cert.')", *serverName, providerName)
|
||||
relayUDPAddr, relayTCPAddr = nil, nil
|
||||
relay = nil
|
||||
}
|
||||
}
|
||||
tryFragmentsSupport := true
|
||||
if knownBugs.fragmentsBlocked {
|
||||
tryFragmentsSupport = false
|
||||
}
|
||||
in, rtt, fragmentsBlocked, err := dnsExchange(proxy, proto, &query, serverAddress, relayUDPAddr, relayTCPAddr, serverName, tryFragmentsSupport)
|
||||
in, rtt, fragmentsBlocked, err := dnsExchange(proxy, proto, &query, serverAddress, relay, serverName, tryFragmentsSupport)
|
||||
if err != nil {
|
||||
dlog.Noticef("[%s] TIMEOUT", *serverName)
|
||||
return CertInfo{}, 0, fragmentsBlocked, err
|
||||
|
@ -197,7 +197,7 @@ type dnsExchangeResponse struct {
|
|||
err error
|
||||
}
|
||||
|
||||
func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr, serverName *string, tryFragmentsSupport bool) (*dns.Msg, time.Duration, bool, error) {
|
||||
func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relay *DNSCryptRelay, serverName *string, tryFragmentsSupport bool) (*dns.Msg, time.Duration, bool, error) {
|
||||
for {
|
||||
cancelChannel := make(chan struct{})
|
||||
channel := make(chan dnsExchangeResponse)
|
||||
|
@ -209,7 +209,7 @@ func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress strin
|
|||
queryCopy := query.Copy()
|
||||
queryCopy.Id += uint16(options)
|
||||
go func(query *dns.Msg, delay time.Duration) {
|
||||
option := _dnsExchange(proxy, proto, query, serverAddress, relayUDPAddr, relayTCPAddr, 1500)
|
||||
option := _dnsExchange(proxy, proto, query, serverAddress, relay, 1500)
|
||||
option.fragmentsBlocked = false
|
||||
option.priority = 0
|
||||
channel <- option
|
||||
|
@ -225,7 +225,7 @@ func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress strin
|
|||
queryCopy := query.Copy()
|
||||
queryCopy.Id += uint16(options)
|
||||
go func(query *dns.Msg, delay time.Duration) {
|
||||
option := _dnsExchange(proxy, proto, query, serverAddress, relayUDPAddr, relayTCPAddr, 480)
|
||||
option := _dnsExchange(proxy, proto, query, serverAddress, relay, 480)
|
||||
option.fragmentsBlocked = true
|
||||
option.priority = 1
|
||||
channel <- option
|
||||
|
@ -262,18 +262,18 @@ func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress strin
|
|||
return bestOption.response, bestOption.rtt, bestOption.fragmentsBlocked, nil
|
||||
}
|
||||
|
||||
if relayUDPAddr == nil || !proxy.anonDirectCertFallback {
|
||||
if relay == nil || !proxy.anonDirectCertFallback {
|
||||
if err == nil {
|
||||
err = errors.New("Unable to reach the server")
|
||||
}
|
||||
return nil, 0, false, err
|
||||
}
|
||||
dlog.Infof("Unable to get a certificate for [%v] via relay [%v], retrying over a direct connection", *serverName, relayUDPAddr.IP)
|
||||
relayUDPAddr, relayTCPAddr = nil, nil
|
||||
dlog.Infof("Unable to get a certificate for [%v] via relay [%v], retrying over a direct connection", *serverName, relay.RelayUDPAddr.IP)
|
||||
relay = nil
|
||||
}
|
||||
}
|
||||
|
||||
func _dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr, paddedLen int) dnsExchangeResponse {
|
||||
func _dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relay *DNSCryptRelay, paddedLen int) dnsExchangeResponse {
|
||||
var packet []byte
|
||||
var rtt time.Duration
|
||||
|
||||
|
@ -299,9 +299,9 @@ func _dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress stri
|
|||
return dnsExchangeResponse{err: err}
|
||||
}
|
||||
upstreamAddr := udpAddr
|
||||
if relayUDPAddr != nil {
|
||||
if relay != nil {
|
||||
proxy.prepareForRelay(udpAddr.IP, udpAddr.Port, &binQuery)
|
||||
upstreamAddr = relayUDPAddr
|
||||
upstreamAddr = relay.RelayUDPAddr
|
||||
}
|
||||
now := time.Now()
|
||||
pc, err := net.DialUDP("udp", nil, upstreamAddr)
|
||||
|
@ -332,9 +332,9 @@ func _dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress stri
|
|||
return dnsExchangeResponse{err: err}
|
||||
}
|
||||
upstreamAddr := tcpAddr
|
||||
if relayTCPAddr != nil {
|
||||
if relay != nil {
|
||||
proxy.prepareForRelay(tcpAddr.IP, tcpAddr.Port, &binQuery)
|
||||
upstreamAddr = relayTCPAddr
|
||||
upstreamAddr = relay.RelayTCPAddr
|
||||
}
|
||||
now := time.Now()
|
||||
var pc net.Conn
|
||||
|
|
|
@ -386,8 +386,8 @@ func (proxy *Proxy) prepareForRelay(ip net.IP, port int, encryptedQuery *[]byte)
|
|||
|
||||
func (proxy *Proxy) exchangeWithUDPServer(serverInfo *ServerInfo, sharedKey *[32]byte, encryptedQuery []byte, clientNonce []byte) ([]byte, error) {
|
||||
upstreamAddr := serverInfo.UDPAddr
|
||||
if serverInfo.RelayUDPAddr != nil {
|
||||
upstreamAddr = serverInfo.RelayUDPAddr
|
||||
if serverInfo.Relay != nil && serverInfo.Relay.Dnscrypt != nil {
|
||||
upstreamAddr = serverInfo.Relay.Dnscrypt.RelayUDPAddr
|
||||
}
|
||||
var err error
|
||||
var pc net.Conn
|
||||
|
@ -404,7 +404,7 @@ func (proxy *Proxy) exchangeWithUDPServer(serverInfo *ServerInfo, sharedKey *[32
|
|||
if err := pc.SetDeadline(time.Now().Add(serverInfo.Timeout)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if serverInfo.RelayUDPAddr != nil {
|
||||
if serverInfo.Relay != nil && serverInfo.Relay.Dnscrypt != nil {
|
||||
proxy.prepareForRelay(serverInfo.UDPAddr.IP, serverInfo.UDPAddr.Port, &encryptedQuery)
|
||||
}
|
||||
encryptedResponse := make([]byte, MaxDNSPacketSize)
|
||||
|
@ -424,8 +424,8 @@ func (proxy *Proxy) exchangeWithUDPServer(serverInfo *ServerInfo, sharedKey *[32
|
|||
|
||||
func (proxy *Proxy) exchangeWithTCPServer(serverInfo *ServerInfo, sharedKey *[32]byte, encryptedQuery []byte, clientNonce []byte) ([]byte, error) {
|
||||
upstreamAddr := serverInfo.TCPAddr
|
||||
if serverInfo.RelayUDPAddr != nil {
|
||||
upstreamAddr = serverInfo.RelayTCPAddr
|
||||
if serverInfo.Relay != nil && serverInfo.Relay.Dnscrypt != nil {
|
||||
upstreamAddr = serverInfo.Relay.Dnscrypt.RelayTCPAddr
|
||||
}
|
||||
var err error
|
||||
var pc net.Conn
|
||||
|
@ -442,7 +442,7 @@ func (proxy *Proxy) exchangeWithTCPServer(serverInfo *ServerInfo, sharedKey *[32
|
|||
if err := pc.SetDeadline(time.Now().Add(serverInfo.Timeout)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if serverInfo.RelayTCPAddr != nil {
|
||||
if serverInfo.Relay != nil && serverInfo.Relay.Dnscrypt != nil {
|
||||
proxy.prepareForRelay(serverInfo.TCPAddr.IP, serverInfo.TCPAddr.Port, &encryptedQuery)
|
||||
}
|
||||
encryptedQuery, err = PrefixWithSize(encryptedQuery)
|
||||
|
|
|
@ -50,9 +50,8 @@ type ServerInfo struct {
|
|||
HostName string
|
||||
UDPAddr *net.UDPAddr
|
||||
TCPAddr *net.TCPAddr
|
||||
RelayUDPAddr *net.UDPAddr
|
||||
Relay *Relay
|
||||
URL *url.URL
|
||||
RelayTCPAddr *net.TCPAddr
|
||||
initialRtt int
|
||||
Timeout time.Duration
|
||||
CryptoConstruction CryptoConstruction
|
||||
|
@ -100,6 +99,16 @@ func (LBStrategyRandom) getCandidate(serversCount int) int {
|
|||
|
||||
var DefaultLBStrategy = LBStrategyP2{}
|
||||
|
||||
type DNSCryptRelay struct {
|
||||
RelayUDPAddr *net.UDPAddr
|
||||
RelayTCPAddr *net.TCPAddr
|
||||
}
|
||||
|
||||
type Relay struct {
|
||||
Proto stamps.StampProtoType
|
||||
Dnscrypt *DNSCryptRelay
|
||||
}
|
||||
|
||||
type ServersInfo struct {
|
||||
sync.RWMutex
|
||||
inner []*ServerInfo
|
||||
|
@ -252,17 +261,17 @@ func fetchServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew
|
|||
return ServerInfo{}, errors.New(fmt.Sprintf("Unsupported protocol for [%s]: [%s]", name, stamp.Proto.String()))
|
||||
}
|
||||
|
||||
func route(proxy *Proxy, name string) (*net.UDPAddr, *net.TCPAddr, error) {
|
||||
func route(proxy *Proxy, name string) (*Relay, error) {
|
||||
routes := proxy.routes
|
||||
if routes == nil {
|
||||
return nil, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
relayNames, ok := (*routes)[name]
|
||||
if !ok {
|
||||
relayNames, ok = (*routes)["*"]
|
||||
}
|
||||
if !ok {
|
||||
return nil, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
var relayName string
|
||||
if len(relayNames) > 0 {
|
||||
|
@ -271,7 +280,7 @@ func route(proxy *Proxy, name string) (*net.UDPAddr, *net.TCPAddr, error) {
|
|||
}
|
||||
var relayCandidateStamp *stamps.ServerStamp
|
||||
if len(relayName) == 0 {
|
||||
return nil, nil, fmt.Errorf("Route declared for [%v] but the relay list is empty", name)
|
||||
return nil, fmt.Errorf("Route declared for [%v] but the relay list is empty", name)
|
||||
} else if relayStamp, err := stamps.NewServerStampFromString(relayName); err == nil {
|
||||
relayCandidateStamp = &relayStamp
|
||||
} else {
|
||||
|
@ -289,21 +298,21 @@ func route(proxy *Proxy, name string) (*net.UDPAddr, *net.TCPAddr, error) {
|
|||
}
|
||||
}
|
||||
if relayCandidateStamp == nil {
|
||||
return nil, nil, fmt.Errorf("Undefined relay [%v] for server [%v]", relayName, name)
|
||||
return nil, fmt.Errorf("Undefined relay [%v] for server [%v]", relayName, name)
|
||||
}
|
||||
if relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCrypt ||
|
||||
relayCandidateStamp.Proto == stamps.StampProtoTypeDNSCryptRelay {
|
||||
switch relayCandidateStamp.Proto {
|
||||
case stamps.StampProtoTypeDNSCrypt | stamps.StampProtoTypeDNSCryptRelay:
|
||||
relayUDPAddr, err := net.ResolveUDPAddr("udp", relayCandidateStamp.ServerAddrStr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
relayTCPAddr, err := net.ResolveTCPAddr("tcp", relayCandidateStamp.ServerAddrStr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
return relayUDPAddr, relayTCPAddr, nil
|
||||
return &Relay{Proto: stamps.StampProtoTypeDNSCryptRelay, Dnscrypt: &DNSCryptRelay{RelayUDPAddr: relayUDPAddr, RelayTCPAddr: relayTCPAddr}}, nil
|
||||
}
|
||||
return nil, nil, fmt.Errorf("Invalid relay [%v] for server [%v]", relayName, name)
|
||||
return nil, fmt.Errorf("Invalid relay [%v] for server [%v]", relayName, name)
|
||||
}
|
||||
|
||||
func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isNew bool) (ServerInfo, error) {
|
||||
|
@ -323,17 +332,21 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp
|
|||
break
|
||||
}
|
||||
}
|
||||
relayUDPAddr, relayTCPAddr, err := route(proxy, name)
|
||||
relay, err := route(proxy, name)
|
||||
if err != nil {
|
||||
return ServerInfo{}, err
|
||||
}
|
||||
certInfo, rtt, fragmentsBlocked, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew, relayUDPAddr, relayTCPAddr, knownBugs)
|
||||
var dnscryptRelay *DNSCryptRelay
|
||||
if relay != nil {
|
||||
dnscryptRelay = relay.Dnscrypt
|
||||
}
|
||||
certInfo, rtt, fragmentsBlocked, err := FetchCurrentDNSCryptCert(proxy, &name, proxy.mainProto, stamp.ServerPk, stamp.ServerAddrStr, stamp.ProviderName, isNew, dnscryptRelay, knownBugs)
|
||||
if !knownBugs.fragmentsBlocked && fragmentsBlocked {
|
||||
dlog.Debugf("[%v] drops fragmented queries", name)
|
||||
knownBugs.fragmentsBlocked = true
|
||||
}
|
||||
if knownBugs.fragmentsBlocked && (relayUDPAddr != nil || relayTCPAddr != nil) {
|
||||
relayTCPAddr, relayUDPAddr = nil, nil
|
||||
if knownBugs.fragmentsBlocked && relay != nil && relay.Dnscrypt != nil {
|
||||
relay = nil
|
||||
if proxy.skipAnonIncompatbibleResolvers {
|
||||
dlog.Infof("[%v] is incompatible with anonymization, it will be ignored", name)
|
||||
return ServerInfo{}, errors.New("Resolver is incompatible with anonymization")
|
||||
|
@ -361,8 +374,7 @@ func fetchDNSCryptServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp
|
|||
Timeout: proxy.timeout,
|
||||
UDPAddr: remoteUDPAddr,
|
||||
TCPAddr: remoteTCPAddr,
|
||||
RelayUDPAddr: relayUDPAddr,
|
||||
RelayTCPAddr: relayTCPAddr,
|
||||
Relay: relay,
|
||||
initialRtt: rtt,
|
||||
knownBugs: knownBugs,
|
||||
}, nil
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue