// Resolve wraps Unbound's ub_resolve. func (u *Unbound) Resolve(name string, rrtype, rrclass uint16) (*Result, error) { res := C.new_ub_result() r := new(Result) defer C.ub_resolve_free(res) i := C.ub_resolve(u.ctx, C.CString(name), C.int(rrtype), C.int(rrclass), &res) err := newError(int(i)) if err != nil { return nil, err } r.Qname = C.GoString(res.qname) r.Qtype = uint16(res.qtype) r.Qclass = uint16(res.qclass) r.CanonName = C.GoString(res.canonname) r.Rcode = int(res.rcode) r.AnswerPacket = new(dns.Msg) r.AnswerPacket.Unpack(C.GoBytes(res.answer_packet, res.answer_len)) // Should always work r.HaveData = res.havedata == 1 r.NxDomain = res.nxdomain == 1 r.Secure = res.secure == 1 r.Bogus = res.bogus == 1 r.WhyBogus = C.GoString(res.why_bogus) // Re-create the RRs var h dns.RR_Header h.Name = r.Qname h.Rrtype = r.Qtype h.Class = r.Qclass h.Ttl = 0 r.Data = make([][]byte, 0) r.Rr = make([]dns.RR, 0) j := 0 if r.HaveData { b := C.GoBytes(unsafe.Pointer(C.array_elem_char(res.data, C.int(j))), C.array_elem_int(res.len, C.int(j))) for len(b) != 0 { // Create the RR h.Rdlength = uint16(len(b)) msg := make([]byte, 20+len(h.Name)) // Long enough off, _ := dns.PackStruct(&h, msg, 0) msg = msg[:off] rrbuf := append(msg, b...) rr, _, err := dns.UnpackRR(rrbuf, 0) if err == nil { r.Rr = append(r.Rr, rr) } r.Data = append(r.Data, b) j++ b = C.GoBytes(unsafe.Pointer(C.array_elem_char(res.data, C.int(j))), C.array_elem_int(res.len, C.int(j))) } } return r, err }