func parseQuery(m *dns.Msg) { var rr dns.RR for _, q := range m.Question { if read_rr, e := getRecord(q.Name, q.Qtype); e == nil { rr = read_rr.(dns.RR) if rr.Header().Name == q.Name { m.Answer = append(m.Answer, rr) } } else { m2 := new(dns.Msg) if q.Qtype == dns.TypeA { m2.SetQuestion(q.Name, dns.TypeA) } else { m2.Question = make([]dns.Question, 1) m2.Question[0] = q } ret := queryUpStream(m2) if ret != nil { if q.Qtype == dns.TypeA { for _, r := range ret.Answer { // fmt.Printf("%s\n", r) if *cache { storeRecord(r) //FIXME: only be able to save one record } tmp := strings.Split(r.String(), " ") if len(tmp) > 2 && tmp[len(tmp)-2] == "A" { fmt.Printf("%s\n", tmp[len(tmp)-1]) } } } m.Answer = append(m.Answer, ret.Answer...) } } } }
func updateRecord(r dns.RR, q *dns.Question) { var ( rr dns.RR name string rtype uint16 ttl uint32 ip net.IP ) header := r.Header() name = header.Name rtype = header.Rrtype ttl = header.Ttl if _, ok := dns.IsDomainName(name); ok { if header.Class == dns.ClassANY && header.Rdlength == 0 { // Delete record deleteRecord(name, rtype) } else { // Add record rheader := dns.RR_Header{ Name: name, Rrtype: rtype, Class: dns.ClassINET, Ttl: ttl, } if a, ok := r.(*dns.A); ok { rrr, err := getRecord(name, rtype) if err == nil { rr = rrr.(*dns.A) } else { rr = new(dns.A) } ip = a.A rr.(*dns.A).Hdr = rheader rr.(*dns.A).A = ip } else if a, ok := r.(*dns.AAAA); ok { rrr, err := getRecord(name, rtype) if err == nil { rr = rrr.(*dns.AAAA) } else { rr = new(dns.AAAA) } ip = a.AAAA rr.(*dns.AAAA).Hdr = rheader rr.(*dns.AAAA).AAAA = ip } storeRecord(rr) } } }
func storeRecord(rr dns.RR) (err error) { key, _ := getKey(rr.Header().Name, rr.Header().Rrtype) err = bdb.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(rr_bucket)) err := b.Put([]byte(key), []byte(rr.String())) if err != nil { e := errors.New("Store record failed: " + rr.String()) log.Println(e.Error()) return e } return nil }) return err }