mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04:00 
			
		
		
		
	
		
			
	
	
		
			58 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			58 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package middleware
 | ||
|  | 
 | ||
|  | import (
 | ||
|  | 	"bytes"
 | ||
|  | 
 | ||
|  | 	"github.com/miekg/dns"
 | ||
|  | )
 | ||
|  | 
 | ||
|  | // Less returns <0 when a is less than b, 0 when they are equal and
 | ||
|  | // >0 when a is larger than b.
 | ||
|  | // The function order names in DNSSEC canonical order.
 | ||
|  | //
 | ||
|  | // See http://bert-hubert.blogspot.co.uk/2015/10/how-to-do-fast-canonical-ordering-of.html
 | ||
|  | // for a blog article on how we do this. And https://tools.ietf.org/html/rfc4034#section-6.1 .
 | ||
|  | func Less(a, b string) int {
 | ||
|  | 	i := 1
 | ||
|  | 	aj := len(a)
 | ||
|  | 	bj := len(b)
 | ||
|  | 	for {
 | ||
|  | 		ai, _ := dns.PrevLabel(a, i)
 | ||
|  | 		bi, _ := dns.PrevLabel(b, i)
 | ||
|  | 		// sadly this []byte will allocate...
 | ||
|  | 		ab := []byte(a[ai:aj])
 | ||
|  | 		toLowerAndDDD(ab)
 | ||
|  | 		bb := []byte(b[bi:bj])
 | ||
|  | 		toLowerAndDDD(bb)
 | ||
|  | 
 | ||
|  | 		res := bytes.Compare(ab, bb)
 | ||
|  | 		if res != 0 {
 | ||
|  | 			return res
 | ||
|  | 		}
 | ||
|  | 
 | ||
|  | 		i++
 | ||
|  | 		aj, bj = ai, bi
 | ||
|  | 	}
 | ||
|  | 	return 0
 | ||
|  | }
 | ||
|  | 
 | ||
|  | func toLowerAndDDD(b []byte) {
 | ||
|  | 	lb := len(b)
 | ||
|  | 	for i := 0; i < lb; i++ {
 | ||
|  | 		if b[i] >= 'A' && b[i] <= 'Z' {
 | ||
|  | 			b[i] += 32
 | ||
|  | 			continue
 | ||
|  | 		}
 | ||
|  | 		if i+3 < lb && b[i] == '\\' && isDigit(b[i+1]) && isDigit(b[i+2]) && isDigit(b[i+3]) {
 | ||
|  | 			b[i] = dddToByte(b[i:])
 | ||
|  | 			for j := i + 1; j < lb-3; j++ {
 | ||
|  | 				b[j] = b[j+3]
 | ||
|  | 			}
 | ||
|  | 			lb -= 3
 | ||
|  | 		}
 | ||
|  | 	}
 | ||
|  | }
 | ||
|  | 
 | ||
|  | func isDigit(b byte) bool     { return b >= '0' && b <= '9' }
 | ||
|  | func dddToByte(s []byte) byte { return byte((s[1]-'0')*100 + (s[2]-'0')*10 + (s[3] - '0')) }
 |