func (rr *OPT) SetDo(do ...bool) {
	if len(do) == 1 {
		if do[0] {
			rr.Hdr.Ttl |= _DO
		} else {
			rr.Hdr.Ttl &^= _DO
		}
	} else {
		rr.Hdr.Ttl |= _DO
	}
}
SetDo sets the DO (DNSSEC OK) bit.
If we pass an argument, set the DO bit to that value.
It is possible to pass 2 or more arguments. Any arguments after the 1st is silently ignored.
package dns
import (
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"net"
	"strconv"
)
const (
	EDNS0LLQ          = 0x1      
	EDNS0UL           = 0x2      
	EDNS0NSID         = 0x3      
	EDNS0DAU          = 0x5      
	EDNS0DHU          = 0x6      
	EDNS0N3U          = 0x7      
	EDNS0SUBNET       = 0x8      
	EDNS0EXPIRE       = 0x9      
	EDNS0COOKIE       = 0xa      
	EDNS0TCPKEEPALIVE = 0xb      
	EDNS0SUBNETDRAFT  = 0x50fa   
	EDNS0LOCALSTART   = 0xFDE9   
	EDNS0LOCALEND     = 0xFFFE   
	_DO               = 1 << 15  
)
type OPT struct {
	Hdr    RR_Header
	Option []EDNS0 `dns:"opt"`
}
func (rr *OPT) String() string {
	s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; "
	if rr.Do() {
		s += "flags: do; "
	} else {
		s += "flags: ; "
	}
	s += "udp: " + strconv.Itoa(int(rr.UDPSize()))
	for _, o := range rr.Option {
		switch o.(type) {
		case *EDNS0_NSID:
			s += "\n; NSID: " + o.String()
			h, e := o.pack()
			var r string
			if e == nil {
				for _, c := range h {
					r += "(" + string(c) + ")"
				}
				s += "  " + r
			}
		case *EDNS0_SUBNET:
			s += "\n; SUBNET: " + o.String()
			if o.(*EDNS0_SUBNET).DraftOption {
				s += " (draft)"
			}
		case *EDNS0_COOKIE:
			s += "\n; COOKIE: " + o.String()
		case *EDNS0_UL:
			s += "\n; UPDATE LEASE: " + o.String()
		case *EDNS0_LLQ:
			s += "\n; LONG LIVED QUERIES: " + o.String()
		case *EDNS0_DAU:
			s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String()
		case *EDNS0_DHU:
			s += "\n; DS HASH UNDERSTOOD: " + o.String()
		case *EDNS0_N3U:
			s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
		case *EDNS0_LOCAL:
			s += "\n; LOCAL OPT: " + o.String()
		}
	}
	return s
}
func (rr *OPT) len() int {
	l := rr.Hdr.len()
	for i := 0; i < len(rr.Option); i++ {
		l += 4  
		lo, _ := rr.Option[i].pack()
		l += len(lo)
	}
	return l
}
func (rr *OPT) Version() uint8 {
	return uint8((rr.Hdr.Ttl & 0x00FF0000) >> 16)
}
func (rr *OPT) SetVersion(v uint8) {
	rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | (uint32(v) << 16)
}
func (rr *OPT) ExtendedRcode() int {
	return int((rr.Hdr.Ttl&0xFF000000)>>24) + 15
}
func (rr *OPT) SetExtendedRcode(v uint8) {
	if v < RcodeBadVers {  
		return
	}
	rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v-15) << 24)
}
func (rr *OPT) UDPSize() uint16 {
	return rr.Hdr.Class
}
func (rr *OPT) SetUDPSize(size uint16) {
	rr.Hdr.Class = size
}
func (rr *OPT) Do() bool {
	return rr.Hdr.Ttl&_DO == _DO
}