//a,ns,txt,cname,soa,srv,aaaa,mx int fill_rrset_in_buffer(uchar * buffer, uchar * label, uchar * hdr, int lth, int type, struct hlpp *hlp) { int mlen = 0; uint16_t len = lth; // uchar nsc[512] = { 0 }; struct srv *from, *to; switch (type) { case A: mlen = 4; memcpy(buffer, label, 4); break; case NS: case CNAME: get_domain_from_msg(label, hdr, buffer, &mlen); to_lowercase(buffer, mlen); break; case SOA: //do nothing mlen = 0; break; case AAAA: mlen = 16; memcpy(buffer, label, 16); break; case MX: memcpy(buffer, label, 2); //reference value label += 2; //16bits buffer += 2; get_domain_from_msg(label, hdr, buffer, &mlen); mlen += 2; break; case SRV: from = (struct srv *) label; to = (struct srv *) buffer; to->pri = from->pri; //net endian to->wei = from->wei; to->port = from->port; buffer += sizeof(uint16_t) * 3; label += sizeof(uint16_t) * 3; get_domain_from_msg(label, hdr, buffer, &mlen); mlen += sizeof(uint16_t) * 3; break; case TXT: //the only case that lth used memcpy(buffer, &len, sizeof(uint16_t)); //uint16_t buffer += sizeof(uint16_t); memcpy(buffer, label, lth); mlen = lth + sizeof(uint16_t); break; default: return -1; } return mlen; }
void fun(void *buf, int32_t b_len, char *src,char *answer) { char domain[256] = {0}; int len = 0; int num = 0; struct in_addr ips[10]; int i = 0; printf("get type - %d\n",get_view_from_msg(buf)); printf("get vid - %d\n",get_vid_from_msg(buf)); printf("get opt - %d\n",get_opt_from_msg(buf)); get_domain_from_msg(buf,domain,&len); printf("get domain - %s(%d)\n",domain,len); get_ip_from_msg(buf,ips,&num); printf("get ip - (%d)\n",num); for (i = 0; i < num ; i ++) { printf("get ip - %s\n",inet_ntoa(ips[i])); } memcpy(answer,"01",2); }
//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; }
//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[65535] = {0}; ushort type = 0,class,lth,offset; uint ttl = 0,tmpttl,tx; int i,dlen,bidx = 0,ret; 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[512] = {0},dm[512] = {0},*itor = NULL; ushort tmptype = 0; int tag; itor = buffer + sizeof(struct mvalue); tx = global_now; /// //if(hlp->section != AN_SECTION) //see header comments. //rbt = NULL; for(i = 0;i < n;i ++) { dlen = get_domain_from_msg(label,hdr,tmpdomain); if(dm[1] == 0 && dm[2] == 0) //first time { memcpy(dm + 1,tmpdomain,strlen(tmpdomain) + 1); if(check_dms(dm + 1,hlp->dms,hlp->dmsidx) < 0) return NULL; } if(dlen < 0) return NULL; label += dlen; if(get_dns_info(label,&tmptype,&class,&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) *stype = tmptype; if(type == 0) //first time type = tmptype; if(ttl > MAX_TTL) ttl = MAX_TTL; if(tmpttl == 0) //first time tmpttl = ttl; if((strcmp(tmpdomain,dm + 1) != 0) || (type != tmptype)) { if(check_dms(dm,hlp->dms,hlp->dmsidx) < 0) return NULL; dm[0] = type; mv->ttl = random_ttl(tmpttl + i + (tx % 5)) + tx; mv->hits = 0; mv->seg = 0; //23com0 if(dm[dm[1] + 2] != 0) //not top level domain insert_kv_mem(rbt,ds,dm,buffer,mv->len + sizeof(struct mvalue)); type = tmptype; memcpy(dm + 1,tmpdomain,strlen(tmpdomain) + 1); mv->len = mv->ttl = mv->num = mv->hits = 0; 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) { dm[0] = type; mv->ttl = random_ttl(tmpttl + i + (tx % 5)) + tx; mv->hits = 0; mv->seg = 0; if(dm[dm[1] + 2] != 0) //not top level domain insert_kv_mem(rbt,ds,dm,buffer,mv->len + sizeof(struct mvalue)); } return label; }