diff --git a/edns.go b/edns.go index e9e9e42e..6d0dfb9d 100644 --- a/edns.go +++ b/edns.go @@ -14,7 +14,7 @@ // o.Hdr.Rrtype = dns.TypeOPT // // The rdata of an OPT RR consists out of a slice of EDNS0 interfaces. Currently -// only a few have been standardized: EDNS0_NSID (RFC 5001) and EDNS0_SUBNET (draft). Note that +// only a few have been standardized: EDNS0_NSID (RFC 5001) and EDNS0_SUBNET (RFC 6891). Note that // these options may be combined in an OPT RR. // Basic use pattern for a server to check if (and which) options are set: // @@ -38,14 +38,15 @@ import ( // EDNS0 Option codes. const ( - EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 - EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt - EDNS0NSID = 0x3 // nsid (RFC5001) - EDNS0SUBNET = 0x50fa // client-subnet draft: http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-01 - EDNS0DAU = 0x5 // DNSSEC Algorithm Understood - EDNS0DHU = 0x6 // DS Hash Understood - EDNS0N3U = 0x7 // NSEC3 Hash Understood - _DO = 1 << 7 // dnssec ok + EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 + EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt + EDNS0NSID = 0x3 // nsid (RFC5001) + EDNS0DAU = 0x5 // DNSSEC Algorithm Understood + EDNS0DHU = 0x6 // DS Hash Understood + EDNS0N3U = 0x7 // NSEC3 Hash Understood + EDNS0SUBNET = 0x8 // client-subnet (RFC6891) + EDNS0SUBNETDRAFT = 0x50fa // client-subnet draft: http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-01 + _DO = 1 << 7 // dnssec ok ) type OPT struct { @@ -80,6 +81,9 @@ func (rr *OPT) String() string { } case *EDNS0_SUBNET: s += "\n; SUBNET: " + o.String() + if o.(*EDNS0_SUBNET).DraftOption { + s += " (draft)" + } case *EDNS0_UL: s += "\n; UPDATE LEASE: " + o.String() case *EDNS0_LLQ: @@ -220,10 +224,15 @@ type EDNS0_SUBNET struct { SourceNetmask uint8 SourceScope uint8 Address net.IP + DraftOption bool } func (e *EDNS0_SUBNET) Option() uint16 { - return EDNS0SUBNET + if e.DraftOption { + return EDNS0SUBNETDRAFT + } else { + return EDNS0SUBNET + } } func (e *EDNS0_SUBNET) pack() ([]byte, error) { diff --git a/ex/q/q.go b/ex/q/q.go index 63c5abea..86f776ba 100644 --- a/ex/q/q.go +++ b/ex/q/q.go @@ -44,6 +44,7 @@ func main() { tcp := flag.Bool("tcp", false, "TCP mode") nsid := flag.Bool("nsid", false, "set edns nsid option") client := flag.String("client", "", "set edns client-subnet option") + clientdraftcode := flag.Bool("clientdraft", false, "set edns client-subnet option using the draft option code") //serial := flag.Int("serial", 0, "perform an IXFR with this serial") flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [options] [@server] [qtype] [qclass] [name ...]\n", os.Args[0]) @@ -177,6 +178,9 @@ Flags: if *client != "" { e := new(dns.EDNS0_SUBNET) e.Code = dns.EDNS0SUBNET + if *clientdraftcode { + e.DraftOption = true + } e.SourceScope = 0 e.Address = net.ParseIP(*client) if e.Address == nil { diff --git a/msg.go b/msg.go index e647d6fa..098f0a18 100644 --- a/msg.go +++ b/msg.go @@ -786,11 +786,14 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err er e.unpack(msg[off1 : off1+int(optlen)]) edns = append(edns, e) off = off1 + int(optlen) - case EDNS0SUBNET: + case EDNS0SUBNET, EDNS0SUBNETDRAFT: e := new(EDNS0_SUBNET) e.unpack(msg[off1 : off1+int(optlen)]) edns = append(edns, e) off = off1 + int(optlen) + if code == EDNS0SUBNETDRAFT { + e.DraftOption = true + } case EDNS0UL: e := new(EDNS0_UL) e.unpack(msg[off1 : off1+int(optlen)])