reverse dns for ipv6

pull/686/head
Jeff Becker 5 years ago
parent eb10638497
commit c60099002b
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -1,6 +1,7 @@
#define __USE_MINGW_ANSI_STDIO 1
#include <dns/name.hpp>
#include <net/net.hpp>
#include <net/ip.hpp>
#include <algorithm>
#include <sstream>
@ -76,13 +77,20 @@ namespace llarp
}
bool
DecodePTR(const Name_t& name, huint32_t& ip)
DecodePTR(const Name_t& name, huint128_t& ip)
{
auto pos = name.find(".in-addr.arpa");
bool isV6 = false;
auto pos = name.find(".in-addr.arpa");
if(pos == std::string::npos)
{
pos = name.find(".ip6.arpa");
isV6 = true;
}
if(pos == std::string::npos)
return false;
std::string sub = name.substr(0, pos + 1);
if(std::count(sub.begin(), sub.end(), '.') == 4)
std::string sub = name.substr(0, pos + 1);
const auto numdots = std::count(sub.begin(), sub.end(), '.');
if(numdots == 4 && !isV6)
{
uint8_t a, b, c, d;
pos = sub.find('.');
@ -96,7 +104,25 @@ namespace llarp
sub = sub.substr(pos + 1);
pos = sub.find('.');
a = atoi(sub.substr(0, pos).c_str());
ip = llarp::ipaddr_ipv4_bits(a, b, c, d);
ip = net::IPPacket::ExpandV4(llarp::ipaddr_ipv4_bits(a, b, c, d));
return true;
}
else if(numdots == 32 && isV6)
{
size_t idx = 0;
uint8_t lo, hi;
uint8_t* ptr = (uint8_t*)&ip.h;
while(idx < 16)
{
pos = sub.find('.');
lo = (*sub.substr(0, pos).c_str()) - 'a';
sub = sub.substr(pos + 1);
pos = sub.find('.');
hi = (*sub.substr(0, pos).c_str()) - 'a';
sub = sub.substr(pos + 1);
ptr[idx] = lo | (hi << 4);
++idx;
}
return true;
}
else

@ -21,7 +21,7 @@ namespace llarp
EncodeName(llarp_buffer_t* buf, const Name_t& name);
bool
DecodePTR(const Name_t& name, huint32_t& ip);
DecodePTR(const Name_t& name, huint128_t& ip);
} // namespace dns
} // namespace llarp

@ -127,7 +127,8 @@ namespace llarp
dst = net::IPPacket::TruncateV6(m_Parent->GetIfAddr());
else
dst = pkt.dstv4();
pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(m_IP)), xhtonl(dst));
pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(m_IP)),
xhtonl(dst));
}
else
{

@ -71,10 +71,10 @@ namespace llarp
// always hook ptr for ranges we own
if(msg.questions[0].qtype == dns::qTypePTR)
{
huint32_t ip;
huint128_t ip;
if(!dns::DecodePTR(msg.questions[0].qname, ip))
return false;
return m_OurRange.ContainsV4(ip);
return m_OurRange.Contains(ip);
}
else if(msg.questions[0].qtype == dns::qTypeA
|| msg.questions[0].qtype == dns::qTypeCNAME
@ -94,18 +94,17 @@ namespace llarp
{
if(msg.questions[0].qtype == dns::qTypePTR)
{
huint32_t ip;
huint128_t ip;
if(!dns::DecodePTR(msg.questions[0].qname, ip))
return false;
huint128_t ipv6 = net::IPPacket::ExpandV4(ip);
if(ipv6 == m_IfAddr)
if(ip == m_IfAddr)
{
RouterID us = GetRouter()->pubkey();
msg.AddAReply(us.ToString(), 300);
}
else
{
auto itr = m_IPToKey.find(ipv6);
auto itr = m_IPToKey.find(ip);
if(itr != m_IPToKey.end()
&& m_SNodeKeys.find(itr->second) != m_SNodeKeys.end())
{

@ -423,12 +423,20 @@ namespace llarp
}
else if(addr.FromString(qname, ".snode"))
{
dns::Message *replyMsg = new dns::Message(std::move(msg));
EnsurePathToSNode(
addr.as_array(), [=](const RouterID &, exit::BaseSession_ptr s) {
SendDNSReply(addr, s, replyMsg, reply, true, isV6);
});
return true;
if(isV4 && SupportsV6())
{
msg.hdr_fields |= dns::flags_QR | dns::flags_AA | dns::flags_RA;
}
else
{
dns::Message *replyMsg = new dns::Message(std::move(msg));
EnsurePathToSNode(addr.as_array(),
[=](const RouterID &, exit::BaseSession_ptr s) {
SendDNSReply(addr, s, replyMsg, reply, true,
isV6);
});
return true;
}
}
else
msg.AddNXReply();
@ -438,24 +446,22 @@ namespace llarp
else if(msg.questions[0].qtype == dns::qTypePTR)
{
// reverse dns
huint128_t ipv6 = {0};
huint32_t ip = {0};
huint128_t ip = {0};
if(!dns::DecodePTR(msg.questions[0].qname, ip))
{
msg.AddNXReply();
reply(msg);
return true;
}
ipv6 = net::IPPacket::ExpandV4(ip);
llarp::service::Address addr(
ObtainAddrForIP< llarp::service::Address >(ipv6, true));
ObtainAddrForIP< llarp::service::Address >(ip, true));
if(!addr.IsZero())
{
msg.AddAReply(addr.ToString(".snode"));
reply(msg);
return true;
}
addr = ObtainAddrForIP< llarp::service::Address >(ipv6, false);
addr = ObtainAddrForIP< llarp::service::Address >(ip, false);
if(!addr.IsZero())
{
msg.AddAReply(addr.ToString(".loki"));
@ -504,10 +510,10 @@ namespace llarp
// hook any ranges we own
if(msg.questions[0].qtype == llarp::dns::qTypePTR)
{
huint32_t ip = {0};
huint128_t ip = {0};
if(!dns::DecodePTR(msg.questions[0].qname, ip))
return false;
return m_OurRange.ContainsV4(ip);
return m_OurRange.Contains(ip);
}
}
return false;

@ -5,6 +5,7 @@
#include <dns/name.hpp>
#include <dns/rr.hpp>
#include <net/net.hpp>
#include <net/ip.hpp>
#include <util/buffer.hpp>
#include <algorithm>
@ -49,8 +50,8 @@ TEST_F(DNSLibTest, TestHasTLD)
TEST_F(DNSLibTest, TestPTR)
{
llarp::huint32_t ip = {0};
llarp::huint32_t expected = llarp::ipaddr_ipv4_bits(10, 10, 10, 1);
llarp::huint128_t ip = {0};
llarp::huint128_t expected = llarp::net::IPPacket::ExpandV4(llarp::ipaddr_ipv4_bits(10, 10, 10, 1));
ASSERT_TRUE(llarp::dns::DecodePTR("1.10.10.10.in-addr.arpa.", ip));
ASSERT_EQ(ip, expected);
}

Loading…
Cancel
Save