Преглед изворни кода

Switch up order of query checks in server.

We should set the AA bit if it applies, even if there are things wrong
with the query. An EDNS(0)-related error supersedes all others.
David Fifield пре 6 година
родитељ
комит
f8b9d73493
1 измењених фајлова са 31 додато и 21 уклоњено
  1. 31 21
      dnstt-server/main.go

+ 31 - 21
dnstt-server/main.go

@@ -179,7 +179,7 @@ func responseFor(query *dns.Message, domain dns.Name) (*dns.Message, turbotunnel
 
 
 	resp := &dns.Message{
 	resp := &dns.Message{
 		ID:       query.ID,
 		ID:       query.ID,
-		Flags:    0x8400, // QR = 1, AA = 1, RCODE = no error
+		Flags:    0x8000, // QR = 1, RCODE = no error
 		Question: query.Question,
 		Question: query.Question,
 	}
 	}
 
 
@@ -234,43 +234,53 @@ func responseFor(query *dns.Message, domain dns.Name) (*dns.Message, turbotunnel
 			payloadSize = 512
 			payloadSize = 512
 		}
 		}
 	}
 	}
+	// We will return RcodeFormatError if payloadSize is too small, but
+	// first, check the name in order to set the AA bit properly.
+
+	// There must be exactly one question.
+	if len(query.Question) != 1 {
+		resp.Flags |= dns.RcodeFormatError
+		return resp, clientID, nil
+	}
+	question := query.Question[0]
+	// Check the name to see if it ends in our chosen domain, and extract
+	// all that comes before the domain if it does. If it does not, we will
+	// return RcodeNameError below, but prefer to return RcodeFormatError
+	// for payload size if that applies as well.
+	prefix, ok := question.Name.TrimSuffix(domain)
+	if ok {
+		resp.Flags |= 0x0400 // AA = 1
+	}
+
+	// We require clients to support EDNS(0) with a minimum payload size;
+	// otherwise we would have to set a small KCP MTU (only around 200
+	// bytes). https://tools.ietf.org/html/rfc6891#section-7 "If there is a
+	// problem with processing the OPT record itself, such as an option
+	// value that is badly formatted or that includes out-of-range values, a
+	// FORMERR MUST be returned."
 	if payloadSize < maxUDPPayload {
 	if payloadSize < maxUDPPayload {
-		// We require clients to support EDNS(0) with a minimum payload
-		// size; otherwise we would have to set a small KCP MTU (only
-		// around 200 bytes).
-		// https://tools.ietf.org/html/rfc6891#section-7
-		// "If there is a problem with processing the OPT record itself,
-		// such as an option value that is badly formatted or that
-		// includes out-of-range values, a FORMERR MUST be returned."
 		resp.Flags |= dns.RcodeFormatError
 		resp.Flags |= dns.RcodeFormatError
 		return resp, clientID, nil
 		return resp, clientID, nil
 	}
 	}
 
 
+	if resp.Flags|0x0400 == 0 { // AA
+		// Not a name we are authoritative for.
+		resp.Flags |= dns.RcodeNameError
+		return resp, clientID, nil
+	}
+
 	if query.Flags&0x7800 != 0 {
 	if query.Flags&0x7800 != 0 {
 		// We don't support OPCODE != QUERY.
 		// We don't support OPCODE != QUERY.
 		resp.Flags |= dns.RcodeNotImplemented
 		resp.Flags |= dns.RcodeNotImplemented
 		return resp, clientID, nil
 		return resp, clientID, nil
 	}
 	}
 
 
-	if len(query.Question) != 1 {
-		// There must be exactly one question.
-		resp.Flags |= dns.RcodeFormatError
-		return resp, clientID, nil
-	}
-	question := query.Question[0]
 	if question.Type != dns.RRTypeTXT {
 	if question.Type != dns.RRTypeTXT {
 		// We only support QTYPE == TXT.
 		// We only support QTYPE == TXT.
 		resp.Flags |= dns.RcodeNotImplemented
 		resp.Flags |= dns.RcodeNotImplemented
 		return resp, clientID, nil
 		return resp, clientID, nil
 	}
 	}
 
 
-	prefix, ok := question.Name.TrimSuffix(domain)
-	if !ok {
-		// Not a name we are authoritative for.
-		resp.Flags |= dns.RcodeNameError
-		return resp, clientID, nil
-	}
-
 	encoded := bytes.ToUpper(bytes.Join(prefix, nil))
 	encoded := bytes.ToUpper(bytes.Join(prefix, nil))
 	payload := make([]byte, base32Encoding.DecodedLen(len(encoded)))
 	payload := make([]byte, base32Encoding.DecodedLen(len(encoded)))
 	n, err := base32Encoding.Decode(payload, encoded)
 	n, err := base32Encoding.Decode(payload, encoded)