Skip to content

Commit

Permalink
Read and Write TXT records based on length only.
Browse files Browse the repository at this point in the history
TXT records should not be encoded / decoded as a domain name, they are
not name compressed as domain names and do not end with a 0 length. Also
do the same for any other unsupported record type as well so that they
pass the request and response without dropping them.

Conflicts:
	src/dns/bind/bind_util.cc
	src/dns/test/dns_bind_test.cc

Change-Id: I37f85727a89937c6f33026e90029e537c5d90a32
closes-bug: #1583053
(cherry picked from commit 51802ea)
  • Loading branch information
haripk committed May 21, 2016
1 parent 0b3eec0 commit fb6408c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 9 deletions.
39 changes: 31 additions & 8 deletions src/dns/bind/bind_util.cc
Expand Up @@ -72,7 +72,7 @@ uint16_t BindUtil::DnsClass(const std::string &cl) {
std::string BindUtil::DnsClass(uint16_t cl) {
DnsTypeNumIter iter = g_dns_class_num_map.find(cl);
if (iter == g_dns_class_num_map.end())
return "";
return integerToString(cl);
return iter->second;
}

Expand All @@ -86,7 +86,7 @@ uint16_t BindUtil::DnsType(const std::string &tp) {
std::string BindUtil::DnsType(uint16_t tp) {
DnsTypeNumIter iter = g_dns_type_num_map.find(tp);
if (iter == g_dns_type_num_map.end())
return "";
return integerToString(tp);
return iter->second;
}

Expand Down Expand Up @@ -179,8 +179,7 @@ uint8_t *BindUtil::AddData(uint8_t *ptr, const DnsItem &item,
length += 2 + 20;
} else if(item.type == DNS_PTR_RECORD ||
item.type == DNS_CNAME_RECORD ||
item.type == DNS_NS_RECORD ||
item.type == DNS_TXT_RECORD) {
item.type == DNS_NS_RECORD) {
uint16_t data_len = DataLength(item.data_plen, item.data_offset,
item.data.size());
ptr = WriteShort(ptr, data_len);
Expand All @@ -205,8 +204,19 @@ uint8_t *BindUtil::AddData(uint8_t *ptr, const DnsItem &item,
item.srv.hn_offset, length);
length += 2 + 6;
} else {
DNS_BIND_TRACE(DnsBindError,
"Unsupported record type in response : " << item.type);
// TXT and other record types are handled here.
// TODO: In case a record type has domain name and name is compressed
// in the message that is being read, it may lead to problem if the
// offset in the message we send doesnt match with the offset in the
// message that is received. Each such message has to be handled
// as a different case here.
uint16_t size = item.data.size();
ptr = WriteShort(ptr, size);
if (size) {
memcpy(ptr, item.data.c_str(), size);
ptr += size;
}
length += 2 + size;
}

return ptr;
Expand Down Expand Up @@ -327,8 +337,7 @@ bool BindUtil::ReadData(uint8_t *dns, uint16_t dnslen, int *remlen,
return ReadWord(dns, dnslen, remlen, item.soa.ttl);
} else if(item.type == DNS_PTR_RECORD ||
item.type == DNS_CNAME_RECORD ||
item.type == DNS_NS_RECORD ||
item.type == DNS_TXT_RECORD) {
item.type == DNS_NS_RECORD) {
return ReadName(dns, dnslen, remlen, item.data, item.data_plen, item.data_offset);
} else if(item.type == DNS_MX_RECORD) {
if (ReadShort(dns, dnslen, remlen, item.priority) == false)
Expand All @@ -343,6 +352,20 @@ bool BindUtil::ReadData(uint8_t *dns, uint16_t dnslen, int *remlen,
return false;
return ReadName(dns, dnslen, remlen, item.srv.hostname,
item.srv.hn_plen, item.srv.hn_offset);
} else {
// TXT and other record types are handled here.
// TODO: In case a record type has domain name and name is compressed
// in the message that is being read, it may lead to problem if the
// offset in the message we send doesnt match with the offset in the
// message that is received. Each such message has to be handled
// as a different case here.
if (*remlen < length) {
return false;
}
uint8_t *ptr = dns + (dnslen - *remlen);
item.data.assign((const char *)ptr, length);
*remlen -= length;
return true;
}

DNS_BIND_TRACE(DnsBindError,
Expand Down
35 changes: 34 additions & 1 deletion src/dns/test/dns_bind_test.cc
Expand Up @@ -802,7 +802,7 @@ TEST_F(DnsBindTest, ReorderedExternalReverseResolutionDisabled) {

TEST_F(DnsBindTest, DnsClassTest) {
std::string cl = BindUtil::DnsClass(4);
EXPECT_TRUE(cl == "");
EXPECT_TRUE(cl == "4");
}

#define MAX_ITEMS 3
Expand Down Expand Up @@ -1098,7 +1098,40 @@ TEST_F(DnsBindTest, DnsResponseSRVParse) {
EXPECT_TRUE(ans == ans_in);
}

// Check the parsing of a TXT record
TEST_F(DnsBindTest, DnsResponseTxtParse) {
uint8_t buf[1024];
DnsItems ans_in;
DnsItem item;
item.eclass = DNS_CLASS_IN;
item.type = DNS_TXT_RECORD;
item.ttl = 100;
item.name = "google.com";
item.data = "v=spf1 include:_spf.google.com ~all";
ans_in.push_back(item);

dnshdr *dns = (dnshdr *) buf;
BindUtil::BuildDnsHeader(dns, 0x0102, DNS_QUERY_RESPONSE, DNS_OPCODE_QUERY,
0, 0, 0, 0);
dns->ques_rrcount = htons(1);
dns->ans_rrcount = htons(1);
dns->auth_rrcount = 0;
dns->add_rrcount = 0;

uint16_t len = sizeof(dnshdr);
uint8_t *ptr = (uint8_t *) (dns + 1);
ptr = BindUtil::AddQuestionSection(ptr, "google.com",
DNS_TXT_RECORD, DNS_CLASS_IN, len);
for (DnsItems::iterator it = ans_in.begin(); it != ans_in.end(); it++)
ptr = BindUtil::AddAnswerSection(ptr, *it, len);

uint16_t xid;
dns_flags flags;
DnsItems ques, ans, auth, add;
EXPECT_TRUE(BindUtil::ParseDnsResponse(buf, len, xid, flags,
ques, ans, auth, add));
EXPECT_TRUE(ans == ans_in);
}

} // namespace

Expand Down

0 comments on commit fb6408c

Please sign in to comment.