msg.Copy() makes a deep-copy of the msg object
There was a copy function that did shallow copies of the msg object. Export it and make it support proper deep copying.
This commit is contained in:
parent
a627d88e3f
commit
2cfad667d7
|
@ -105,7 +105,7 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
|
|||
return r, rtt, err
|
||||
}
|
||||
if shared {
|
||||
return r.copy(), rtt, nil
|
||||
return r.Copy(), rtt, nil
|
||||
}
|
||||
return r, rtt, nil
|
||||
}
|
||||
|
|
22
msg.go
22
msg.go
|
@ -1545,18 +1545,30 @@ func (dns *Msg) Len() int {
|
|||
return l
|
||||
}
|
||||
|
||||
func (dns *Msg) copy() *Msg {
|
||||
// Create a deep-copy
|
||||
func (dns *Msg) Copy() *Msg {
|
||||
r1 := new(Msg)
|
||||
r1.MsgHdr = dns.MsgHdr
|
||||
r1.Compress = dns.Compress
|
||||
|
||||
r1.Question = make([]Question, len(dns.Question))
|
||||
copy(r1.Question, dns.Question) // Question is an immutable value, ok to do a shallow-copy
|
||||
|
||||
r1.Answer = make([]RR, len(dns.Answer))
|
||||
for i := 0; i < len(dns.Answer); i++ {
|
||||
r1.Answer[i] = dns.Answer[i].copy()
|
||||
}
|
||||
|
||||
r1.Ns = make([]RR, len(dns.Ns))
|
||||
for i := 0; i < len(dns.Ns); i++ {
|
||||
r1.Ns[i] = dns.Ns[i].copy()
|
||||
}
|
||||
|
||||
r1.Extra = make([]RR, len(dns.Extra))
|
||||
copy(r1.Question, dns.Question)
|
||||
copy(r1.Answer, dns.Answer)
|
||||
copy(r1.Ns, dns.Ns)
|
||||
copy(r1.Extra, dns.Extra)
|
||||
for i := 0; i < len(dns.Extra); i++ {
|
||||
r1.Extra[i] = dns.Extra[i].copy()
|
||||
}
|
||||
|
||||
return r1
|
||||
}
|
||||
|
||||
|
|
16
types.go
16
types.go
|
@ -165,6 +165,14 @@ const (
|
|||
_LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2.
|
||||
)
|
||||
|
||||
// helper: duplicate net.IP structure (it's a []byte)
|
||||
func dupIP(ip net.IP) net.IP {
|
||||
var ip2 net.IP
|
||||
ip2 = make([]byte, len(ip))
|
||||
copy(ip2, ip)
|
||||
return ip2
|
||||
}
|
||||
|
||||
// DNS queries.
|
||||
type Question struct {
|
||||
Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed)
|
||||
|
@ -586,7 +594,7 @@ type A struct {
|
|||
}
|
||||
|
||||
func (rr *A) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *A) copy() RR { return &A{*rr.Hdr.copyHeader(), rr.A} }
|
||||
func (rr *A) copy() RR { return &A{*rr.Hdr.copyHeader(), dupIP(rr.A)} }
|
||||
func (rr *A) len() int { return rr.Hdr.len() + net.IPv4len }
|
||||
|
||||
func (rr *A) String() string {
|
||||
|
@ -602,7 +610,7 @@ type AAAA struct {
|
|||
}
|
||||
|
||||
func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *AAAA) copy() RR { return &AAAA{*rr.Hdr.copyHeader(), rr.AAAA} }
|
||||
func (rr *AAAA) copy() RR { return &AAAA{*rr.Hdr.copyHeader(), dupIP(rr.AAAA)} }
|
||||
func (rr *AAAA) len() int { return rr.Hdr.len() + net.IPv6len }
|
||||
|
||||
func (rr *AAAA) String() string {
|
||||
|
@ -1264,7 +1272,7 @@ func (rr *WKS) len() int { return rr.Hdr.len() + net.IPv4len + 1 }
|
|||
func (rr *WKS) copy() RR {
|
||||
cp := make([]uint16, len(rr.BitMap), cap(rr.BitMap))
|
||||
copy(cp, rr.BitMap)
|
||||
return &WKS{*rr.Hdr.copyHeader(), rr.Address, rr.Protocol, cp}
|
||||
return &WKS{*rr.Hdr.copyHeader(), dupIP(rr.Address), rr.Protocol, cp}
|
||||
}
|
||||
|
||||
func (rr *WKS) String() (s string) {
|
||||
|
@ -1303,7 +1311,7 @@ type L32 struct {
|
|||
}
|
||||
|
||||
func (rr *L32) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *L32) copy() RR { return &L32{*rr.Hdr.copyHeader(), rr.Preference, rr.Locator32} }
|
||||
func (rr *L32) copy() RR { return &L32{*rr.Hdr.copyHeader(), rr.Preference, dupIP(rr.Locator32)} }
|
||||
func (rr *L32) len() int { return rr.Hdr.len() + net.IPv4len }
|
||||
|
||||
func (rr *L32) String() string {
|
||||
|
|
Loading…
Reference in New Issue