//databuffer format //type.mvalue.data.type.mvalue.data... int // write_back_to_client(uchar * td, enum rrtype otype, uint8_t level, ushort id, int dlen, write_back_to_client(mbuf_type *mbuf, uchar * fr, int vlen) { struct setheader sh = { 0 }; //data in dns header int main_val = 0, dnslen = 0; uchar *msg = mbuf->buf, type; //if bigger, use TCP uchar *from = fr, *to = msg; struct mvalue *mv = NULL; int jump = 0; uint16_t temp = 0; struct hlpc hlp[100]; //p domians to compression hlp[0].name = mbuf->td; hlp[0].off = sizeof(dnsheader); hlp[0].level = mbuf->lowerdomain.label_count; hlp[0].ref = -1; hlp[0].mt = 0; hlp[0].len = mbuf->dlen; if (mbuf->dlen == 2) // root jump = sizeof(dnsheader) + 1 + sizeof(qdns); else jump = sizeof(dnsheader) + mbuf->dlen + sizeof(qdns); to = to + jump; while (vlen > 1) //vlen include type.mvalue.data. { type = from[0]; mv = (struct mvalue *)(from + 1); to = fill_rrset_in_msg(hlp, from, to, &main_val, msg); if (to == NULL) return -1; // *to = 0; vlen = vlen - 1 - mv->len - sizeof(struct mvalue); sh.an += mv->num; from = from + mv->len + 1 + sizeof(struct mvalue); // type.mv.len. /** * if previous record is CNAME(query type can't be ANY, that we don't support now), * next A & AAAA & CNAME use previous domain name (cname name). * We duplicate here to make it possible to refer previous one. */ if (type == CNAME && vlen > 1 /*&& mbuf->qtype != ANY*/ && (from[0] == A || from[0] == AAAA || from[0] == CNAME)) { main_val++; hlp[main_val].name = hlp[main_val - 1].name; hlp[main_val].off = hlp[main_val - 1].off; hlp[main_val].level = hlp[main_val - 1].level; hlp[main_val].len = hlp[main_val - 1].len; hlp[main_val].ref = -1; hlp[main_val].mt = 0; } } sh.itor = msg; sh.dlen = (mbuf->dlen == 2) ? 1: (mbuf->dlen); sh.od = mbuf->td; sh.id = mbuf->id; sh.type = mbuf->qtype; fill_header_in_msg(&sh); dnslen = to - msg; mbuf->buflen = dnslen; mbuf->addr = &(mbuf->caddr); if (mbuf->socktype == UDP) { if (dnslen > MAX_UDP_SIZE) send_tc_to_client(mbuf); else udp_write_info(mbuf, 0); //ignore send error } else { temp = DNS_GET16(dnslen); memcpy(msg - 2, &temp, sizeof(uint16_t)); mbuf->buflen = dnslen + 2; mbuf->buf = msg - 2; tcp_write_info(mbuf, 0); } //////////////////////////////////////////////////////////// //key, val, vallen, ttl offset //if now + TTL_UPDATE > ttl //return /* ret = transfer_record_to_msg(msgto, td, msg + 2, dnslen, ttloff); */ /* if (ret < 0) */ /* return -1; */ return 0; }
//databuffer format //type.mvalue.data.type.mvalue.data... int // write_back_to_client(uchar * td, enum rrtype otype, uint8_t level, ushort id, int dlen, write_back_to_client(mbuf_type *mbuf, uchar * fr, int vlen) { struct setheader sh = { 0 }; //data in dns header int main_val = 0, dnslen = 0; uchar *msg = mbuf->buf, type; //if bigger, use TCP uchar *from = fr, *to = msg; struct mvalue *mv = NULL; int jump = 0; uint16_t temp = 0; struct hlpc hlp[100]; //p domians to compression hlp[0].name = mbuf->td; hlp[0].off = sizeof(dnsheader); hlp[0].level = mbuf->lowerdomain.label_count; hlp[0].ref = -1; hlp[0].mt = 0; hlp[0].len = mbuf->dlen; jump = sizeof(dnsheader) + mbuf->dlen + sizeof(qdns); to = to + jump; while (vlen > 1) //vlen include type.mvalue.data. { type = from[0]; mv = (struct mvalue *)(from + 1); to = fill_rrset_in_msg(hlp, from, to, main_val, msg); if (to == NULL) return -1; // *to = 0; vlen = vlen - 1 - mv->len - sizeof(struct mvalue); sh.an += mv->num; if (type == CNAME) //cname must be 1 main_val++; //no all rdata is the cname's from = from + mv->len + 1 + sizeof(struct mvalue); // type.mv.len. } sh.itor = msg; sh.dlen = mbuf->dlen; sh.od = mbuf->td; sh.id = mbuf->id; sh.type = mbuf->qtype; fill_header_in_msg(&sh); dnslen = to - msg; mbuf->buflen = dnslen; mbuf->addr = &(mbuf->caddr); if (mbuf->socktype == UDP) { if (dnslen > MAX_UDP_SIZE) send_tc_to_client(mbuf); else udp_write_info(mbuf, 0); //ignore send error } else { temp = DNS_GET16(dnslen); memcpy(msg - 2, &temp, sizeof(uint16_t)); mbuf->buflen = dnslen + 2; mbuf->buf = msg - 2; tcp_write_info(mbuf, 0); } //////////////////////////////////////////////////////////// //key, val, vallen, ttl offset //if now + TTL_UPDATE > ttl //return /* ret = transfer_record_to_msg(msgto, td, msg + 2, dnslen, ttloff); */ /* if (ret < 0) */ /* return -1; */ return 0; }