github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/dns/resolver/edns.go (about) 1 package dns 2 3 import ( 4 "bytes" 5 "net" 6 ) 7 8 type EDNSOPT [2]byte 9 10 // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-11 11 var ( 12 Reserved = EDNSOPT{0b00000000, 0b00000000} //0 13 LLQ = EDNSOPT{0b00000000, 0b00000001} //1 Optional 14 UL = EDNSOPT{0b00000000, 0b00000010} //2 On-hold 15 NSID = EDNSOPT{0b00000000, 0b00000011} //3 Standard 16 Reserved2 = EDNSOPT{0b00000000, 0b00000100} //4 17 DAU = EDNSOPT{0b00000000, 0b00000101} //5 Standard 18 DHU = EDNSOPT{0b00000000, 0b00000110} //6 Standard 19 N3U = EDNSOPT{0b00000000, 0b00000111} //7 Standard 20 EdnsClientSubnet = EDNSOPT{0b00000000, 0b00001000} //8 Optional 21 EDNSEXPIRE = EDNSOPT{0b00000000, 0b00001001} //9 Optional 22 COOKIE = EDNSOPT{0b00000000, 0b00001010} //10 Standard 23 TcpKeepalive = EDNSOPT{0b00000000, 0b00001011} //11 Standard 24 Padding = EDNSOPT{0b00000000, 0b00001100} //12 Standard 25 CHAIN = EDNSOPT{0b00000000, 0b00001101} //13 Standard 26 KEYTAG = EDNSOPT{0b00000000, 0b00001110} //14 Optional 27 ExtendedDNSError = EDNSOPT{0b00000000, 0b00001111} //15 Standard 28 EDNSClientTag = EDNSOPT{0b00000000, 0b00010000} //16 Optional 29 EDNSServerTag = EDNSOPT{0b00000000, 0b00010001} //17 Optional 30 31 ) 32 33 type eDNSHeader struct { 34 DnsHeader []byte 35 Name [1]byte 36 Type [2]byte 37 PayloadSize [2]byte 38 ExtendRCode [1]byte 39 EDNSVersion [1]byte 40 Z [2]byte 41 Data []byte 42 } 43 44 func createEDNSRequ(header eDNSHeader) []byte { 45 header.DnsHeader[10] = 0b00000000 46 header.DnsHeader[11] = 0b00000001 47 length := getLength(len(header.Data)) 48 return bytes.Join([][]byte{header.DnsHeader, header.Name[:], header.Type[:], header.PayloadSize[:], header.ExtendRCode[:], header.EDNSVersion[:], header.Z[:], length[:], header.Data}, []byte{}) 49 } 50 51 // https://tools.ietf.org/html/rfc7871 52 // https://tools.ietf.org/html/rfc2671 53 func createEDNSReq(domain string, reqType2 reqType, eDNS []byte) []byte { 54 data := bytes.NewBuffer(creatRequest(domain, reqType2, true)) 55 data.WriteByte(0b00000000) // name 56 data.Write([]byte{0b00000000, 0b00101001}) // type 41 57 data.Write([]byte{0b00010000, 0b00000000}) // payloadSize 4096 58 data.WriteByte(0b00000000) // extendRcode 59 data.WriteByte(0b00000000) // EDNS Version 60 data.Write([]byte{0b00000000, 0b00000000}) // Z 61 data.Write(getLength(len(eDNS))) // data length 62 data.Write(eDNS) // data 63 return data.Bytes() 64 } 65 66 func createEdnsClientSubnet(ip *net.IPNet) []byte { 67 optionData := bytes.NewBuffer(nil) 68 mask, _ := ip.Mask.Size() 69 subnet := ip.IP.To4() 70 if subnet == nil { // family https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml 71 optionData.Write([]byte{0b00000000, 0b00000010}) // family ipv6 2 72 subnet = ip.IP.To16() 73 } else { 74 optionData.Write([]byte{0b00000000, 0b00000001}) // family ipv4 1 75 } 76 optionData.WriteByte(byte(mask)) // mask 77 optionData.WriteByte(0b00000000) // 0 In queries, it MUST be set to 0. 78 optionData.Write(subnet) // subnet IP 79 80 data := bytes.NewBuffer(nil) 81 data.Write([]byte{EdnsClientSubnet[0], EdnsClientSubnet[1]}) // option Code 82 data.Write(getLength(optionData.Len())) // option data length 83 data.Write(optionData.Bytes()) // option data 84 return data.Bytes() 85 } 86 87 func getLength(length int) []byte { 88 return []byte{byte(length >> 8), byte(length - ((length >> 8) << 8))} 89 } 90 91 func resolveAdditional(b []byte, arCount int) { 92 for arCount != 0 { 93 arCount-- 94 //name := b[:1] 95 b = b[1:] // name 96 typeE := b[:2] 97 b = b[2:] // type 98 b = b[2:] // payLoadSize 99 b = b[1:] // rCode 100 b = b[1:] // version 101 b = b[2:] // Z 102 dataLength := int(b[0])<<8 + int(b[1]) 103 b = b[2:] 104 if typeE[0] != 0 || typeE[1] != 41 { 105 //optData := b[:dataLength] 106 b = b[dataLength:] // optData 107 continue 108 } 109 110 if dataLength == 0 { 111 continue 112 } 113 optCode := EDNSOPT{b[0], b[1]} 114 b = b[2:] 115 optionLength := int(b[0])<<8 + int(b[1]) 116 b = b[2:] 117 switch optCode { 118 case EdnsClientSubnet: 119 b = b[2:] // family 120 b = b[1:] // source Netmask 121 b = b[1:] // scope Netmask 122 b = b[optionLength-4:] // Subnet IP 123 default: 124 b = b[optionLength:] // opt data 125 } 126 } 127 } 128 129 // protocol change https://tools.ietf.org/html/rfc3225 130 // https://tools.ietf.org/html/rfc4034 131 // https://tools.ietf.org/html/rfc4035 132 // Algorithm https://tools.ietf.org/html/rfc4034#appendix-A.1 133 func createDNSSEC(domain string, reqType2 reqType) (header eDNSHeader, b []byte) { 134 //eDNSHeader := createEDNSReq(domain,reqType2,[]byte{}) 135 header = eDNSHeader{} 136 header.DnsHeader = creatRequest(domain, reqType2, true) 137 header.Name[0] = 0b0 138 header.Type = [2]byte{0b00000000, 0b00101001} 139 header.PayloadSize = [2]byte{0b00010000, 0b00000000} //4096 140 header.ExtendRCode = [1]byte{0b00000000} 141 header.EDNSVersion = [1]byte{0b00000000} 142 header.Z = [2]byte{0b10000000, 0b00000000} // Do bit = 1 143 return header, createEDNSRequ(header) 144 }