mirror of
https://github.com/m13253/dns-over-https.git
synced 2026-03-31 11:55:38 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4516429ee | ||
|
|
12df47f45f | ||
|
|
450c10a594 | ||
|
|
e7c4450787 | ||
|
|
bd5ef5d61e | ||
|
|
ff0e9529cb | ||
|
|
627e2d639d | ||
|
|
7d5cf98d2b | ||
|
|
34adf40b36 | ||
|
|
b9c1bcaad2 | ||
|
|
47df06b6e2 | ||
|
|
1abba72898 | ||
|
|
ce656ac3f7 |
74
Changelog.md
Normal file
74
Changelog.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
This Changelog records major changes between versions.
|
||||||
|
|
||||||
|
Not all changes are recorded. Please check git log for details.
|
||||||
|
|
||||||
|
## Version 1.3.3
|
||||||
|
|
||||||
|
- Take User-Agent out of common library, that would be better for packaging
|
||||||
|
|
||||||
|
## Version 1.3.2
|
||||||
|
|
||||||
|
- Fix version string in HTTP User-Agent
|
||||||
|
|
||||||
|
## Version 1.3.1
|
||||||
|
|
||||||
|
- Fix the "address already in use" issue
|
||||||
|
|
||||||
|
## Version 1.3.0
|
||||||
|
|
||||||
|
- Breaking change: Add client / server support for multiple listen address
|
||||||
|
The `listen` option in the configuration file is a list now
|
||||||
|
|
||||||
|
## Version 1.2.1
|
||||||
|
|
||||||
|
- Update protocol to IETF draft-07
|
||||||
|
- Update installation documentations for Ubuntu / Debian
|
||||||
|
|
||||||
|
## Version 1.2.0
|
||||||
|
|
||||||
|
- Add installation documentations for Ubuntu / Debian
|
||||||
|
- Include CloudFlare DOH server (1.1.1.1, 1.0.0.1) in default configuration
|
||||||
|
- Fix a problem causing `go get` to fail due to relative paths
|
||||||
|
- Add documentation about `/etc/hosts` preloading
|
||||||
|
|
||||||
|
## Version 1.1.4
|
||||||
|
|
||||||
|
- Add `no_cookies` option
|
||||||
|
- Add documentation on privacy issues
|
||||||
|
- Adapt for CloudFlare DNS service
|
||||||
|
- Fix a problem causing a single network failure blocking future requests
|
||||||
|
- Add experimental macOS support
|
||||||
|
|
||||||
|
## Version 1.1.3
|
||||||
|
|
||||||
|
- Unsupported Content-Type now generates HTTP error code 415
|
||||||
|
|
||||||
|
## Version 1.1.2
|
||||||
|
|
||||||
|
- Adapt to IETF protocol
|
||||||
|
- Optimize for HTTP caches
|
||||||
|
|
||||||
|
## Version 1.1.1
|
||||||
|
|
||||||
|
- Adapt to IETF protocol
|
||||||
|
- Optimize for HTTP caches
|
||||||
|
- Add documentation for uninstallation instructions
|
||||||
|
- Fix build issues
|
||||||
|
|
||||||
|
## Version 1.1.0
|
||||||
|
|
||||||
|
- Adpat to IETF protocol
|
||||||
|
- Fix issues regarding to HTTP caching
|
||||||
|
- Require Go 1.9 to build now
|
||||||
|
- Fix systemd issue
|
||||||
|
|
||||||
|
## Version 1.0.1
|
||||||
|
|
||||||
|
- Fix build issues
|
||||||
|
|
||||||
|
## Version 1.0.0
|
||||||
|
|
||||||
|
- First release
|
||||||
|
- Relicense as MIT license
|
||||||
3
Makefile
3
Makefile
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
GOBUILD=go build
|
GOBUILD=go build
|
||||||
GOGET=go get -d -v
|
GOGET=go get -d -v
|
||||||
|
GOGET_UPDATE=go get -d -u -v
|
||||||
PREFIX=/usr/local
|
PREFIX=/usr/local
|
||||||
ifeq ($(shell uname),Darwin)
|
ifeq ($(shell uname),Darwin)
|
||||||
CONFDIR=/usr/local/etc/dns-over-https
|
CONFDIR=/usr/local/etc/dns-over-https
|
||||||
@@ -40,6 +41,8 @@ uninstall:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
deps:
|
deps:
|
||||||
|
@# I am not sure if it is the correct way to keep the common library updated
|
||||||
|
$(GOGET_UPDATE) github.com/m13253/dns-over-https/json-dns
|
||||||
$(GOGET) ./doh-client ./doh-server
|
$(GOGET) ./doh-client ./doh-server
|
||||||
|
|
||||||
doh-client/doh-client: deps doh-client/client.go doh-client/config.go doh-client/google.go doh-client/ietf.go doh-client/main.go json-dns/error.go json-dns/globalip.go json-dns/marshal.go json-dns/response.go json-dns/unmarshal.go
|
doh-client/doh-client: deps doh-client/client.go doh-client/config.go doh-client/google.go doh-client/ietf.go doh-client/main.go json-dns/error.go json-dns/globalip.go json-dns/marshal.go json-dns/response.go json-dns/unmarshal.go
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ import (
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
conf *config
|
conf *config
|
||||||
bootstrap []string
|
bootstrap []string
|
||||||
udpServer *dns.Server
|
udpServers []*dns.Server
|
||||||
tcpServer *dns.Server
|
tcpServers []*dns.Server
|
||||||
bootstrapResolver *net.Resolver
|
bootstrapResolver *net.Resolver
|
||||||
cookieJar *cookiejar.Jar
|
cookieJar *cookiejar.Jar
|
||||||
httpClientMux *sync.RWMutex
|
httpClientMux *sync.RWMutex
|
||||||
@@ -64,16 +64,21 @@ func NewClient(conf *config) (c *Client, err error) {
|
|||||||
c = &Client{
|
c = &Client{
|
||||||
conf: conf,
|
conf: conf,
|
||||||
}
|
}
|
||||||
c.udpServer = &dns.Server{
|
|
||||||
Addr: conf.Listen,
|
udpH := dns.HandlerFunc(c.udpHandlerFunc)
|
||||||
Net: "udp",
|
tcpH := dns.HandlerFunc(c.tcpHandlerFunc)
|
||||||
Handler: dns.HandlerFunc(c.udpHandlerFunc),
|
for _, addr := range conf.Listen {
|
||||||
UDPSize: 4096,
|
c.udpServers = append(c.udpServers, &dns.Server{
|
||||||
}
|
Addr: addr,
|
||||||
c.tcpServer = &dns.Server{
|
Net: "udp",
|
||||||
Addr: conf.Listen,
|
Handler: udpH,
|
||||||
Net: "tcp",
|
UDPSize: 4096,
|
||||||
Handler: dns.HandlerFunc(c.tcpHandlerFunc),
|
})
|
||||||
|
c.tcpServers = append(c.tcpServers, &dns.Server{
|
||||||
|
Addr: addr,
|
||||||
|
Net: "tcp",
|
||||||
|
Handler: tcpH,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
c.bootstrapResolver = net.DefaultResolver
|
c.bootstrapResolver = net.DefaultResolver
|
||||||
if len(conf.Bootstrap) != 0 {
|
if len(conf.Bootstrap) != 0 {
|
||||||
@@ -149,27 +154,25 @@ func (c *Client) newHTTPClient() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Start() error {
|
func (c *Client) Start() error {
|
||||||
result := make(chan error)
|
results := make(chan error, len(c.udpServers)+len(c.tcpServers))
|
||||||
go func() {
|
for _, srv := range append(c.udpServers, c.tcpServers...) {
|
||||||
err := c.udpServer.ListenAndServe()
|
go func(srv *dns.Server) {
|
||||||
if err != nil {
|
err := srv.ListenAndServe()
|
||||||
log.Println(err)
|
if err != nil {
|
||||||
}
|
log.Println(err)
|
||||||
result <- err
|
}
|
||||||
}()
|
results <- err
|
||||||
go func() {
|
}(srv)
|
||||||
err := c.tcpServer.ListenAndServe()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
result <- err
|
|
||||||
}()
|
|
||||||
err := <-result
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
err = <-result
|
|
||||||
return err
|
for i := 0; i < cap(results); i++ {
|
||||||
|
err := <-results
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(results)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) handlerFunc(w dns.ResponseWriter, r *dns.Msg, isTCP bool) {
|
func (c *Client) handlerFunc(w dns.ResponseWriter, r *dns.Msg, isTCP bool) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
Listen string `toml:"listen"`
|
Listen []string `toml:"listen"`
|
||||||
UpstreamGoogle []string `toml:"upstream_google"`
|
UpstreamGoogle []string `toml:"upstream_google"`
|
||||||
UpstreamIETF []string `toml:"upstream_ietf"`
|
UpstreamIETF []string `toml:"upstream_ietf"`
|
||||||
Bootstrap []string `toml:"bootstrap"`
|
Bootstrap []string `toml:"bootstrap"`
|
||||||
@@ -50,8 +50,8 @@ func loadConfig(path string) (*config, error) {
|
|||||||
return nil, &configError{fmt.Sprintf("unknown option %q", key.String())}
|
return nil, &configError{fmt.Sprintf("unknown option %q", key.String())}
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf.Listen == "" {
|
if len(conf.Listen) == 0 {
|
||||||
conf.Listen = "127.0.0.1:53"
|
conf.Listen = []string{"127.0.0.1:53", "[::1]:53"}
|
||||||
}
|
}
|
||||||
if len(conf.UpstreamGoogle) == 0 && len(conf.UpstreamIETF) == 0 {
|
if len(conf.UpstreamGoogle) == 0 && len(conf.UpstreamIETF) == 0 {
|
||||||
conf.UpstreamGoogle = []string{"https://dns.google.com/resolve"}
|
conf.UpstreamGoogle = []string{"https://dns.google.com/resolve"}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# DNS listen port
|
# DNS listen port
|
||||||
listen = "127.0.0.1:53"
|
listen = [
|
||||||
|
"127.0.0.1:53",
|
||||||
|
"[::1]:53",
|
||||||
|
]
|
||||||
|
|
||||||
# HTTP path for upstream resolver
|
# HTTP path for upstream resolver
|
||||||
# If multiple servers are specified, a random one will be chosen each time.
|
# If multiple servers are specified, a random one will be chosen each time.
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (c *Client) generateRequestGoogle(w dns.ResponseWriter, r *dns.Msg, isTCP b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
req.Header.Set("Accept", "application/json, application/dns-message, application/dns-udpwireformat")
|
req.Header.Set("Accept", "application/json, application/dns-message, application/dns-udpwireformat")
|
||||||
req.Header.Set("User-Agent", "DNS-over-HTTPS/1.1 (+https://github.com/m13253/dns-over-https)")
|
req.Header.Set("User-Agent", USER_AGENT)
|
||||||
c.httpClientMux.RLock()
|
c.httpClientMux.RLock()
|
||||||
resp, err := c.httpClient.Do(req)
|
resp, err := c.httpClient.Do(req)
|
||||||
c.httpClientMux.RUnlock()
|
c.httpClientMux.RUnlock()
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ func (c *Client) generateRequestIETF(w dns.ResponseWriter, r *dns.Msg, isTCP boo
|
|||||||
req.Header.Set("Content-Type", "application/dns-message")
|
req.Header.Set("Content-Type", "application/dns-message")
|
||||||
}
|
}
|
||||||
req.Header.Set("Accept", "application/dns-message, application/dns-udpwireformat, application/json")
|
req.Header.Set("Accept", "application/dns-message, application/dns-udpwireformat, application/json")
|
||||||
req.Header.Set("User-Agent", "DNS-over-HTTPS/1.1 (+https://github.com/m13253/dns-over-https)")
|
req.Header.Set("User-Agent", USER_AGENT)
|
||||||
c.httpClientMux.RLock()
|
c.httpClientMux.RLock()
|
||||||
resp, err := c.httpClient.Do(req)
|
resp, err := c.httpClient.Do(req)
|
||||||
c.httpClientMux.RUnlock()
|
c.httpClientMux.RUnlock()
|
||||||
|
|||||||
27
doh-client/version.go
Normal file
27
doh-client/version.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
DNS-over-HTTPS
|
||||||
|
Copyright (C) 2017-2018 Star Brilliant <m13253@hotmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
const VERSION = "1.3.3"
|
||||||
|
const USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
|
||||||
@@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
Listen string `toml:"listen"`
|
Listen []string `toml:"listen"`
|
||||||
Cert string `toml:"cert"`
|
Cert string `toml:"cert"`
|
||||||
Key string `toml:"key"`
|
Key string `toml:"key"`
|
||||||
Path string `toml:"path"`
|
Path string `toml:"path"`
|
||||||
@@ -51,9 +51,10 @@ func loadConfig(path string) (*config, error) {
|
|||||||
return nil, &configError{fmt.Sprintf("unknown option %q", key.String())}
|
return nil, &configError{fmt.Sprintf("unknown option %q", key.String())}
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf.Listen == "" {
|
if len(conf.Listen) == 0 {
|
||||||
conf.Listen = "127.0.0.1:8053"
|
conf.Listen = []string{"127.0.0.1:8053", "[::1]:8053"}
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf.Path == "" {
|
if conf.Path == "" {
|
||||||
conf.Path = "/dns-query"
|
conf.Path = "/dns-query"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# HTTP listen port
|
# HTTP listen port
|
||||||
listen = "127.0.0.1:8053"
|
listen = [
|
||||||
|
"127.0.0.1:8053",
|
||||||
|
"[::1]:8053",
|
||||||
|
]
|
||||||
|
|
||||||
# TLS certification file
|
# TLS certification file
|
||||||
cert = ""
|
cert = ""
|
||||||
|
|||||||
@@ -43,8 +43,5 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
server := NewServer(conf)
|
server := NewServer(conf)
|
||||||
err = server.Start()
|
_ = server.Start()
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,15 +75,35 @@ func (s *Server) Start() error {
|
|||||||
if s.conf.Verbose {
|
if s.conf.Verbose {
|
||||||
servemux = handlers.CombinedLoggingHandler(os.Stdout, servemux)
|
servemux = handlers.CombinedLoggingHandler(os.Stdout, servemux)
|
||||||
}
|
}
|
||||||
if s.conf.Cert != "" || s.conf.Key != "" {
|
results := make(chan error, len(s.conf.Listen))
|
||||||
return http.ListenAndServeTLS(s.conf.Listen, s.conf.Cert, s.conf.Key, servemux)
|
for _, addr := range s.conf.Listen {
|
||||||
|
go func(addr string) {
|
||||||
|
var err error
|
||||||
|
if s.conf.Cert != "" || s.conf.Key != "" {
|
||||||
|
err = http.ListenAndServeTLS(addr, s.conf.Cert, s.conf.Key, servemux)
|
||||||
|
} else {
|
||||||
|
err = http.ListenAndServe(addr, servemux)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
results <- err
|
||||||
|
}(addr)
|
||||||
}
|
}
|
||||||
return http.ListenAndServe(s.conf.Listen, servemux)
|
// wait for all handlers
|
||||||
|
for i := 0; i < cap(results); i++ {
|
||||||
|
err := <-results
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(results)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handlerFunc(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) handlerFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Server", "DNS-over-HTTPS/1.1 (+https://github.com/m13253/dns-over-https)")
|
w.Header().Set("Server", USER_AGENT)
|
||||||
w.Header().Set("X-Powered-By", "DNS-over-HTTPS/1.1 (+https://github.com/m13253/dns-over-https)")
|
w.Header().Set("X-Powered-By", USER_AGENT)
|
||||||
|
|
||||||
if r.Form == nil {
|
if r.Form == nil {
|
||||||
const maxMemory = 32 << 20 // 32 MB
|
const maxMemory = 32 << 20 // 32 MB
|
||||||
|
|||||||
27
doh-server/version.go
Normal file
27
doh-server/version.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
DNS-over-HTTPS
|
||||||
|
Copyright (C) 2017-2018 Star Brilliant <m13253@hotmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
const VERSION = "1.3.3"
|
||||||
|
const USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
|
||||||
Reference in New Issue
Block a user