| | 36 | string simpleCompress(const string& label) |
| | 37 | { |
| | 38 | typedef vector<pair<unsigned int, unsigned int> > parts_t; |
| | 39 | parts_t parts; |
| | 40 | vstringtok(parts, label, "."); |
| | 41 | string ret; |
| | 42 | ret.reserve(label.size()+4); |
| | 43 | for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { |
| | 44 | ret.append(1, (char)(i->second - i->first)); |
| | 45 | ret.append(label.c_str() + i->first, i->second - i->first); |
| | 46 | } |
| | 47 | ret.append(1,0); |
| | 48 | return ret; |
| | 49 | } |
| | 50 | |
| | 51 | void simpleExpandTo(const string& label, unsigned int frompos, string& ret) |
| | 52 | { |
| | 53 | unsigned int labellen=0; |
| | 54 | while((labellen=label.at(frompos++))) { |
| | 55 | ret.append(label.c_str()+frompos, labellen); |
| | 56 | ret.append(1,'.'); |
| | 57 | frompos+=labellen; |
| | 58 | } |
| | 59 | } |
| | 60 | |
| 43 | | rr.content=regen->getZoneRepresentation(); |
| 44 | | rr.qtype=regen->d_qtype; |
| 45 | | |
| 46 | | rr.content.reserve(0); |
| 47 | | rr.qname.reserve(0); |
| | 65 | rr.qtype=qt; |
| | 66 | rr.qname=qname; |
| | 67 | |
| | 68 | if(rr.qtype.getCode()==QType::A) { |
| | 69 | uint32_t ip; |
| | 70 | memcpy((char*)&ip, serial.c_str(), 4); |
| | 71 | rr.content=U32ToIP(ntohl(ip)); |
| | 72 | } |
| | 73 | else if(rr.qtype.getCode()==QType::CNAME || rr.qtype.getCode()==QType::NS || rr.qtype.getCode()==QType::PTR) { |
| | 74 | unsigned int frompos=0; |
| | 75 | unsigned char labellen; |
| | 76 | |
| | 77 | while((labellen=serial.at(frompos++))) { |
| | 78 | if((labellen & 0xc0) == 0xc0) { |
| | 79 | string encoded=simpleCompress(qname); |
| | 80 | uint16_t offset=256*(labellen & ~0xc0) + (unsigned int)serial.at(frompos++) - sizeof(dnsheader)-5; |
| | 81 | |
| | 82 | simpleExpandTo(encoded, offset, rr.content); |
| | 83 | // cerr<<"Oops, fallback, content so far: '"<<rr.content<<"', offset: "<<offset<<", '"<<qname<<"', "<<qt.getName()<<"\n"; |
| | 84 | break; |
| | 85 | } |
| | 86 | rr.content.append(serial.c_str()+frompos, labellen); |
| | 87 | frompos+=labellen; |
| | 88 | rr.content.append(1,'.'); |
| | 89 | } |
| | 90 | } |
| | 91 | else { |
| | 92 | shared_ptr<DNSRecordContent> regen=DNSRecordContent::unserialize(qname,qt.getCode(), serial); |
| | 93 | rr.content=regen->getZoneRepresentation(); |
| | 94 | } |
| | 95 | |
| | 96 | // rr.content.reserve(0); |
| | 97 | // rr.qname.reserve(0); |
| 56 | | shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(type, 1, rr.content)); |
| 57 | | string ret=drc->serialize(rr.qname); |
| | 104 | |
| | 105 | if(type==QType::A) { |
| | 106 | uint32_t ip; |
| | 107 | IpToU32(rr.content, &ip); |
| | 108 | return string((char*)&ip, 4); |
| | 109 | } |
| | 110 | else if(type==QType::NS) { |
| | 111 | NSRecordContent ar(rr.content); |
| | 112 | return ar.serialize(rr.qname); |
| | 113 | } |
| | 114 | else if(type==QType::CNAME) { |
| | 115 | CNAMERecordContent ar(rr.content); |
| | 116 | return ar.serialize(rr.qname); |
| | 117 | } |
| | 118 | else { |
| | 119 | string ret; |
| | 120 | shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(type, 1, rr.content)); |
| | 121 | ret=drc->serialize(rr.qname); |