//-1 error //-2 tc //0 continue //1 normal int check_enter(struct author *author, uchar * buf, int *idx, mbuf_type **mbuf, packet_type *lowerdomain) { int32_t id, typeoff; int /*off, */ret; int tx = 0; dnsheader *hdr = (dnsheader *) buf; *idx = hdr->id; id = GET_IDX(hdr->id); typeoff = GET_TYPE(hdr->id); if (id >= QLIST_TABLE_SIZE || typeoff >= SUPPORT_TYPE_NUM) return -1; ret = check_dns_name(buf + sizeof(dnsheader), lowerdomain); if (ret < 0) return -1; ret = htable_find_list(author->s->qlist, lowerdomain->domain, typeoff, id, (uchar **)mbuf); if (ret < 0) return -1; if ((*mbuf)->stat == NEW_QUERY) { *mbuf = NULL; return -1; } //-1 error //1 tc //0 normal //2 retry ret = check_an_msg(hdr->flags, NULL, &tx); if (ret < 0) return -1; //error if (ret == 1) //tc return -2; if ((ret == 2) && (tx == 1)) //server error ,continue return -3; (*mbuf)->socktype = UDP; //default return 1; }
//make import info into struct baseinfo void passer_dns_data(mbuf_type *mbuf) { uchar *buf = mbuf->buf; int num; int dlen = 0; uchar *tail = NULL; dnsheader *hdr = (dnsheader *) buf; mbuf->err = 1; num = ntohs(hdr->qdcount); if (num != 1) return; num = ntohs(hdr->ancount); if (num != 0) return; num = ntohs(hdr->nscount); if (num != 0) return ; num = ntohs(hdr->arcount); if (num > 1) //edns makes ar==1 return; mbuf->id = hdr->id; dlen = check_dns_name(buf + sizeof(dnsheader), &(mbuf->lowerdomain)); if (dlen < 0) { return; } mbuf->dlen = dlen; tail = mbuf->origindomain = buf + sizeof(dnsheader); if (dlen == 2) // root tail += 1; else tail += dlen; mbuf->qtype = ntohs(*(ushort *) tail); if (check_support_type(mbuf->qtype) == 0) mbuf->err = 0; return; }
//make import info into struct baseinfo struct baseinfo passer_dns_data(struct sockinfo *si) { uchar *buf = si->buf; int num; int i = 0,len = sizeof(struct sockaddr_in); int dlen = 0,seg = 0; struct baseinfo bi; uchar *tail = NULL,*ptrs[MAX_NS_LVL] = {0},*domain = NULL; ushort offset; dnsheader *hdr = (dnsheader*)buf; bi.err = 1; num = ntohs(hdr->qdcount); if(num != 1) return bi; num = ntohs(hdr->ancount); if(num != 0) return bi; num = ntohs(hdr->nscount); if(num != 0) return bi; num = ntohs(hdr->arcount); if(num > 1) //edns makes ar==1 return bi; bi.id = hdr->id; //if(check_client_addr() < 0) //return bi; dlen = check_dns_name(buf + sizeof(dnsheader),&seg); if(dlen < 0) return bi; bi.dlen = dlen; tail = bi.origindomain = buf + sizeof(dnsheader); tail += dlen; bi.type = ntohs(*(ushort*)tail); if(check_support_type(bi.type) == 0) bi.err = 0; return bi; }
//when we insert "ttl expired" in the rbtree //if A or CNAME or MX or TXT or ... 's ttl is small, then we don't need to insert //NS's "ttl expired" element, we update the record at the same time when we //update A or CNAME Or MX or TXT or.... //if NS's ttl is small than A or CNAME or MX or TXT or ... //we update it when update A or CNAME or MX or TXT, or when some query some domain's NS //in brief, we insert ANSWER section into ttl tree only. uchar * process_rdata(struct hlpp * hlp, uchar * label, int n) { uchar *buffer = hlp->tmpbuf; ushort type = 0, classin, lth, tmptype = 0; uint ttl = 0, tmpttl = 0, tx; int i, dlen, ret, tmplen = 0; int *stype = hlp->stype; struct htable *ds = hlp->ds; struct rbtree *rbt = hlp->rbt; uchar *hdr = hlp->buf; int mlen = hlp->datalen; struct mvalue *mv = (struct mvalue *) buffer; uchar *tmpdomain = hlp->domainbuf, *dm, *itor = NULL; packet_type lowerdomain; dm = lowerdomain.domain; memset(mv, 0, sizeof(struct mvalue)); itor = buffer + sizeof(struct mvalue); tx = global_now; /// dm[0] = dm[1] = 0; //if(hlp->section != AN_SECTION) //see header comments. // rbt = NULL; for (i = 0; i < n; i++) { dlen = get_domain_from_msg(label, hdr, tmpdomain, &tmplen); if (dm[0] == 0 && dm[1] == 0) //first time { check_dns_name(tmpdomain, &lowerdomain); } if (dlen < 0) return NULL; label += dlen; if (get_dns_info(label, &tmptype, &classin, &ttl, <h) < 0) return NULL; if (ttl < MIN_TTL) ttl = MIN_TTL; ttl = random_ttl(ttl + n); label += 10; // 2type,2class,4ttl,2lth if ((tmptype == SOA || tmptype == CNAME) && i == (n - 1)) *stype = tmptype; if (type == 0) //first time type = tmptype; if (ttl > MAX_TTL) ttl = MAX_TTL; if (tmpttl == 0) //first time tmpttl = ttl; if ((dict_comp_str_equ(tmpdomain, dm) != 0) || (type != tmptype)) { mv->ttl = random_ttl(tmpttl + i + (tx % 5)) + tx; //23com0 if (dm[dm[0] + 2] != 0) //not top level domain insert_kv_mem(rbt, ds, dm, lowerdomain.label_len[0], type, buffer, mv->len + sizeof(struct mvalue), 0, &lowerdomain); type = tmptype; check_dns_name(tmpdomain, &lowerdomain); memset(mv, 0, sizeof(struct mvalue)); itor = buffer + sizeof(struct mvalue); } ret = fill_rrset_in_buffer(itor, label, hdr, lth, type, hlp); if (ret > 0) { itor += ret; //in dns msg mv->len += ret; //in memory mv->num++; } tmpttl = ttl; label += lth; if ((label < hdr) || (label > (hdr + mlen))) return NULL; } if (mv->num > 0) { mv->ttl = random_ttl(tmpttl + i + (tx % 5)) + tx; mv->hits = 0; mv->seg = 0; if (dm[dm[0] + 2] != 0) //not top level domain insert_kv_mem(rbt, ds, dm, lowerdomain.label_len[0], type, buffer, mv->len + sizeof(struct mvalue), 0, &lowerdomain); } return label; }