From 236f7931e668ae81c2115ada11d1835159be95b1 Mon Sep 17 00:00:00 2001 From: Star Brilliant Date: Tue, 10 Apr 2018 14:02:51 +0800 Subject: [PATCH] Update to IETF draft-06 --- doh-client/client.go | 16 +++++++++------- doh-client/google.go | 2 +- doh-client/ietf.go | 7 ++++--- doh-server/ietf.go | 4 ++-- doh-server/server.go | 17 ++++++++++++----- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/doh-client/client.go b/doh-client/client.go index 04ad6e2..e30b649 100644 --- a/doh-client/client.go +++ b/doh-client/client.go @@ -182,21 +182,21 @@ func (c *Client) handlerFunc(w dns.ResponseWriter, r *dns.Msg, isTCP bool) { if len(c.conf.UpstreamIETF) == 0 { requestType = "application/dns-json" } else if len(c.conf.UpstreamGoogle) == 0 { - requestType = "application/dns-udpwireformat" + requestType = "message/dns" } else { numServers := len(c.conf.UpstreamGoogle) + len(c.conf.UpstreamIETF) random := rand.Intn(numServers) if random < len(c.conf.UpstreamGoogle) { requestType = "application/dns-json" } else { - requestType = "application/dns-udpwireformat" + requestType = "message/dns" } } var req *DNSRequest if requestType == "application/dns-json" { req = c.generateRequestGoogle(w, r, isTCP) - } else if requestType == "application/dns-udpwireformat" { + } else if requestType == "message/dns" { req = c.generateRequestIETF(w, r, isTCP) } else { panic("Unknown request Content-Type") @@ -210,19 +210,21 @@ func (c *Client) handlerFunc(w dns.ResponseWriter, r *dns.Msg, isTCP bool) { candidateType := strings.SplitN(req.response.Header.Get("Content-Type"), ";", 2)[0] if candidateType == "application/json" { contentType = "application/json" + } else if candidateType == "message/dns" { + contentType = "message/dns" } else if candidateType == "application/dns-udpwireformat" { - contentType = "application/dns-udpwireformat" + contentType = "message/dns" } else { if requestType == "application/dns-json" { contentType = "application/json" - } else if requestType == "application/dns-udpwireformat" { - contentType = "application/dns-udpwireformat" + } else if requestType == "message/dns" { + contentType = "message/dns" } } if contentType == "application/json" { c.parseResponseGoogle(w, r, isTCP, req) - } else if contentType == "application/dns-udpwireformat" { + } else if contentType == "message/dns" { c.parseResponseIETF(w, r, isTCP, req) } else { panic("Unknown response Content-Type") diff --git a/doh-client/google.go b/doh-client/google.go index 1e38db8..d2daa29 100644 --- a/doh-client/google.go +++ b/doh-client/google.go @@ -91,7 +91,7 @@ func (c *Client) generateRequestGoogle(w dns.ResponseWriter, r *dns.Msg, isTCP b err: err, } } - req.Header.Set("Accept", "application/json, application/dns-udpwireformat") + req.Header.Set("Accept", "application/json, message/dns, application/dns-udpwireformat") req.Header.Set("User-Agent", "DNS-over-HTTPS/1.1 (+https://github.com/m13253/dns-over-https)") c.httpClientMux.RLock() resp, err := c.httpClient.Do(req) diff --git a/doh-client/ietf.go b/doh-client/ietf.go index 7cd1023..e616a34 100644 --- a/doh-client/ietf.go +++ b/doh-client/ietf.go @@ -128,6 +128,7 @@ func (c *Client) generateRequestIETF(w dns.ResponseWriter, r *dns.Msg, isTCP boo numServers := len(c.conf.UpstreamIETF) upstream := c.conf.UpstreamIETF[rand.Intn(numServers)] requestURL := fmt.Sprintf("%s?ct=application/dns-udpwireformat&dns=%s", upstream, requestBase64) + //requestURL := fmt.Sprintf("%s?ct=message/dns&dns=%s", upstream, requestBase64) var req *http.Request if len(requestURL) < 2048 { @@ -150,9 +151,9 @@ func (c *Client) generateRequestIETF(w dns.ResponseWriter, r *dns.Msg, isTCP boo err: err, } } - req.Header.Set("Content-Type", "application/dns-udpwireformat") + req.Header.Set("Content-Type", "message/dns") } - req.Header.Set("Accept", "application/dns-udpwireformat, application/json") + req.Header.Set("Accept", "message/dns, application/dns-udpwireformat, application/json") req.Header.Set("User-Agent", "DNS-over-HTTPS/1.1 (+https://github.com/m13253/dns-over-https)") c.httpClientMux.RLock() resp, err := c.httpClient.Do(req) @@ -184,7 +185,7 @@ func (c *Client) parseResponseIETF(w dns.ResponseWriter, r *dns.Msg, isTCP bool, log.Printf("HTTP error: %s\n", req.response.Status) req.reply.Rcode = dns.RcodeServerFailure contentType := req.response.Header.Get("Content-Type") - if contentType != "application/dns-udpwireformat" && !strings.HasPrefix(contentType, "application/dns-udpwireformat;") { + if contentType != "message/dns" && !strings.HasPrefix(contentType, "message/dns;") { w.WriteMsg(req.reply) return } diff --git a/doh-server/ietf.go b/doh-server/ietf.go index 7786273..d08a50b 100644 --- a/doh-server/ietf.go +++ b/doh-server/ietf.go @@ -45,7 +45,7 @@ func (s *Server) parseRequestIETF(w http.ResponseWriter, r *http.Request) *DNSRe errtext: fmt.Sprintf("Invalid argument value: \"dns\" = %q", requestBase64), } } - if len(requestBinary) == 0 && r.Header.Get("Content-Type") == "application/dns-udpwireformat" { + if len(requestBinary) == 0 && (r.Header.Get("Content-Type") == "message/dns" || r.Header.Get("Content-Type") == "application/dns-udpwireformat") { requestBinary, err = ioutil.ReadAll(r.Body) if err != nil { return &DNSRequest{ @@ -144,7 +144,7 @@ func (s *Server) generateResponseIETF(w http.ResponseWriter, r *http.Request, re return } - w.Header().Set("Content-Type", "application/dns-udpwireformat") + w.Header().Set("Content-Type", "message/dns") now := time.Now().UTC().Format(http.TimeFormat) w.Header().Set("Date", now) w.Header().Set("Last-Modified", now) diff --git a/doh-server/server.go b/doh-server/server.go index 2eb4de7..2a0f33e 100644 --- a/doh-server/server.go +++ b/doh-server/server.go @@ -98,17 +98,20 @@ func (s *Server) handlerFunc(w http.ResponseWriter, r *http.Request) { if r.FormValue("name") != "" { contentType = "application/dns-json" } else if r.FormValue("dns") != "" { - contentType = "application/dns-udpwireformat" + contentType = "message/dns" } } var responseType string for _, responseCandidate := range strings.Split(r.Header.Get("Accept"), ",") { - responseCandidate = strings.ToLower(strings.SplitN(responseCandidate, ";", 2)[0]) + responseCandidate = strings.SplitN(responseCandidate, ";", 2)[0] if responseCandidate == "application/json" { responseType = "application/json" break } else if responseCandidate == "application/dns-udpwireformat" { - responseType = "application/dns-udpwireformat" + responseType = "message/dns" + break + } else if responseCandidate == "message/dns" { + responseType = "message/dns" break } } @@ -116,14 +119,18 @@ func (s *Server) handlerFunc(w http.ResponseWriter, r *http.Request) { // Guess response Content-Type based on request Content-Type if contentType == "application/dns-json" { responseType = "application/json" + } else if contentType == "message/dns" { + responseType = "message/dns" } else if contentType == "application/dns-udpwireformat" { - responseType = "application/dns-udpwireformat" + responseType = "message/dns" } } var req *DNSRequest if contentType == "application/dns-json" { req = s.parseRequestGoogle(w, r) + } else if contentType == "message/dns" { + req = s.parseRequestIETF(w, r) } else if contentType == "application/dns-udpwireformat" { req = s.parseRequestIETF(w, r) } else { @@ -144,7 +151,7 @@ func (s *Server) handlerFunc(w http.ResponseWriter, r *http.Request) { if responseType == "application/json" { s.generateResponseGoogle(w, r, req) - } else if responseType == "application/dns-udpwireformat" { + } else if responseType == "message/dns" { s.generateResponseIETF(w, r, req) } else { panic("Unknown response Content-Type")