//First ensure the search name, if it has a cname, search the cname //If we find it in fwd table, return the ip length, it's > 0 //Here we dont care the cname in fwd table, if somebody want to do this //Add the main domain in fwd table int pre_find(struct qoutinfo *qo,struct htable *fwd,struct htable *ht,uchar *ip) { uchar td[512] = {0},*itor = NULL; int xlen = 0,dbg = 100; uchar buffer[2000] = {0}; struct mvalue *mv = NULL; qo->qname = Q_DOMAIN; //default if(qo->hascname == 1) { qo->qing = qo->qbuffer; //latest cname memcpy(td + 1,qo->qbuffer,strlen(qo->qbuffer) + 1); } else { memcpy(td,qo->td,qo->dlen + 1); qo->qing = qo->td + 1; } td[0] = A; //forward ip xlen = htable_find(fwd,td,ip,1900,NULL); //100 for struct mvalue if(xlen > 0) { ip = ip + xlen; mv = (struct mvalue*)ip; mv->num = 0; //tail 0 mv->ttl = 0; mv->hits = 0; mv->len = 0; return xlen; } if(qo->td[0] == CNAME) //query cname return 0; //find nothing td[0] = CNAME; itor = buffer; while(1) //find cname { xlen = find_record_with_ttl(ht,td,itor,2000,NULL); if(xlen > 0) {//if domain has a cname, put it in qo->qbuffer qo->qname = Q_CNAME; qo->hascname = 1; mv = (struct mvalue*)itor; itor = itor + sizeof(struct mvalue); memcpy(td + 1,itor,mv->len); if(mv->len > (QBUFFER_SIZE - 1)) return -1; memcpy(qo->qbuffer,itor,mv->len); qo->qing = qo->qbuffer; } else break; if((dbg --) == 0) return -1; } return 0; }
//format in databuffer //type.mvalue.data.type.mvalue.data.. int find_record_from_mem(uchar * otd, int dlen, int type, struct htable *datasets, uchar * tdbuffer, uchar * databuffer, hashval_t *hash) { uchar /*type, */*td = otd; int ret, dataidx = 0, clen, debug = 100; hashval_t thash, *h = hash; dataidx++; //add 1 for type. value will be type.mvalue.rrset if (type != CNAME) { while ((ret = find_record_with_ttl(datasets, td, dlen, CNAME, databuffer + dataidx, AUTH_DATA_LEN - dataidx, NULL, h)) > 0) { databuffer[dataidx - 1] = CNAME; //prev byte is type clen = ret - sizeof(struct mvalue); td = tdbuffer; memcpy(td, databuffer + dataidx + sizeof(struct mvalue), clen); dataidx += ret; dataidx++; //for type if (debug-- == 0) //error return -1; thash = 0; h = &thash; dlen = clen; } thash = 0; } ret = find_record_with_ttl(datasets, td, dlen, type, databuffer + dataidx, AUTH_DATA_LEN - dataidx, NULL, h); if (ret > 0) { databuffer[dataidx - 1] = type; dataidx += ret; return dataidx; } return -1; }
//we found some ns //try to find their ip int retrive_ip(mbuf_type *mbuf, uchar * itor, int num, uchar * ip, struct htable *ht, int *fq) { struct mvalue *mi = NULL; int i, xlen, iplen = IP_DATA_LEN; int got = 0; uchar *ipbuffer = mbuf->ipbuffer; *fq = 0; uchar *nstd, *iitor = ip; hashval_t hash; for (i = 0; i < num; i++) { xlen = strlen((const char *)itor) + 1; nstd = itor; itor = itor + xlen; hash = 0; xlen = find_record_with_ttl(ht, nstd, xlen, A, ipbuffer, iplen - sizeof(struct mvalue), NULL, &hash); if (xlen > 0) { mi = (struct mvalue *) ipbuffer; if (mi->seg > 0) //segment make_A_record_from_segment(ipbuffer, iitor); else memcpy(iitor, ipbuffer, mi->len + sizeof(struct mvalue)); iitor = iitor + mi->len + sizeof(struct mvalue); iplen = iplen - mi->len - sizeof(struct mvalue); got++; } if (xlen < 0) //iplen is not enough { *fq = i; break; } } if (iitor != ip) //found some ip { mi = (struct mvalue *) iitor; mi->num = 0; //tail 0 mi->ttl = 0; mi->hits = 0; mi->len = 0; return got; } return -1; //no ip }
//we found some ns //try to find their ip int retrive_ip(uchar *itor,int num,uchar *ip,struct htable *ht,int *fq) { struct mvalue *mi = NULL; int i,xlen,iplen = IP_DATA_LEN; int got = 0; uchar ipbuffer[400] = {0}; *fq = 0; uchar nstd[512] = {0},*iitor = ip; for(i = 0;i < num;i ++) { nstd[0] = A; //NS's A xlen = strlen(itor) + 1; memcpy(nstd + 1,itor,xlen); itor = itor + xlen; xlen = find_record_with_ttl(ht,nstd,ipbuffer,iplen - sizeof(struct mvalue),NULL); if(xlen > 0) { mi = (struct mvalue*)ipbuffer; if(mi->seg > 0) //segment make_A_record_from_segment(ipbuffer); //after make_A_xxxx //ipbuffer changed and mi changed too memcpy(iitor,ipbuffer,mi->len + sizeof(struct mvalue)); iitor = iitor + mi->len + sizeof(struct mvalue); iplen = iplen - mi->len - sizeof(struct mvalue); got ++; } if(xlen < 0) //iplen is not enough { *fq = i; break; } } if(iitor != ip) //found some ip { mi = (struct mvalue*)iitor; mi->num = 0; //tail 0 mi->ttl = 0; mi->hits = 0; mi->len = 0; return got; } return -1; //no ip }
//ht,type,domain,dlen int find_addr(struct htable *fwd, struct htable *ht, mbuf_type *mbuf, uchar * ip, int forward) { int ret, xlen = 0, dbg = 100; int first_query, i; struct mvalue *mv = NULL; uchar *td, *buffer = mbuf->tempbuffer, *itor = NULL, *glue = NULL; int td_len, diff_len; int ori_flag = 0; int root_flag = 0; hashval_t thash, *hash; int label_count = 0; if (mbuf->qtimes > (MAX_TRY_TIMES - 3)) { fill_extra_addr(ip); return 0; } ret = pre_find(mbuf, fwd, ht, ip); if (ret > 0) //find fwd return 0; else if (ret < 0) //error return ret; else { if (forward) { fill_extra_addr(ip); return 0; } } //now we have domain or latest cname in qo->qing //point to qo->td or qo->qbuffer td = mbuf->qing; itor = td; hash = mbuf->qhash; td_len = mbuf->qlen; if (mbuf->hascname) ori_flag = 1; while (1) //put ns in itor(buffer), put ns'a in iitor(ip) { while (1) { ret = find_record_with_ttl(ht, itor, td_len, NS, buffer, IP_DATA_LEN, NULL, hash); //ns do not if (ret > 0) break; if ((dbg--) == 0) //if mess buffer return -1; if (ori_flag) { diff_len = itor[0] + 1; itor = itor + diff_len; //parent, assert itor[1] < 64 if (itor[0] == 0) //root { if (root_flag == 0) { itor[1] = '\0'; root_flag = 1; td_len = 2; } else return -1; } else { td_len -= diff_len; } thash = 0; hash = &thash; } else { label_count++; if (label_count > mbuf->lowerdomain.label_count) return -1; if (label_count == mbuf->lowerdomain.label_count) // root { itor = mbuf->lowerdomain.label[label_count - 1] + mbuf->lowerdomain.label_len[label_count - 1]; itor[1] = '\0'; td_len = 2; thash = 0; hash = &thash; } else { itor = mbuf->lowerdomain.label[label_count]; td_len = mbuf->lowerdomain.label_len[label_count]; hash = &(mbuf->lowerdomain.hash[label_count]); } } } mv = (struct mvalue *) buffer; //ns record in buffer glue = itor; //data in td, real domain we get ns //key itor = buffer + sizeof(struct mvalue); //data //value ret = retrive_ip(mbuf, itor, mv->num, ip, ht, &first_query); if ((ret > 0)) { if ((ret < mv->num) && (mbuf->qns == 1)) { mbuf->qns = 0; for (i = 0; i < first_query; i++) { xlen = strlen((const char *)itor) + 1; itor = itor + xlen; } } else return 0; } if (is_glue(glue, itor) != 1) //domain and it's ns,should be use itor,not buffer + sizeof(struct mvalue) { if (!ori_flag) ori_flag = 1; { xlen = strlen((const char *)itor) + 1; //ns len if (xlen > (QBUFFER_SIZE - 1) || itor[0] == 0 || itor[0] > xlen) return -1; memcpy(mbuf->qbuffer, itor, xlen); mbuf->qbuffer_hash = 0; mbuf->qing = mbuf->qbuffer; mbuf->qhash = &(mbuf->qbuffer_hash); mbuf->qlen = xlen; hash = mbuf->qhash; td_len = mbuf->qlen; td = mbuf->qing; } itor = td; //itor point to key now } else { //qbuffer and qing need NO change if (ori_flag) { diff_len = glue[0] + 1; itor = glue + diff_len; //glue[0] is type,glue[1] is label length if (itor[0] == 0) //root return -1; td_len -= diff_len; thash = 0; hash = &thash; } else { label_count++; if (label_count >= mbuf->lowerdomain.label_count) // root return -1; itor = mbuf->lowerdomain.label[label_count]; td_len = mbuf->lowerdomain.label_len[label_count]; hash = &(mbuf->lowerdomain.hash[label_count]); } } mbuf->qname = Q_NS; if ((dbg--) == 0) return -1; } return 0; }
//First ensure the search name, if it has a cname, search the cname //If we find it in fwd table, return the ip length, it's > 0 //Here we dont care the cname in fwd table, if somebody want to do this //Add the main domain in fwd table int pre_find(mbuf_type *mbuf, struct htable *fwd, struct htable *ht, uchar * ip) { uchar *td, *itor = NULL/*, type*/; int xlen = 0, dbg = 100; // uchar *buffer[2000]; struct mvalue *mv = NULL; int td_len, new_td_len; hashval_t *hash, thash = 0; mbuf->qname = Q_DOMAIN; //default if (mbuf->hascname == 1) { mbuf->qing = mbuf->qbuffer; //latest cname td_len = mbuf->qlen; td = mbuf->qbuffer; mbuf->qhash = &(mbuf->qbuffer_hash); } else { td_len = mbuf->dlen; mbuf->qing = mbuf->td; mbuf->qlen = mbuf->dlen; td = mbuf->td; mbuf->qhash = &(mbuf->lowerdomain.hash[0]); } hash = mbuf->qhash; xlen = htable_find(fwd, td, td_len, A, ip, 1900, NULL, hash); //100 for struct mvalue if (xlen > 0) { ip = ip + xlen; mv = (struct mvalue *) ip; mv->num = 0; //tail 0 mv->ttl = 0; mv->hits = 0; mv->len = 0; return xlen; } else { uchar *new_td = mbuf->tdbuffer; if (mbuf->lowerdomain.label_count > 1) { new_td[0] = 1; new_td[1] = '*'; new_td_len = mbuf->lowerdomain.label_len[mbuf->lowerdomain.label_count - 2]; memcpy(new_td + 2, mbuf->lowerdomain.label[mbuf->lowerdomain.label_count - 2], new_td_len); thash = 0; int rlen = htable_find(fwd, new_td, new_td_len + 2, A, ip, 1900, NULL, &thash); if (rlen > 0) { ip = ip + rlen; mv = (struct mvalue *) ip; mv->num = 0; //tail 0 mv->ttl = 0; mv->hits = 0; mv->len = 0; return rlen; } } } if (mbuf->qtype == CNAME) //query cname return 0; //find nothing itor = mbuf->tempbuffer; while (1) //find cname { xlen = find_record_with_ttl(ht, td, td_len, CNAME, itor, 2000, NULL, hash); if (xlen > 0) { //if domain has a cname, put it in qo->qbuffer mbuf->qname = Q_CNAME; mbuf->hascname = 1; mv = (struct mvalue *) itor; itor = itor + sizeof(struct mvalue); if (mv->len > (QBUFFER_SIZE - 1)) return -1; memcpy(mbuf->qbuffer, itor, mv->len); mbuf->qing = mbuf->qbuffer; mbuf->qlen = td_len = mv->len; mbuf->qbuffer_hash = 0; hash = &(mbuf->qbuffer_hash); td = mbuf->qbuffer; } else break; if ((dbg--) == 0) return -1; } return 0; }
//ht,type,domain,dlen int find_addr(struct htable *fwd,struct htable *ht,struct qoutinfo *qo,uchar *ip) { int ret,xlen = 0,dbg = 100,iplen = IP_DATA_LEN; int first_query,i; struct mvalue *mv = NULL; uchar td[512] = {0},buffer[IP_DATA_LEN] = {0},*itor = NULL,*glue = NULL; if(qo->qtimes > (MAX_TRY_TIMES - 3)) { fill_extra_addr(qo,ip); return 0; } ret = pre_find(qo,fwd,ht,ip); if(ret > 0) //find fwd return 0; if(ret < 0) //error return ret; itor = td; //now we have domain or latest cname in qo->qing //point to qo->td or qo->qbuffer memcpy(td + 1,qo->qing,strlen(qo->qing) + 1); td[0] = NS; while(1) //put ns in itor(buffer), put ns'a in iitor(ip) { while(1) { ret = find_record_with_ttl(ht,itor,buffer,IP_DATA_LEN,NULL); //ns do not if(ret > 0) break; itor = itor + itor[1] + 1; //parent, assert itor[1] < 64 itor[0] = NS; if(itor[1] == 0) //root return -1; if((dbg --) == 0)//if mess buffer return -1; } mv = (struct mvalue*)buffer; //ns record in buffer glue = itor; //data in td, real domain we get ns //key itor = buffer + sizeof(struct mvalue); //data //value ret = retrive_ip(itor,mv->num,ip,ht,&first_query); if((ret > 0)) { if((ret < mv->num) && (qo->qns == 1)) { qo->qns = 0; for(i = 0;i < first_query;i ++) { xlen = strlen(itor) + 1; itor = itor + xlen; } xlen = strlen(itor) + 1; memcpy(qo->qbuffer,itor,xlen); qo->qing = qo->qbuffer; memcpy(td + 1,qo->qbuffer,xlen); } else return 0; } if(is_glue(glue,buffer + sizeof(struct mvalue)) != 1) //domain and it's ns { itor = buffer + sizeof(struct mvalue); xlen = strlen(itor) + 1;//ns len if(xlen > (QBUFFER_SIZE - 1)) return -1; memcpy(qo->qbuffer,itor,xlen); qo->qing = qo->qbuffer; memcpy(td + 1,qo->qbuffer,xlen); itor = td; //itor point to key now } else //qbuffer and qing need NO change itor = glue + glue[1] + 1; //glue[0] is type,glue[1] is label length itor[0] = NS; qo->qname = Q_NS; if((dbg --) == 0) return -1; } return 0; }