diff --git a/doh-server/config.go b/doh-server/config.go index e51c07c..f937c14 100644 --- a/doh-server/config.go +++ b/doh-server/config.go @@ -31,6 +31,7 @@ import ( type config struct { Listen []string `toml:"listen"` + LocalAddr string `toml:"local_addr"` Cert string `toml:"cert"` Key string `toml:"key"` Path string `toml:"path"` diff --git a/doh-server/doh-server.conf b/doh-server/doh-server.conf index 335fe86..eaa7f53 100644 --- a/doh-server/doh-server.conf +++ b/doh-server/doh-server.conf @@ -4,6 +4,10 @@ listen = [ "[::1]:8053", ] +# Local address and port for upstream DNS +# If left empty, a local address is automatically chosen. +local_addr = "" + # TLS certification file # If left empty, plain-text HTTP will be used. # You are recommended to leave empty and to use a server load balancer (e.g. diff --git a/doh-server/main.go b/doh-server/main.go index a6c24e5..813bee5 100644 --- a/doh-server/main.go +++ b/doh-server/main.go @@ -110,6 +110,9 @@ func main() { conf.Verbose = true } - server := NewServer(conf) + server, err := NewServer(conf) + if err != nil { + log.Fatalln(err) + } _ = server.Start() } diff --git a/doh-server/server.go b/doh-server/server.go index 22ffce3..e758767 100644 --- a/doh-server/server.go +++ b/doh-server/server.go @@ -56,22 +56,41 @@ type DNSRequest struct { errtext string } -func NewServer(conf *config) (s *Server) { - s = &Server{ +func NewServer(conf *config) (*Server, error) { + timeout := time.Duration(conf.Timeout) * time.Second + s := &Server{ conf: conf, udpClient: &dns.Client{ Net: "udp", UDPSize: dns.DefaultMsgSize, - Timeout: time.Duration(conf.Timeout) * time.Second, + Timeout: timeout, }, tcpClient: &dns.Client{ Net: "tcp", - Timeout: time.Duration(conf.Timeout) * time.Second, + Timeout: timeout, }, 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) - return + return s, nil } func (s *Server) Start() error {