Pad certificate requests and add support for proxies

This commit is contained in:
Frank Denis 2019-10-19 22:08:02 +02:00
parent ac6fd3db39
commit d6b63aaf15
2 changed files with 83 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"errors"
"net"
"strings"
"time"
@ -32,8 +33,7 @@ func FetchCurrentDNSCryptCert(proxy *Proxy, serverName *string, proto string, pk
}
query := new(dns.Msg)
query.SetQuestion(providerName, dns.TypeTXT)
client := dns.Client{Net: proto, UDPSize: uint16(MaxDNSUDPPacketSize)}
in, rtt, err := client.Exchange(query, serverAddress)
in, rtt, err := dnsExchange(proxy, proto, query, serverAddress)
if err != nil {
dlog.Noticef("[%s] TIMEOUT", *serverName)
return CertInfo{}, 0, err
@ -178,3 +178,82 @@ 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) {
var packet []byte
var rtt time.Duration
if proto == "udp" {
qNameLen, padding := len(query.Question[0].Name), 0
if qNameLen < 256 {
padding = 256 - qNameLen
}
if padding > 0 {
opt := new(dns.OPT)
opt.Hdr.Name = "."
ext := new(dns.EDNS0_PADDING)
ext.Padding = make([]byte, padding)
opt.Option = append(opt.Option, ext)
query.Extra = []dns.RR{opt}
}
binQuery, err := query.Pack()
if err != nil {
return nil, 0, err
}
udpAddr, err := net.ResolveUDPAddr("udp", serverAddress)
if err != nil {
return nil, 0, err
}
now := time.Now()
pc, err := net.DialUDP("udp", nil, udpAddr)
if err != nil {
return nil, 0, err
}
defer pc.Close()
pc.SetDeadline(time.Now().Add(proxy.timeout))
pc.Write(binQuery)
packet = make([]byte, MaxDNSPacketSize)
length, err := pc.Read(packet)
if err != nil {
return nil, 0, err
}
rtt = time.Since(now)
packet = packet[:length]
} else {
binQuery, err := query.Pack()
if err != nil {
return nil, 0, err
}
tcpAddr, err := net.ResolveTCPAddr("tcp", serverAddress)
if err != nil {
return nil, 0, err
}
now := time.Now()
var pc net.Conn
proxyDialer := proxy.xTransport.proxyDialer
if proxyDialer == nil {
pc, err = net.DialTCP("tcp", nil, tcpAddr)
} else {
pc, err = (*proxyDialer).Dial("tcp", tcpAddr.String())
}
if err != nil {
return nil, 0, err
}
defer pc.Close()
pc.SetDeadline(time.Now().Add(proxy.timeout))
binQuery, err = PrefixWithSize(binQuery)
if err != nil {
return nil, 0, err
}
pc.Write(binQuery)
packet, err = ReadPrefixed(&pc)
if err != nil {
return nil, 0, err
}
rtt = time.Since(now)
}
msg := dns.Msg{}
if err := msg.Unpack(packet); err != nil {
return nil, 0, err
}
return &msg, rtt, nil
}

View File

@ -298,6 +298,7 @@ func (proxy *Proxy) exchangeWithUDPServer(serverInfo *ServerInfo, sharedKey *[32
if err != nil {
return nil, err
}
defer pc.Close()
pc.SetDeadline(time.Now().Add(serverInfo.Timeout))
if serverInfo.RelayUDPAddr != nil {
proxy.prepareForRelay(serverInfo.UDPAddr.IP, serverInfo.UDPAddr.Port, &encryptedQuery)
@ -305,7 +306,6 @@ func (proxy *Proxy) exchangeWithUDPServer(serverInfo *ServerInfo, sharedKey *[32
pc.Write(encryptedQuery)
encryptedResponse := make([]byte, MaxDNSPacketSize)
length, err := pc.Read(encryptedResponse)
pc.Close()
if err != nil {
return nil, err
}
@ -329,6 +329,7 @@ func (proxy *Proxy) exchangeWithTCPServer(serverInfo *ServerInfo, sharedKey *[32
if err != nil {
return nil, err
}
defer pc.Close()
pc.SetDeadline(time.Now().Add(serverInfo.Timeout))
if serverInfo.RelayTCPAddr != nil {
proxy.prepareForRelay(serverInfo.TCPAddr.IP, serverInfo.TCPAddr.Port, &encryptedQuery)
@ -339,7 +340,6 @@ func (proxy *Proxy) exchangeWithTCPServer(serverInfo *ServerInfo, sharedKey *[32
}
pc.Write(encryptedQuery)
encryptedResponse, err := ReadPrefixed(&pc)
pc.Close()
if err != nil {
return nil, err
}