if (!subnet.empty() || addECS) {
EDNSSubnetOpts opt;
- opt.source = Netmask(subnet.empty() ? "0.0.0.0/32" : subnet);
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ opt.setSource(Netmask(subnet.empty() ? "0.0.0.0/32" : subnet));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
}
if (!ednsOptions.empty() || (packetWriter.getHeader()->id % 2) != 0) {
EDNSSubnetOpts eso;
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- if (getEDNSSubnetOptsFromString(reinterpret_cast<const char*>(&packet.at(optRDPosition + ecsOptionStartPosition + (EDNS_OPTION_CODE_SIZE + EDNS_OPTION_LENGTH_SIZE))), ecsOptionSize - (EDNS_OPTION_CODE_SIZE + EDNS_OPTION_LENGTH_SIZE), &eso)) {
- subnet = eso.source;
+ if (EDNSSubnetOpts::getFromString(reinterpret_cast<const char*>(&packet.at(optRDPosition + ecsOptionStartPosition + (EDNS_OPTION_CODE_SIZE + EDNS_OPTION_LENGTH_SIZE))), ecsOptionSize - (EDNS_OPTION_CODE_SIZE + EDNS_OPTION_LENGTH_SIZE), &eso)) {
+ subnet = eso.getSource();
return true;
}
}
{
Netmask sourceNetmask(source, ECSPrefixLength);
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = sourceNetmask;
- string payload = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(sourceNetmask);
+ string payload = ecsOpts.makeOptString();
generateEDNSOption(EDNSOptionCode::ECS, payload, res);
}
GenericDNSPacketWriter<PacketBuffer> packetWriter(query, name, QType::A, QClass::IN, 0);
packetWriter.getHeader()->rd = 1;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOption = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOption = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOption);
packetWriter.addOpt(512, 0, 0, opts);
GenericDNSPacketWriter<PacketBuffer> packetWriter(query, ids.qname, QType::A, QClass::IN, 0);
packetWriter.getHeader()->rd = 1;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOption = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOption = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOption);
packetWriter.addOpt(512, 0, 0, opts);
GenericDNSPacketWriter<PacketBuffer> packetWriter(query, name, QType::A, QClass::IN, 0);
packetWriter.getHeader()->rd = 1;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, 32);
- string origECSOption = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, 32));
+ string origECSOption = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOption);
packetWriter.addOpt(512, 0, 0, opts);
EDNSSubnetOpts ecsOpts;
// smaller (less specific so less bits) option
static_assert(8 < ECSSourcePrefixV4, "The ECS scope should be smaller");
- ecsOpts.source = Netmask(origRemote, 8);
- string origECSOption = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, 8));
+ string origECSOption = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOption);
packetWriter.addOpt(512, 0, 0, opts);
GenericDNSPacketWriter<PacketBuffer> packetWriter(query, name, QType::A, QClass::IN, 0);
packetWriter.getHeader()->rd = 1;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, 8);
- string origECSOption = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, 8));
+ string origECSOption = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOption);
packetWriter.addOpt(512, 0, 0, opts);
packetWriter.startRecord(DNSName("powerdns.com."), QType::A, 0, QClass::IN, DNSResourceRecord::ANSWER, true);
packetWriter.commit();
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, 8);
- string origECSOption = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, 8));
+ string origECSOption = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOption);
packetWriter.addOpt(512, 0, 0, opts);
packetWriter.startRecord(DNSName("powerdns.com."), QType::A, 0, QClass::IN, DNSResourceRecord::AUTHORITY, true);
packetWriter.commit();
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, 8);
- string origECSOption = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, 8));
+ string origECSOption = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOption);
packetWriter.addOpt(512, 0, 0, opts);
GenericDNSPacketWriter<PacketBuffer> packetWriter(query, name, QType::A, QClass::IN, 0);
packetWriter.getHeader()->rd = 1;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, 8);
- string origECSOption = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, 8));
+ string origECSOption = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOption);
packetWriter.startRecord(DNSName("additional"), QType::A, 0, QClass::IN, DNSResourceRecord::ADDITIONAL, false);
packetWriter.commit();
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOptionStr);
packetWriter.addOpt(512, 0, 0, opts);
packetWriter.commit();
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV6);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV6));
+ string origECSOptionStr = ecsOpts.makeOptString();
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
string cookiesOptionStr = cookiesOpt.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
packetWriter.commit();
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
-
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
string cookiesOptionStr1 = cookiesOpt.makeOptString();
string cookiesOptionStr2 = cookiesOpt.makeOptString();
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
string cookiesOptionStr = cookiesOpt.makeOptString();
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::COOKIE, cookiesOptionStr);
opts.emplace_back(EDNSOptionCode::ECS, origECSOptionStr);
packetWriter.xfr32BitInt(0x01020304);
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOptionStr);
packetWriter.addOpt(512, 0, 0, opts);
packetWriter.xfr32BitInt(0x01020304);
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
string cookiesOptionStr = cookiesOpt.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
packetWriter.xfr32BitInt(0x01020304);
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
string cookiesOptionStr1 = cookiesOpt.makeOptString();
string cookiesOptionStr2 = cookiesOpt.makeOptString();
packetWriter.xfr32BitInt(0x01020304);
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(origRemote, ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
string cookiesOptionStr = cookiesOpt.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
uint16_t qtype = QType::A;
uint16_t qclass = QClass::IN;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
string cookiesOptionStr = cookiesOpt.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
uint16_t zValue = 0;
uint16_t udpPayloadSize = 0;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4);
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4));
+ string origECSOptionStr = ecsOpts.makeOptString();
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
string cookiesOptionStr = cookiesOpt.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
const uint16_t qtype = QType::A;
const uint16_t qclass = QClass::IN;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4);
- const string ecsOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4));
+ const string ecsOptionStr = ecsOpts.makeOptString();
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, ecsOptionStr);
const ComboAddress rem("127.0.0.1");
const uint16_t qtype = QType::A;
const uint16_t qclass = QClass::IN;
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4);
- const string ecsOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4));
+ const string ecsOptionStr = ecsOpts.makeOptString();
const size_t sizeOfECSContent = ecsOptionStr.size();
const size_t sizeOfECSOption = /* option code */ 2 + /* option length */ 2 + sizeOfECSContent;
EDNSCookiesOpt cookiesOpt("deadbeefdeadbeef");
.extraText = "Synthesized from aggressive NSEC cache"};
opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede));
EDNSSubnetOpts ecsOpt;
- ecsOpt.source = Netmask(ComboAddress("192.0.2.1"), 24U);
- const auto ecsOptStr = makeEDNSSubnetOptsString(ecsOpt);
+ ecsOpt.setSource(Netmask(ComboAddress("192.0.2.1"), 24U));
+ const auto ecsOptStr = ecsOpt.makeOptString();
opts.emplace_back(EDNSOptionCode::ECS, ecsOptStr);
pw.addOpt(512, 0, 0, opts);
pw.commit();
pw.getHeader()->rd = 1;
GenericDNSPacketWriter<PacketBuffer>::optvect_t opts;
EDNSSubnetOpts ecsOpt;
- ecsOpt.source = Netmask(ComboAddress("192.0.2.1"), 24U);
- const auto ecsOptStr = makeEDNSSubnetOptsString(ecsOpt);
+ ecsOpt.setSource(Netmask(ComboAddress("192.0.2.1"), 24U));
+ const auto ecsOptStr = ecsOpt.makeOptString();
opts.emplace_back(EDNSOptionCode::ECS, ecsOptStr);
const EDNSExtendedError ede{
.infoCode = static_cast<uint16_t>(EDNSExtendedError::code::Synthesized),
pwQ.getHeader()->id = qid;
GenericDNSPacketWriter<PacketBuffer>::optvect_t ednsOptions;
EDNSSubnetOpts opt;
- opt.source = Netmask("10.0.59.220/32");
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ opt.setSource(Netmask("10.0.59.220/32"));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
pwQ.addOpt(512, 0, 0, ednsOptions);
pwQ.commit();
bool found = localCache.get(dnsQuestion, 0, &key, subnetOut, dnssecOK, receivedOverUDP);
BOOST_CHECK_EQUAL(found, false);
BOOST_REQUIRE(subnetOut);
- BOOST_CHECK_EQUAL(subnetOut->toString(), opt.source.toString());
+ BOOST_CHECK_EQUAL(subnetOut->toString(), opt.getSource().toString());
PacketBuffer response;
GenericDNSPacketWriter<PacketBuffer> pwR(response, ids.qname, ids.qtype, QClass::IN, 0);
found = localCache.get(dnsQuestion, 0, &key, subnetOut, dnssecOK, receivedOverUDP);
BOOST_CHECK_EQUAL(found, true);
BOOST_REQUIRE(subnetOut);
- BOOST_CHECK_EQUAL(subnetOut->toString(), opt.source.toString());
+ BOOST_CHECK_EQUAL(subnetOut->toString(), opt.getSource().toString());
}
/* now lookup for the same query with a different ECS value,
pwQ.getHeader()->id = qid;
GenericDNSPacketWriter<PacketBuffer>::optvect_t ednsOptions;
EDNSSubnetOpts opt;
- opt.source = Netmask("10.0.167.48/32");
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ opt.setSource(Netmask("10.0.167.48/32"));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
pwQ.addOpt(512, 0, 0, ednsOptions);
pwQ.commit();
BOOST_CHECK_EQUAL(found, false);
BOOST_CHECK_EQUAL(secondKey, key);
BOOST_REQUIRE(subnetOut);
- BOOST_CHECK_EQUAL(subnetOut->toString(), opt.source.toString());
+ BOOST_CHECK_EQUAL(subnetOut->toString(), opt.getSource().toString());
BOOST_CHECK_EQUAL(localCache.getLookupCollisions(), 1U);
}
{
// this is an upper bound
optsize += EDNS_OPTION_CODE_SIZE + EDNS_OPTION_LENGTH_SIZE + 2 + 1 + 1; // code+len+family+src len+scope len
- optsize += d_eso.source.isIPv4() ? 4 : 16;
+ optsize += d_eso.getSource().isIPv4() ? 4 : 16;
}
if (d_haveednscookie) {
if(d_haveednssubnet) {
EDNSSubnetOpts eso = d_eso;
// use the scopeMask from the resolver, if it is greater - issue #5469
- maxScopeMask = max(maxScopeMask, eso.scope.getBits());
- eso.scope = Netmask(eso.source.getNetwork(), maxScopeMask);
+ maxScopeMask = max(maxScopeMask, eso.getScopePrefixLength());
+ eso.setScopePrefixLength(maxScopeMask);
- string opt = makeEDNSSubnetOptsString(eso);
+ string opt = eso.makeOptString();
opts.emplace_back(8, opt); // 'EDNS SUBNET'
}
d_wantsnsid=true;
}
else if(s_doEDNSSubnetProcessing && (option.first == EDNSOptionCode::ECS)) { // 'EDNS SUBNET'
- if(getEDNSSubnetOptsFromString(option.second, &d_eso)) {
+ if (EDNSSubnetOpts::getFromString(option.second, &d_eso)) {
//cerr<<"Parsed, source: "<<d_eso.source.toString()<<", scope: "<<d_eso.scope.toString()<<", family = "<<d_eso.scope.getNetwork().sin4.sin_family<<endl;
d_haveednssubnet=true;
}
}
void DNSPacket::setRealRemote(const Netmask& netmask) {
- d_eso.source = netmask;
+ d_eso.setSource(netmask);
d_haveednssubnet = true;
}
Netmask DNSPacket::getRealRemote() const
{
- return d_haveednssubnet ? d_eso.source : Netmask{getInnerRemote()};
+ return d_haveednssubnet ? d_eso.getSource() : Netmask{getInnerRemote()};
}
void DNSPacket::setSocket(Utility::sock_t sock)
string ECSOptionStr;
if (reply->hasEDNSSubnet()) {
- DLOG(g_log << "dnsproxy::completePacket: Parsed edns source: " << reply->d_eso.source.toString() << ", scope: " << reply->d_eso.scope.toString() << ", family = " << reply->d_eso.scope.getNetwork().sin4.sin_family << endl);
- ECSOptionStr = makeEDNSSubnetOptsString(reply->d_eso);
+ DLOG(g_log << "dnsproxy::completePacket: Parsed edns source: " << reply->d_eso.getSource().toString() << ", scope: " << Netmask(reply->d_eso.getSource().getNetwork(), reply->d_eso.getScopePrefixLength()).toString() << ", family = " << std::to_string(reply->d_eso.getFamily()) << endl);
+ ECSOptionStr = reply->d_eso.makeOptString();
DLOG(g_log << "from dnsproxy::completePacket: Creating ECS option string " << makeHexDump(ECSOptionStr) << endl);
}
MOADNSParser mdp(false, packet.getString());
// update the EDNS options with info from the resolver - issue #5469
// note that this relies on the ECS string encoder to use the source network, and only take the prefix length from scope
- iter->second.complete->d_eso.scope = packet.d_eso.scope;
- DLOG(g_log << "from dnsproxy::mainLoop: updated EDNS options from resolver EDNS source: " << iter->second.complete->d_eso.source.toString() << " EDNS scope: " << iter->second.complete->d_eso.scope.toString() << endl);
+ iter->second.complete->d_eso.setScopePrefixLength(packet.d_eso.getScopePrefixLength());
+ DLOG(g_log << "from dnsproxy::mainLoop: updated EDNS options from resolver EDNS source: " << iter->second.complete->d_eso.getSource().toString() << " EDNS scope: " << Netmask(iter->second.complete->d_eso.getSource().getNetwork(), iter->second.complete->d_eso.getScopePrefixLength()).toString() << endl);
if (mdp.d_header.rcode == RCode::NoError) {
for (const auto& answer : mdp.d_answers) {
struct dnsheader* dh = (struct dnsheader*) packet;
EDNSSubnetOpts eso;
- if(stamp < 0)
- eso.source = Netmask(remote);
+ if(stamp < 0) {
+ eso.setSource(Netmask(remote));
+ }
else {
ComboAddress stamped(remote);
*((char*)&stamped.sin4.sin_addr.s_addr)=stamp;
- eso.source = Netmask(stamped);
+ eso.setSource(Netmask(stamped));
}
- string optRData=makeEDNSSubnetOptsString(eso);
+ string optRData = eso.makeOptString();
string record;
generateEDNSOption(EDNSOptionCode::ECS, optRData, record);
generateOptRR(record, EDNSRR);
struct EDNSSubnetOptsWire
{
uint16_t family;
- uint8_t sourceMask;
- uint8_t scopeMask;
+ uint8_t sourcePrefixLength;
+ uint8_t scopePrefixLength;
} GCCPACKATTRIBUTE; // BRRRRR
}
-bool getEDNSSubnetOptsFromString(const std::string& options, EDNSSubnetOpts* eso)
+bool EDNSSubnetOpts::getFromString(const std::string& options, EDNSSubnetOpts* eso)
{
- return getEDNSSubnetOptsFromString(options.c_str(), options.length(), eso);
+ return getFromString(options.c_str(), options.length(), eso);
}
-bool getEDNSSubnetOptsFromString(const char* options, unsigned int len, EDNSSubnetOpts* eso)
+bool EDNSSubnetOpts::getFromString(const char* options, unsigned int len, EDNSSubnetOpts* eso)
{
EDNSSubnetOptsWire esow{};
static_assert(sizeof(esow) == 4, "sizeof(EDNSSubnetOptsWire) must be 4 bytes");
esow.family = ntohs(esow.family);
ComboAddress address;
- unsigned int octetsin = esow.sourceMask > 0 ? (((esow.sourceMask - 1) >> 3) + 1) : 0;
+ unsigned int octetsin = esow.sourcePrefixLength > 0 ? (((esow.sourcePrefixLength - 1) >> 3) + 1) : 0;
if (esow.family == 1) {
if (len != sizeof(esow) + octetsin) {
else {
return false;
}
- eso->source = Netmask(address, esow.sourceMask);
- /* 'address' has more bits set (potentially) than scopeMask. This leads to odd looking netmasks that promise
- more precision than they have. For this reason we truncate the address to scopeMask bits */
+ eso->source = Netmask(address, esow.sourcePrefixLength);
+ /* 'address' has more bits set (potentially) than scopePrefixLength. This leads to odd looking netmasks that promise
+ more precision than they have. For this reason we truncate the address to scopePrefixLength bits */
- address.truncate(esow.scopeMask); // truncate will not throw for odd scopeMasks
- eso->scope = Netmask(address, esow.scopeMask);
+ address.truncate(esow.scopePrefixLength); // truncate will not throw for odd scopePrefixLengths
+ eso->scopeBits = esow.scopePrefixLength;
return true;
}
-std::string makeEDNSSubnetOptsString(const EDNSSubnetOpts& eso)
+std::string EDNSSubnetOpts::makeOptString() const
{
std::string ret;
EDNSSubnetOptsWire esow{};
- uint16_t family = htons(eso.source.getNetwork().sin4.sin_family == AF_INET ? 1 : 2);
+ uint16_t family = htons(source.getNetwork().sin4.sin_family == AF_INET ? 1 : 2);
esow.family = family;
- esow.sourceMask = eso.source.getBits();
- esow.scopeMask = eso.scope.getBits();
+ esow.sourcePrefixLength = source.getBits();
+ esow.scopePrefixLength = scopeBits;
// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
ret.assign(reinterpret_cast<const char*>(&esow), sizeof(esow));
- int octetsout = ((esow.sourceMask - 1) >> 3) + 1;
+ int octetsout = ((esow.sourcePrefixLength - 1) >> 3) + 1;
- ComboAddress src = eso.source.getNetwork();
- src.truncate(esow.sourceMask);
+ ComboAddress src = source.getNetwork();
+ src.truncate(esow.sourcePrefixLength);
if (family == htons(1)) {
ret.append(reinterpret_cast<const char*>(&src.sin4.sin_addr.s_addr), octetsout);
#include "iputils.hh"
-struct EDNSSubnetOpts
+class EDNSSubnetOpts
{
+public:
+ void setSource(const Netmask& netmask)
+ {
+ source = netmask;
+ }
+ [[nodiscard]] const Netmask& getSource() const
+ {
+ return source;
+ }
+ [[nodiscard]] uint8_t getFamily() const
+ {
+ return source.getNetwork().sin4.sin_family;
+ }
+ [[nodiscard]] uint8_t getSourcePrefixLength() const
+ {
+ return source.getBits();
+ }
+ void setScopePrefixLength(uint8_t scope)
+ {
+ scopeBits = scope;
+ }
+ [[nodiscard]] uint8_t getScopePrefixLength() const
+ {
+ return scopeBits;
+ }
+ [[nodiscard]] std::string makeOptString() const;
+ static bool getFromString(const std::string& options, EDNSSubnetOpts* eso);
+ static bool getFromString(const char* options, unsigned int len, EDNSSubnetOpts* eso);
+
+private:
Netmask source;
- Netmask scope;
+ uint8_t scopeBits{};
};
-
-bool getEDNSSubnetOptsFromString(const std::string& options, EDNSSubnetOpts* eso);
-bool getEDNSSubnetOptsFromString(const char* options, unsigned int len, EDNSSubnetOpts* eso);
-std::string makeEDNSSubnetOptsString(const EDNSSubnetOpts& eso);
for (const auto& option : *ednsOptions) {
if (option.first == EDNSOptionCode::ECS) {
EDNSSubnetOpts eso;
- if (getEDNSSubnetOptsFromString(option.second, &eso)) {
- return eso.source;
+ if (EDNSSubnetOpts::getFromString(option.second, &eso)) {
+ return eso.getSource();
}
break;
}
if (EDNS0Level > 0) {
DNSPacketWriter::optvect_t opts;
if (srcmask) {
- EDNSSubnetOpts eo;
- eo.source = *srcmask;
+ EDNSSubnetOpts subnetOpts;
+ subnetOpts.setSource(*srcmask);
outgoingECSBits = srcmask->getBits();
outgoingECSAddr = srcmask->getNetwork();
- opts.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(eo));
+ opts.emplace_back(EDNSOptionCode::ECS, subnetOpts.makeOptString());
weWantEDNSSubnet = true;
}
for (const auto& opt : edo.d_options) {
if (opt.first == EDNSOptionCode::ECS) {
EDNSSubnetOpts reso;
- if (getEDNSSubnetOptsFromString(opt.second, &reso)) {
+ if (EDNSSubnetOpts::getFromString(opt.second, &reso)) {
/* rfc7871 states that 0 "indicate[s] that the answer is suitable for all addresses in FAMILY",
so we might want to still pass the information along to be able to differentiate between
IPv4 and IPv6. Still I'm pretty sure it doesn't matter in real life, so let's not duplicate
entries in our cache. */
- if (reso.scope.getBits()) {
- uint8_t bits = std::min(reso.scope.getBits(), outgoingECSBits);
+ if (reso.getScopePrefixLength() != 0) {
+ uint8_t bits = std::min(reso.getScopePrefixLength(), outgoingECSBits);
outgoingECSAddr.truncate(bits);
srcmask = Netmask(outgoingECSAddr, bits);
}
for (const auto& option : edo.d_options) {
if (option.first == EDNSOptionCode::ECS && g_useIncomingECS && !comboWriter->d_ecsParsed) {
- comboWriter->d_ecsFound = getEDNSSubnetOptsFromString(option.second, &comboWriter->d_ednssubnet);
+ comboWriter->d_ecsFound = EDNSSubnetOpts::getFromString(option.second, &comboWriter->d_ednssubnet);
}
else if (option.first == EDNSOptionCode::NSID) {
const static string mode_server_id = ::arg()["server-id"];
}
// lookup failing cannot happen as dc->d_source != dc->d_mappedSource
}
- resolver.setQuerySource(useMapped ? comboWriter->d_mappedSource : comboWriter->d_source, g_useIncomingECS && !comboWriter->d_ednssubnet.source.empty() ? boost::optional<const EDNSSubnetOpts&>(comboWriter->d_ednssubnet) : boost::none);
+ resolver.setQuerySource(useMapped ? comboWriter->d_mappedSource : comboWriter->d_source, g_useIncomingECS && !comboWriter->d_ednssubnet.getSource().empty() ? boost::optional<const EDNSSubnetOpts&>(comboWriter->d_ednssubnet) : boost::none);
resolver.setQueryReceivedOverTCP(comboWriter->d_tcp);
"qtype", Logging::Loggable(QType(comboWriter->d_mdp.d_qtype)),
"remote", Logging::Loggable(comboWriter->getRemote()),
"proto", Logging::Loggable(comboWriter->d_tcp ? "tcp" : "udp"),
- "ecs", Logging::Loggable(comboWriter->d_ednssubnet.source.empty() ? "" : comboWriter->d_ednssubnet.source.toString()),
+ "ecs", Logging::Loggable(comboWriter->d_ednssubnet.getSource().empty() ? "" : comboWriter->d_ednssubnet.getSource().toString()),
"mtid", Logging::Loggable(g_multiTasker->getTid()));
RunningResolveGuard tcpGuard(comboWriter);
if (!g_slogStructured) {
g_log << Logger::Warning << RecThreadInfo::id() << " [" << g_multiTasker->getTid() << "/" << g_multiTasker->numProcesses() << "] " << (comboWriter->d_tcp ? "TCP " : "") << "question for '" << comboWriter->d_mdp.d_qname << "|"
<< QType(comboWriter->d_mdp.d_qtype) << "' from " << comboWriter->getRemote();
- if (!comboWriter->d_ednssubnet.source.empty()) {
- g_log << " (ecs " << comboWriter->d_ednssubnet.source.toString() << ")";
+ if (!comboWriter->d_ednssubnet.getSource().empty()) {
+ g_log << " (ecs " << comboWriter->d_ednssubnet.getSource().toString() << ")";
}
g_log << endl;
}
if (g_useIncomingECS && comboWriter->d_ecsFound && !resolver.wasVariable() && !variableAnswer) {
EDNSSubnetOpts ednsOptions;
- ednsOptions.source = comboWriter->d_ednssubnet.source;
+ ednsOptions.setSource(comboWriter->d_ednssubnet.getSource());
ComboAddress sourceAddr;
sourceAddr.reset();
- sourceAddr.sin4.sin_family = ednsOptions.source.getNetwork().sin4.sin_family;
- ednsOptions.scope = Netmask(sourceAddr, 0);
- auto ecsPayload = makeEDNSSubnetOptsString(ednsOptions);
+ sourceAddr.sin4.sin_family = ednsOptions.getFamily();
+ ednsOptions.setScopePrefixLength(0);
+ auto ecsPayload = ednsOptions.makeOptString();
// if we don't have enough space available let's just not set that scope of zero,
// it will prevent some caching, mostly from dnsdist, but that's fine
pbMessage.setId(comboWriter->d_mdp.d_header.id);
pbMessage.setTime();
- pbMessage.setEDNSSubnet(comboWriter->d_ednssubnet.source, comboWriter->d_ednssubnet.source.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6);
+ pbMessage.setEDNSSubnet(comboWriter->d_ednssubnet.getSource(), comboWriter->d_ednssubnet.getSource().isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6);
pbMessage.setRequestorId(dnsQuestion.requestorId);
pbMessage.setDeviceId(dnsQuestion.deviceId);
pbMessage.setDeviceName(dnsQuestion.deviceName);
int res = getEDNSOption(reinterpret_cast<const char*>(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + sizeof(drh->d_clen), EDNSOptionCode::ECS, &ecsStartPosition, &ecsLen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
if (res == 0 && ecsLen > 4) {
EDNSSubnetOpts eso;
- if (getEDNSSubnetOptsFromString(&question.at(pos - sizeof(drh->d_clen) + ecsStartPosition + 4), ecsLen - 4, &eso)) {
+ if (EDNSSubnetOpts::getFromString(&question.at(pos - sizeof(drh->d_clen) + ecsStartPosition + 4), ecsLen - 4, &eso)) {
*ednssubnet = eso;
foundECS = true;
}
const auto& iter = options->find(EDNSOptionCode::ECS);
if (iter != options->end() && !iter->second.values.empty() && iter->second.values.at(0).content != nullptr && iter->second.values.at(0).size > 0) {
EDNSSubnetOpts eso;
- if (getEDNSSubnetOptsFromString(iter->second.values.at(0).content, iter->second.values.at(0).size, &eso)) {
+ if (EDNSSubnetOpts::getFromString(iter->second.values.at(0).content, iter->second.values.at(0).size, &eso)) {
*ednssubnet = eso;
foundECS = true;
}
if (t_pdl) {
try {
if (t_pdl->hasGettagFFIFunc()) {
- RecursorLua4::FFIParams params(qname, qtype, destaddr, fromaddr, destination, source, ednssubnet.source, data, policyTags, records, ednsOptions, proxyProtocolValues, requestorId, deviceId, deviceName, routingTag, rcode, ttlCap, variable, false, logQuery, logResponse, followCNAMEs, extendedErrorCode, extendedErrorExtra, responsePaddingDisabled, meta);
+ RecursorLua4::FFIParams params(qname, qtype, destaddr, fromaddr, destination, source, ednssubnet.getSource(), data, policyTags, records, ednsOptions, proxyProtocolValues, requestorId, deviceId, deviceName, routingTag, rcode, ttlCap, variable, false, logQuery, logResponse, followCNAMEs, extendedErrorCode, extendedErrorExtra, responsePaddingDisabled, meta);
eventTrace.add(RecEventTrace::LuaGetTagFFI);
ctag = t_pdl->gettag_ffi(params);
}
else if (t_pdl->hasGettagFunc()) {
eventTrace.add(RecEventTrace::LuaGetTag);
- ctag = t_pdl->gettag(source, ednssubnet.source, destination, qname, qtype, &policyTags, data, ednsOptions, false, requestorId, deviceId, deviceName, routingTag, proxyProtocolValues);
+ ctag = t_pdl->gettag(source, ednssubnet.getSource(), destination, qname, qtype, &policyTags, data, ednsOptions, false, requestorId, deviceId, deviceName, routingTag, proxyProtocolValues);
eventTrace.add(RecEventTrace::LuaGetTag, ctag, false);
}
}
RecursorPacketCache::OptPBData pbData{boost::none};
if (t_protobufServers.servers) {
if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && policyTags.empty())) {
- protobufLogQuery(luaconfsLocal, uniqueId, source, destination, mappedSource, ednssubnet.source, false, question.size(), qname, qtype, qclass, policyTags, requestorId, deviceId, deviceName, meta, ednsVersion, *dnsheader);
+ protobufLogQuery(luaconfsLocal, uniqueId, source, destination, mappedSource, ednssubnet.getSource(), false, question.size(), qname, qtype, qclass, policyTags, requestorId, deviceId, deviceName, meta, ednsVersion, *dnsheader);
}
}
pbMessage.setId(header->id);
pbMessage.setTime();
- pbMessage.setEDNSSubnet(ednssubnet.source, ednssubnet.source.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6);
+ pbMessage.setEDNSSubnet(ednssubnet.getSource(), ednssubnet.getSource().isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6);
pbMessage.setRequestorId(requestorId);
pbMessage.setDeviceId(deviceId);
pbMessage.setDeviceName(deviceName);
{
try {
if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && comboWriter->d_policyTags.empty())) {
- protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.source, true, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, ednsVersion, *dnsheader);
+ protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.getSource(), true, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, ednsVersion, *dnsheader);
}
}
catch (const std::exception& e) {
if (t_pdl) {
try {
if (t_pdl->hasGettagFFIFunc()) {
- RecursorLua4::FFIParams params(qname, qtype, comboWriter->d_local, comboWriter->d_remote, comboWriter->d_destination, comboWriter->d_source, comboWriter->d_ednssubnet.source, comboWriter->d_data, comboWriter->d_gettagPolicyTags, comboWriter->d_records, ednsOptions, comboWriter->d_proxyProtocolValues, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_rcode, comboWriter->d_ttlCap, comboWriter->d_variable, true, logQuery, comboWriter->d_logResponse, comboWriter->d_followCNAMERecords, comboWriter->d_extendedErrorCode, comboWriter->d_extendedErrorExtra, comboWriter->d_responsePaddingDisabled, comboWriter->d_meta);
+ RecursorLua4::FFIParams params(qname, qtype, comboWriter->d_local, comboWriter->d_remote, comboWriter->d_destination, comboWriter->d_source, comboWriter->d_ednssubnet.getSource(), comboWriter->d_data, comboWriter->d_gettagPolicyTags, comboWriter->d_records, ednsOptions, comboWriter->d_proxyProtocolValues, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_rcode, comboWriter->d_ttlCap, comboWriter->d_variable, true, logQuery, comboWriter->d_logResponse, comboWriter->d_followCNAMERecords, comboWriter->d_extendedErrorCode, comboWriter->d_extendedErrorExtra, comboWriter->d_responsePaddingDisabled, comboWriter->d_meta);
comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTagFFI);
comboWriter->d_tag = t_pdl->gettag_ffi(params);
comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTagFFI, comboWriter->d_tag, false);
}
else if (t_pdl->hasGettagFunc()) {
comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTag);
- comboWriter->d_tag = t_pdl->gettag(comboWriter->d_source, comboWriter->d_ednssubnet.source, comboWriter->d_destination, qname, qtype, &comboWriter->d_gettagPolicyTags, comboWriter->d_data, ednsOptions, true, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_proxyProtocolValues);
+ comboWriter->d_tag = t_pdl->gettag(comboWriter->d_source, comboWriter->d_ednssubnet.getSource(), comboWriter->d_destination, qname, qtype, &comboWriter->d_gettagPolicyTags, comboWriter->d_data, ednsOptions, true, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_proxyProtocolValues);
comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTag, comboWriter->d_tag, false);
}
// Copy d_gettagPolicyTags to d_policyTags, so other Lua hooks see them and can add their
{
d_requestor = requestor;
- if (incomingECS && incomingECS->source.getBits() > 0) {
- d_cacheRemote = incomingECS->source.getMaskedNetwork();
- uint8_t bits = std::min(incomingECS->source.getBits(), (incomingECS->source.isIPv4() ? s_ecsipv4limit : s_ecsipv6limit));
- ComboAddress trunc = incomingECS->source.getNetwork();
+ if (incomingECS && incomingECS->getSourcePrefixLength() > 0) {
+ d_cacheRemote = incomingECS->getSource().getMaskedNetwork();
+ uint8_t bits = std::min(incomingECS->getSourcePrefixLength(), (incomingECS->getSource().isIPv4() ? s_ecsipv4limit : s_ecsipv6limit));
+ ComboAddress trunc = incomingECS->getSource().getNetwork();
trunc.truncate(bits);
d_outgoingECSNetwork = boost::optional<Netmask>(Netmask(trunc, bits));
}
trunc.truncate(bits);
d_outgoingECSNetwork = boost::optional<Netmask>(Netmask(trunc, bits));
}
- else if (s_ecsScopeZero.source.getBits() > 0) {
+ else if (s_ecsScopeZero.getSourcePrefixLength() > 0) {
/* RFC7871 says we MUST NOT send any ECS if the source scope is 0.
But using an empty ECS in that case would mean inserting
a non ECS-specific entry into the cache, preventing any further
indicator of the applicable scope. Subsequent Stub Resolver queries
for /0 can then be answered from this cached response.
*/
- d_outgoingECSNetwork = boost::optional<Netmask>(s_ecsScopeZero.source.getMaskedNetwork());
- d_cacheRemote = s_ecsScopeZero.source.getNetwork();
+ d_outgoingECSNetwork = boost::optional<Netmask>(s_ecsScopeZero.getSource().getMaskedNetwork());
+ d_cacheRemote = s_ecsScopeZero.getSource().getNetwork();
}
else {
// ECS disabled because no scope-zero address could be derived.
static void setECSScopeZeroAddress(const Netmask& scopeZeroMask)
{
- s_ecsScopeZero.source = scopeZeroMask;
+ s_ecsScopeZero.setSource(scopeZeroMask);
}
static void clearECSStats()
EDNSCookiesOpt cookiesOpt(clientCookie + serverCookie);
string cookiesOptionStr = cookiesOpt.makeOptString();
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = ecs;
- string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ ecsOpts.setSource(ecs);
+ string origECSOptionStr = ecsOpts.makeOptString();
DNSPacketWriter::optvect_t opts;
opts.emplace_back(EDNSOptionCode::COOKIE, cookiesOptionStr);
opts.emplace_back(EDNSOptionCode::ECS, origECSOptionStr);
BOOST_CHECK_EQUAL(res, 0);
EDNSSubnetOpts eso;
- BOOST_REQUIRE(getEDNSSubnetOptsFromString(reinterpret_cast<const char*>(&query.at(pos + 9 + ecsStartPosition + 4)), ecsLen - 4, &eso));
+ BOOST_REQUIRE(EDNSSubnetOpts::getFromString(reinterpret_cast<const char*>(&query.at(pos + 9 + ecsStartPosition + 4)), ecsLen - 4, &eso));
- BOOST_CHECK(eso.source == ecs);
+ BOOST_CHECK(eso.getSource() == ecs);
}
BOOST_AUTO_TEST_CASE(test_getEDNSOptions)
BOOST_REQUIRE_GT(it->second.values.at(0).size, 0U);
EDNSSubnetOpts eso;
- BOOST_REQUIRE(getEDNSSubnetOptsFromString(it->second.values.at(0).content, it->second.values.at(0).size, &eso));
- BOOST_CHECK(eso.source == ecs);
+ BOOST_REQUIRE(EDNSSubnetOpts::getFromString(it->second.values.at(0).content, it->second.values.at(0).size, &eso));
+ BOOST_CHECK(eso.getSource() == ecs);
it = options.find(EDNSOptionCode::COOKIE);
BOOST_REQUIRE(it != options.end());
{
ComboAddress source(sourceStr);
EDNSSubnetOpts ecsOpts;
- ecsOpts.source = Netmask(source, sourceMask);
+ ecsOpts.setSource(Netmask(source, sourceMask));
- string ecsOptionStr = makeEDNSSubnetOptsString(ecsOpts);
+ string ecsOptionStr = ecsOpts.makeOptString();
/* 2 bytes for family, one for source mask and one for scope mask */
const size_t ecsHeaderSize = 4;
}
EDNSSubnetOpts parsed;
- BOOST_REQUIRE(getEDNSSubnetOptsFromString(ecsOptionStr, &parsed));
- BOOST_REQUIRE(parsed.source == Netmask(truncated, sourceMask));
- BOOST_REQUIRE_EQUAL(ecsOpts.scope.getBits(), parsed.scope.getBits());
+ BOOST_REQUIRE(EDNSSubnetOpts::getFromString(ecsOptionStr, &parsed));
+ BOOST_REQUIRE(parsed.getSource() == Netmask(truncated, sourceMask));
+ BOOST_REQUIRE_EQUAL(ecsOpts.getScopePrefixLength(), parsed.getScopePrefixLength());
}
BOOST_AUTO_TEST_CASE(test_makeEDNSSubnetOptsString)
SyncRes::addEDNSDomain(target);
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.2.128/32");
+ incomingECS.setSource(Netmask("192.0.2.128/32"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
SyncRes::addEDNSRemoteSubnet("192.0.2.1/32");
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("2001:DB8::FF/128");
+ incomingECS.setSource(Netmask("2001:DB8::FF/128"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
SyncRes::clearEDNSLocalSubnets();
SyncRes::addEDNSLocalSubnet("192.0.2.254/32");
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.0.0/16");
+ incomingECS.setSource(Netmask("192.0.0.0/16"));
sr->setQuerySource(ComboAddress("192.0.2.127"), boost::optional<const EDNSSubnetOpts&>(incomingECS));
sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
SyncRes::clearEDNSLocalSubnets();
SyncRes::addEDNSLocalSubnet("192.0.2.254/32");
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("0.0.0.0/0");
+ incomingECS.setSource(Netmask("0.0.0.0/0"));
sr->setQuerySource(ComboAddress("192.0.2.127"), boost::optional<const EDNSSubnetOpts&>(incomingECS));
sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
SyncRes::addEDNSDomain(DNSName("powerdns.com."));
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.2.128/32");
+ incomingECS.setSource(Netmask("192.0.2.128/32"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
sr->setAsyncCallback([&](const ComboAddress& address, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, const ResolveContext& /* context */, LWResult* res, bool* /* chained */) {
SyncRes::addEDNSDomain(DNSName("powerdns.com."));
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.2.128/32");
+ incomingECS.setSource(Netmask("192.0.2.128/32"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::s_ecsipv4cachelimit = 24;
SyncRes::addEDNSDomain(DNSName("powerdns.com."));
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.2.128/32");
+ incomingECS.setSource(Netmask("192.0.2.128/32"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::s_ecsipv4cachelimit = 16;
SyncRes::addEDNSDomain(DNSName("powerdns.com."));
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.2.128/32");
+ incomingECS.setSource(Netmask("192.0.2.128/32"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::s_ecscachelimitttl = 30;
SyncRes::addEDNSDomain(DNSName("powerdns.com."));
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.2.128/32");
+ incomingECS.setSource(Netmask("192.0.2.128/32"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::s_ecscachelimitttl = 100;
SyncRes::s_ecsipv4cachelimit = 24;
SyncRes::addEDNSDomain(DNSName("powerdns.com."));
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.2.128/32");
+ incomingECS.setSource(Netmask("192.0.2.128/32"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::s_ecscachelimitttl = 100;
SyncRes::s_ecsipv4cachelimit = 16;
const ComboAddress ns("192.0.2.1:53");
EDNSSubnetOpts incomingECS;
- incomingECS.source = Netmask("192.0.2.128/32");
+ incomingECS.setSource(Netmask("192.0.2.128/32"));
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::addEDNSDomain(target);
DNSPacketWriter::optvect_t opts;
if (ednsnm) {
EDNSSubnetOpts eo;
- eo.source = *ednsnm;
- opts.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(eo));
+ eo.setSource(*ednsnm);
+ opts.emplace_back(EDNSOptionCode::ECS, eo.makeOptString());
}
pw.addOpt(bufsize, 0, dnssec ? EDNSOpts::DNSSECOK : 0, opts);
iter != edo.d_options.end(); ++iter) {
if (iter->first == EDNSOptionCode::ECS) { // 'EDNS subnet'
EDNSSubnetOpts reso;
- if (getEDNSSubnetOptsFromString(iter->second, &reso)) {
- cerr << "EDNS Subnet response: " << reso.source.toString()
- << ", scope: " << reso.scope.toString()
- << ", family = " << reso.scope.getNetwork().sin4.sin_family
+ if (EDNSSubnetOpts::getFromString(iter->second, &reso)) {
+ cerr << "EDNS Subnet response: " << reso.getSource().toString()
+ << ", scope: " << Netmask(reso.getSource().getNetwork(), reso.getScopePrefixLength()).toString()
+ << ", family = " << std::to_string(reso.getFamily())
<< endl;
}
} else if (iter->first == EDNSOptionCode::PADDING) {
if (d_eso != nullptr) {
// pass along EDNS subnet from client if given - issue #5469
- string origECSOptionStr = makeEDNSSubnetOptsString(*d_eso);
+ string origECSOptionStr = d_eso->makeOptString();
DNSPacketWriter::optvect_t opts;
opts.emplace_back(EDNSOptionCode::ECS, origECSOptionStr);
packetWriter.addOpt(512, 0, 0, opts);
}
{
- ecsOpts.source = Netmask(ComboAddress("192.0.2.1"), 32);
- opts.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(ecsOpts));
+ ecsOpts.setSource(Netmask(ComboAddress("192.0.2.1"), 32));
+ opts.emplace_back(EDNSOptionCode::ECS, ecsOpts.makeOptString());
DNSPacketWriter pw(pak, DNSName("www.powerdns.com"), QType::A);
pw.addOpt(512, 0, 0, opts);
pw.commit();
{
DNSPacketWriter pw(pak, DNSName("www.powerdns.com"), QType::A);
- ecsOpts.source = Netmask(ComboAddress("192.0.2.2"), 32);
- opts.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(ecsOpts));
+ ecsOpts.setSource(Netmask(ComboAddress("192.0.2.2"), 32));
+ opts.emplace_back(EDNSOptionCode::ECS, ecsOpts.makeOptString());
pw.addOpt(512, 0, 0, opts);
pw.commit();
ecs2.parse((char*)&pak[0], pak.size());
{
DNSPacketWriter pw(pak, DNSName("www.powerdns.com"), QType::A);
- ecsOpts.source = Netmask(ComboAddress("192.0.2.3"), 16);
- opts.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(ecsOpts));
+ ecsOpts.setSource(Netmask(ComboAddress("192.0.2.3"), 16));
+ opts.emplace_back(EDNSOptionCode::ECS, ecsOpts.makeOptString());
pw.addOpt(512, 0, 0, opts);
pw.commit();
ecs3.parse((char*)&pak[0], pak.size());
pw1.getHeader()->rd = true;
pw1.getHeader()->qr = false;
pw1.getHeader()->id = 0x42;
- opt.source = Netmask("10.0.59.220/32");
+ opt.setSource(Netmask("10.0.59.220/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
pw1.addOpt(512, 0, 0, ednsOptions);
pw1.commit();
pw2.getHeader()->rd = true;
pw2.getHeader()->qr = false;
pw2.getHeader()->id = 0x84;
- opt.source = Netmask("10.0.167.48/32");
+ opt.setSource(Netmask("10.0.167.48/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
pw2.addOpt(512, 0, 0, ednsOptions);
pw2.commit();
pw1.getHeader()->rd = true;
pw1.getHeader()->qr = false;
pw1.getHeader()->id = 0x42;
- opt.source = Netmask("10.0.41.6/32");
+ opt.setSource(Netmask("10.0.41.6/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
pw1.addOpt(512, 0, EDNSOpts::DNSSECOK, ednsOptions);
pw1.commit();
pw2.getHeader()->rd = true;
pw2.getHeader()->qr = false;
pw2.getHeader()->id = 0x84;
- opt.source = Netmask("10.0.119.79/32");
+ opt.setSource(Netmask("10.0.119.79/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
/* no EDNSOpts::DNSSECOK !! */
pw2.addOpt(512, 0, 0, ednsOptions);
pw2.commit();
pw1.getHeader()->rd = true;
pw1.getHeader()->qr = false;
pw1.getHeader()->id = 0x42;
- opt.source = Netmask("192.0.2.1/32");
+ opt.setSource(Netmask("192.0.2.1/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
EDNSCookiesOpt cookiesOpt(string("deadbeefdeadbeef"));
ednsOptions.emplace_back(EDNSOptionCode::COOKIE, cookiesOpt.makeOptString());
pw1.addOpt(512, 0, EDNSOpts::DNSSECOK, ednsOptions);
pw2.getHeader()->rd = true;
pw2.getHeader()->qr = false;
pw2.getHeader()->id = 0x84;
- opt.source = Netmask("192.0.2.1/32");
+ opt.setSource(Netmask("192.0.2.1/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
cookiesOpt.makeFromString(string("deadbeefbadc0fee"));
ednsOptions.emplace_back(EDNSOptionCode::COOKIE, cookiesOpt.makeOptString());
pw2.addOpt(512, 0, EDNSOpts::DNSSECOK, ednsOptions);
pw1.getHeader()->rd = true;
pw1.getHeader()->qr = false;
pw1.getHeader()->id = 0x42;
- opt.source = Netmask("10.0.18.199/32");
+ opt.setSource(Netmask("10.0.18.199/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
pw1.addOpt(512, 0, 0, ednsOptions);
pw1.commit();
pw2.getHeader()->rd = true;
pw2.getHeader()->qr = false;
pw2.getHeader()->id = 0x84;
- opt.source = Netmask("10.0.131.66/32");
+ opt.setSource(Netmask("10.0.131.66/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
pw2.addOpt(512, 0, 0, ednsOptions);
pw2.commit();
pw1.getHeader()->rd = true;
pw1.getHeader()->qr = false;
pw1.getHeader()->id = 0x42;
- opt.source = Netmask("192.0.2.1/32");
+ opt.setSource(Netmask("192.0.2.1/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
EDNSCookiesOpt cookiesOpt(string("deadbeefdead\x11\xee\x00\x00").c_str(), 16);
ednsOptions.emplace_back(EDNSOptionCode::COOKIE, cookiesOpt.makeOptString());
pw1.addOpt(512, 0, EDNSOpts::DNSSECOK, ednsOptions);
pw2.getHeader()->rd = true;
pw2.getHeader()->qr = false;
pw2.getHeader()->id = 0x84;
- opt.source = Netmask("192.0.2.1/32");
+ opt.setSource(Netmask("192.0.2.1/32"));
ednsOptions.clear();
- ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt));
+ ednsOptions.emplace_back(EDNSOptionCode::ECS, opt.makeOptString());
cookiesOpt.makeFromString(string("deadbeefdead\x67\x44\x00\x00").c_str(), 16);
ednsOptions.emplace_back(EDNSOptionCode::COOKIE, cookiesOpt.makeOptString());
pw2.addOpt(512, 0, EDNSOpts::DNSSECOK, ednsOptions);