mirror of
https://github.com/m13253/dns-over-https.git
synced 2026-03-31 18:25:38 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ec9548ff1 | ||
|
|
81f1cfba5d | ||
|
|
ebba9c8ef5 | ||
|
|
6a2f2cea22 | ||
|
|
63f07d20af | ||
|
|
f0dec57e1a | ||
|
|
f6b52a653a | ||
|
|
9a07f5b856 | ||
|
|
8787921faf | ||
|
|
1642730af0 | ||
|
|
2332d9b7c1 | ||
|
|
7f5a23584f | ||
|
|
17e5848178 |
11
Changelog.md
11
Changelog.md
@@ -4,6 +4,17 @@ This Changelog records major changes between versions.
|
|||||||
|
|
||||||
Not all changes are recorded. Please check git log for details.
|
Not all changes are recorded. Please check git log for details.
|
||||||
|
|
||||||
|
## Version 2.1.0
|
||||||
|
|
||||||
|
- Add `local_addr` configuration for doh-server (#39)
|
||||||
|
- Fix a problem when compiling on macOS 10.14.4 or newer
|
||||||
|
- Add Quad9 DoH server to the example `doh-client.conf`
|
||||||
|
- Use TCP when appropriate for the given query type/response (AXFR/IXFR)
|
||||||
|
|
||||||
|
## Version 2.0.1
|
||||||
|
|
||||||
|
- Fix a crash with the random load balancing algorithm.
|
||||||
|
|
||||||
## Version 2.0.0
|
## Version 2.0.0
|
||||||
|
|
||||||
**This is a breaking change!** Please update the configuration file after upgrading.
|
**This is a breaking change!** Please update the configuration file after upgrading.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ PREFIX = /usr/local
|
|||||||
all: doh-logger
|
all: doh-logger
|
||||||
|
|
||||||
doh-logger: doh-logger.swift
|
doh-logger: doh-logger.swift
|
||||||
$(SWIFTC) -o $@ -O -static-stdlib $<
|
$(SWIFTC) -o $@ -O $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f doh-logger
|
rm -f doh-logger
|
||||||
|
|||||||
@@ -21,25 +21,24 @@ upstream_selector = "random"
|
|||||||
# weight = 50
|
# weight = 50
|
||||||
|
|
||||||
## CloudFlare's resolver, bad ECS, good DNSSEC
|
## CloudFlare's resolver, bad ECS, good DNSSEC
|
||||||
#[[upstream.upstream_google]]
|
## ECS is disabled for privacy by design: https://developers.cloudflare.com/1.1.1.1/nitty-gritty-details/#edns-client-subnet
|
||||||
# url = "https://cloudflare-dns.com/dns-query"
|
|
||||||
# weight = 50
|
|
||||||
|
|
||||||
## CloudFlare's resolver, bad ECS, good DNSSEC
|
|
||||||
#[[upstream.upstream_google]]
|
|
||||||
# url = "https://1.1.1.1/dns-query"
|
|
||||||
# weight = 50
|
|
||||||
|
|
||||||
# CloudFlare's resolver, bad ECS, good DNSSEC
|
|
||||||
[[upstream.upstream_ietf]]
|
[[upstream.upstream_ietf]]
|
||||||
url = "https://cloudflare-dns.com/dns-query"
|
url = "https://cloudflare-dns.com/dns-query"
|
||||||
weight = 50
|
weight = 50
|
||||||
|
|
||||||
## CloudFlare's resolver, bad ECS, good DNSSEC
|
## CloudFlare's resolver, bad ECS, good DNSSEC
|
||||||
|
## ECS is disabled for privacy by design: https://developers.cloudflare.com/1.1.1.1/nitty-gritty-details/#edns-client-subnet
|
||||||
|
## Note that some ISPs have problems connecting to 1.1.1.1, try 1.0.0.1 if problems happen.
|
||||||
#[[upstream.upstream_ietf]]
|
#[[upstream.upstream_ietf]]
|
||||||
# url = "https://1.1.1.1/dns-query"
|
# url = "https://1.1.1.1/dns-query"
|
||||||
# weight = 50
|
# weight = 50
|
||||||
|
|
||||||
|
## Quad9's resolver, bad ECS, good DNSSEC
|
||||||
|
## ECS is disabled for privacy by design: https://www.quad9.net/faq/#What_is_EDNS_Client-Subnet
|
||||||
|
#[[upstream.upstream_ietf]]
|
||||||
|
# url = "https://9.9.9.9/dns-query"
|
||||||
|
# weight = 50
|
||||||
|
|
||||||
## Google's experimental resolver, good ECS, good DNSSEC
|
## Google's experimental resolver, good ECS, good DNSSEC
|
||||||
#[[upstream.upstream_ietf]]
|
#[[upstream.upstream_ietf]]
|
||||||
# url = "https://dns.google.com/experimental"
|
# url = "https://dns.google.com/experimental"
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func (rs *RandomSelector) Add(url string, upstreamType UpstreamType) (err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RandomSelector) Get() *Upstream {
|
func (rs *RandomSelector) Get() *Upstream {
|
||||||
return rs.upstreams[rand.Intn(len(rs.upstreams)-1)]
|
return rs.upstreams[rand.Intn(len(rs.upstreams))]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *RandomSelector) StartEvaluate() {}
|
func (rs *RandomSelector) StartEvaluate() {}
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
const (
|
const (
|
||||||
VERSION = "2.0.0"
|
VERSION = "2.1.0"
|
||||||
USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
|
USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import (
|
|||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
Listen []string `toml:"listen"`
|
Listen []string `toml:"listen"`
|
||||||
|
LocalAddr string `toml:"local_addr"`
|
||||||
Cert string `toml:"cert"`
|
Cert string `toml:"cert"`
|
||||||
Key string `toml:"key"`
|
Key string `toml:"key"`
|
||||||
Path string `toml:"path"`
|
Path string `toml:"path"`
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ listen = [
|
|||||||
"[::1]:8053",
|
"[::1]:8053",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Local address and port for upstream DNS
|
||||||
|
# If left empty, a local address is automatically chosen.
|
||||||
|
local_addr = ""
|
||||||
|
|
||||||
# TLS certification file
|
# TLS certification file
|
||||||
# If left empty, plain-text HTTP will be used.
|
# If left empty, plain-text HTTP will be used.
|
||||||
# You are recommended to leave empty and to use a server load balancer (e.g.
|
# You are recommended to leave empty and to use a server load balancer (e.g.
|
||||||
|
|||||||
@@ -110,6 +110,9 @@ func main() {
|
|||||||
conf.Verbose = true
|
conf.Verbose = true
|
||||||
}
|
}
|
||||||
|
|
||||||
server := NewServer(conf)
|
server, err := NewServer(conf)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
_ = server.Start()
|
_ = server.Start()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,22 +56,41 @@ type DNSRequest struct {
|
|||||||
errtext string
|
errtext string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(conf *config) (s *Server) {
|
func NewServer(conf *config) (*Server, error) {
|
||||||
s = &Server{
|
timeout := time.Duration(conf.Timeout) * time.Second
|
||||||
|
s := &Server{
|
||||||
conf: conf,
|
conf: conf,
|
||||||
udpClient: &dns.Client{
|
udpClient: &dns.Client{
|
||||||
Net: "udp",
|
Net: "udp",
|
||||||
UDPSize: dns.DefaultMsgSize,
|
UDPSize: dns.DefaultMsgSize,
|
||||||
Timeout: time.Duration(conf.Timeout) * time.Second,
|
Timeout: timeout,
|
||||||
},
|
},
|
||||||
tcpClient: &dns.Client{
|
tcpClient: &dns.Client{
|
||||||
Net: "tcp",
|
Net: "tcp",
|
||||||
Timeout: time.Duration(conf.Timeout) * time.Second,
|
Timeout: timeout,
|
||||||
},
|
},
|
||||||
servemux: http.NewServeMux(),
|
servemux: http.NewServeMux(),
|
||||||
}
|
}
|
||||||
|
if conf.LocalAddr != "" {
|
||||||
|
udpLocalAddr, err := net.ResolveUDPAddr("udp", conf.LocalAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tcpLocalAddr, err := net.ResolveTCPAddr("tcp", conf.LocalAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.udpClient.Dialer = &net.Dialer{
|
||||||
|
Timeout: timeout,
|
||||||
|
LocalAddr: udpLocalAddr,
|
||||||
|
}
|
||||||
|
s.tcpClient.Dialer = &net.Dialer{
|
||||||
|
Timeout: timeout,
|
||||||
|
LocalAddr: tcpLocalAddr,
|
||||||
|
}
|
||||||
|
}
|
||||||
s.servemux.HandleFunc(conf.Path, s.handlerFunc)
|
s.servemux.HandleFunc(conf.Path, s.handlerFunc)
|
||||||
return
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Start() error {
|
func (s *Server) Start() error {
|
||||||
@@ -244,20 +263,39 @@ func (s *Server) patchRootRD(req *DNSRequest) *DNSRequest {
|
|||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the position index for the question of qtype from a DNS msg, otherwise return -1
|
||||||
|
func (s *Server) indexQuestionType(msg *dns.Msg, qtype uint16) int {
|
||||||
|
for i, question := range msg.Question {
|
||||||
|
if question.Qtype == qtype {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) doDNSQuery(ctx context.Context, req *DNSRequest) (resp *DNSRequest, err error) {
|
func (s *Server) doDNSQuery(ctx context.Context, req *DNSRequest) (resp *DNSRequest, err error) {
|
||||||
// TODO(m13253): Make ctx work. Waiting for a patch for ExchangeContext from miekg/dns.
|
// TODO(m13253): Make ctx work. Waiting for a patch for ExchangeContext from miekg/dns.
|
||||||
numServers := len(s.conf.Upstream)
|
numServers := len(s.conf.Upstream)
|
||||||
for i := uint(0); i < s.conf.Tries; i++ {
|
for i := uint(0); i < s.conf.Tries; i++ {
|
||||||
req.currentUpstream = s.conf.Upstream[rand.Intn(numServers)]
|
req.currentUpstream = s.conf.Upstream[rand.Intn(numServers)]
|
||||||
if !s.conf.TCPOnly {
|
|
||||||
|
// Use TCP if always configured to or if the Query type dictates it (AXFR)
|
||||||
|
if s.conf.TCPOnly || (s.indexQuestionType(req.request, dns.TypeAXFR) > -1) {
|
||||||
|
req.response, _, err = s.tcpClient.Exchange(req.request, req.currentUpstream)
|
||||||
|
} else {
|
||||||
req.response, _, err = s.udpClient.Exchange(req.request, req.currentUpstream)
|
req.response, _, err = s.udpClient.Exchange(req.request, req.currentUpstream)
|
||||||
if err == nil && req.response != nil && req.response.Truncated {
|
if err == nil && req.response != nil && req.response.Truncated {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
req.response, _, err = s.tcpClient.Exchange(req.request, req.currentUpstream)
|
req.response, _, err = s.tcpClient.Exchange(req.request, req.currentUpstream)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
// Retry with TCP if this was an IXFR request and we only received an SOA
|
||||||
|
if (s.indexQuestionType(req.request, dns.TypeIXFR) > -1) &&
|
||||||
|
(len(req.response.Answer) == 1) &&
|
||||||
|
(req.response.Answer[0].Header().Rrtype == dns.TypeSOA) {
|
||||||
req.response, _, err = s.tcpClient.Exchange(req.request, req.currentUpstream)
|
req.response, _, err = s.tcpClient.Exchange(req.request, req.currentUpstream)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
const (
|
const (
|
||||||
VERSION = "2.0.0"
|
VERSION = "2.1.0"
|
||||||
USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
|
USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user