*/
unsigned int MDBGetRandomID(MDBRWTransaction& txn, MDBDbi& dbi);
-/** This is our serialization interface.
- You can define your own serToString for your type if you know better
-*/
-template<typename T>
-std::string serToString(const T& t)
+/**
+ * This is our serialization interface. It can be specialized for other types.
+ */
+template <typename T>
+std::string serializeToBuffer(const T& value)
{
- std::string serial_str;
- boost::iostreams::back_insert_device<std::string> inserter(serial_str);
- boost::iostreams::stream<boost::iostreams::back_insert_device<std::string> > s(inserter);
- boost::archive::binary_oarchive oa(s, boost::archive::no_header | boost::archive::no_codecvt);
-
- oa << t;
- return serial_str;
+ std::string buffer;
+ boost::iostreams::back_insert_device<std::string> inserter(buffer);
+ boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>> inserterStream(inserter);
+ boost::archive::binary_oarchive outputArchive(inserterStream, boost::archive::no_header | boost::archive::no_codecvt);
+ outputArchive << value;
+ return buffer;
}
-template<typename T>
-void serFromString(const string_view& str, T& ret)
+template <typename T>
+void deserializeFromBuffer(const string_view& buffer, T& value)
{
- ret = T();
-
- boost::iostreams::array_source source(&str[0], str.size());
+ value = T();
+ boost::iostreams::array_source source(&buffer[0], buffer.size());
boost::iostreams::stream<boost::iostreams::array_source> stream(source);
- boost::archive::binary_iarchive in_archive(stream, boost::archive::no_header|boost::archive::no_codecvt);
- in_archive >> ret;
-
- /*
- std::istringstream istr{str};
- boost::archive::binary_iarchive oi(istr,boost::archive::no_header|boost::archive::no_codecvt );
- oi >> ret;
- */
+ boost::archive::binary_iarchive inputArchive(stream, boost::archive::no_header | boost::archive::no_codecvt);
+ inputArchive >> value;
}
-
template <class T, class Enable>
-inline std::string keyConv(const T& t);
+inline std::string keyConv(const T& value);
-template <class T, typename std::enable_if<std::is_arithmetic<T>::value,T>::type* = nullptr>
-inline std::string keyConv(const T& t)
+template <class T, typename std::enable_if<std::is_arithmetic<T>::value, T>::type* = nullptr>
+inline std::string keyConv(const T& value)
{
- return std::string((char*)&t, sizeof(t));
+ return std::string((char*)&value, sizeof(value));
}
-// this is how to override specific types.. it is ugly
-template<class T, typename std::enable_if<std::is_same<T, std::string>::value,T>::type* = nullptr>
-inline std::string keyConv(const T& t)
+/**
+ * keyConv specialization for std::string.
+ */
+template <class T, typename std::enable_if<std::is_same<T, std::string>::value, T>::type* = nullptr>
+inline std::string keyConv(const T& value)
{
- return t;
+ return value;
}
-
namespace {
inline MDBOutVal getKeyFromCombinedKey(MDBInVal combined) {
if (combined.d_mdbval.mv_size < sizeof(uint32_t)) {
if((*d_parent.d_txn)->get(d_parent.d_parent->d_main, id, data))
return false;
- serFromString(data.get<std::string>(), t);
+ deserializeFromBuffer(data.get<std::string>(), t);
return true;
}
if(d_on_index) {
if((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data))
throw std::runtime_error("Missing id in constructor");
- serFromString(d_data.get<std::string>(), d_t);
+ deserializeFromBuffer(d_data.get<std::string>(), d_t);
}
else
- serFromString(d_id.get<std::string>(), d_t);
+ deserializeFromBuffer(d_id.get<std::string>(), d_t);
}
explicit iter_t(Parent* parent, typename Parent::cursor_t&& cursor, const std::string& prefix) :
if(d_on_index) {
if((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data))
throw std::runtime_error("Missing id in constructor");
- serFromString(d_data.get<std::string>(), d_t);
+ deserializeFromBuffer(d_data.get<std::string>(), d_t);
}
else
- serFromString(d_id.get<std::string>(), d_t);
+ deserializeFromBuffer(d_id.get<std::string>(), d_t);
}
// if(filter && !filter(data))
// goto next;
- serFromString(data.get<std::string>(), d_t);
+ deserializeFromBuffer(data.get<std::string>(), d_t);
}
else {
// if(filter && !filter(data))
// goto next;
- serFromString(d_id.get<std::string>(), d_t);
+ deserializeFromBuffer(d_id.get<std::string>(), d_t);
}
}
return *this;
// flags = MDB_APPEND;
}
}
- (*d_txn)->put(d_parent->d_main, id, serToString(t), flags);
+ (*d_txn)->put(d_parent->d_main, id, serializeToBuffer(t), flags);
#define insertMacro(N) std::get<N>(d_parent->d_tuple).put(*d_txn, t, id);
insertMacro(0);
while(!cursor.get(key, data, first ? MDB_FIRST : MDB_NEXT)) {
first = false;
T t;
- serFromString(data.get<std::string>(), t);
+ deserializeFromBuffer(data.get<std::string>(), t);
clearIndex(key.get<uint32_t>(), t);
cursor.del();
}
BOOST_IS_BITWISE_SERIALIZABLE(ComboAddress);
template <>
-std::string serToString(const LMDBBackend::LMDBResourceRecord& lrr)
+std::string serializeToBuffer(const LMDBBackend::LMDBResourceRecord& lrr)
{
std::string ret;
uint16_t len = lrr.content.length();
}
template <>
-std::string serToString(const vector<LMDBBackend::LMDBResourceRecord>& lrrs)
+std::string serializeToBuffer(const vector<LMDBBackend::LMDBResourceRecord>& lrrs)
{
std::string ret;
for (const auto& lrr : lrrs) {
- ret += serToString(lrr);
+ ret += serializeToBuffer(lrr);
}
return ret;
}
-static inline size_t serOneRRFromString(const string_view& str, LMDBBackend::LMDBResourceRecord& lrr)
+static inline size_t deserializeRRFromBuffer(const string_view& str, LMDBBackend::LMDBResourceRecord& lrr)
{
uint16_t len;
memcpy(&len, &str[0], 2);
}
template <>
-void serFromString(const string_view& str, LMDBBackend::LMDBResourceRecord& lrr)
+void deserializeFromBuffer(const string_view& str, LMDBBackend::LMDBResourceRecord& lrr)
{
- serOneRRFromString(str, lrr);
+ deserializeRRFromBuffer(str, lrr);
}
template <>
-void serFromString(const string_view& str, vector<LMDBBackend::LMDBResourceRecord>& lrrs)
+void deserializeFromBuffer(const string_view& str, vector<LMDBBackend::LMDBResourceRecord>& lrrs)
{
auto str_copy = str;
while (str_copy.size() >= 9) { // minimum length for a record is 10
LMDBBackend::LMDBResourceRecord lrr;
- auto rrLength = serOneRRFromString(str_copy, lrr);
+ auto rrLength = deserializeRRFromBuffer(str_copy, lrr);
lrrs.emplace_back(lrr);
str_copy.remove_prefix(rrLength);
}
rrs = _rrs.get<string>();
}
- rrs += serToString(lrr);
+ rrs += serializeToBuffer(lrr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, matchName, rrs);
lrr.ttl = 0;
lrr.content = lrr.qname.toDNSStringLC();
lrr.auth = 0;
- string ser = serToString(lrr);
+ string ser = serializeToBuffer(lrr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(lrr.domain_id, ordername, QType::NSEC3), ser);
lrr.ttl = 1;
lrr.content = ordername.toDNSString();
- ser = serToString(lrr);
+ ser = serializeToBuffer(lrr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(lrr.domain_id, lrr.qname, QType::NSEC3), ser);
}
}
lrr.auth = nt.second;
lrr.ordername = true;
- std::string ser = serToString(lrr);
+ std::string ser = serializeToBuffer(lrr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(domain_id, lrr.qname, QType::ENT), ser);
}
return true;
lrr.ttl = 0;
lrr.auth = nt.second;
lrr.ordername = nt.second;
- ser = serToString(lrr);
+ ser = serializeToBuffer(lrr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(domain_id, lrr.qname, QType::ENT), ser);
if (!narrow && lrr.auth) {
lrr.content = lrr.qname.toDNSString();
lrr.auth = false;
lrr.ordername = false;
- ser = serToString(lrr);
+ ser = serializeToBuffer(lrr);
ordername = DNSName(toBase32Hex(hashQNameWithSalt(ns3prc, nt.first)));
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(domain_id, ordername, QType::NSEC3), ser);
lrr.ttl = 1;
lrr.content = ordername.toDNSString();
- ser = serToString(lrr);
+ ser = serializeToBuffer(lrr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(domain_id, lrr.qname, QType::NSEC3), ser);
}
}
adjustedRRSet.emplace_back(lrr);
}
- txn->txn->put(txn->db->dbi, match, serToString(adjustedRRSet));
+ txn->txn->put(txn->db->dbi, match, serializeToBuffer(adjustedRRSet));
}
if (needCommit)
continue;
}
- serFromString(d_currentVal.get<string_view>(), d_currentrrset);
+ deserializeFromBuffer(d_currentVal.get<string_view>(), d_currentrrset);
d_currentrrsetpos = 0;
}
else {
MDBOutVal val;
if (!txn->txn->get(txn->db->dbi, co(di.id, g_rootdnsname, QType::SOA), val)) {
LMDBResourceRecord lrr;
- serFromString(val.get<string_view>(), lrr);
+ deserializeFromBuffer(val.get<string_view>(), lrr);
if (lrr.content.size() >= 5 * sizeof(uint32_t)) {
uint32_t serial;
// a SOA has five 32 bit fields, the first of which is the serial
compoundOrdername co;
MDBOutVal val;
if (!txn2->txn->get(txn2->db->dbi, co(di.id, g_rootdnsname, QType::SOA), val)) {
- serFromString(val.get<string_view>(), lrr);
+ deserializeFromBuffer(val.get<string_view>(), lrr);
memcpy(&st, &lrr.content[lrr.content.size() - sizeof(soatimes)], sizeof(soatimes));
if ((time_t)(di.last_check + ntohl(st.refresh)) > now) { // still fresh
return false;
}
if (co.getQType(key.getNoStripHeader<StringView>()) == QType::NSEC3) {
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (!lrr.ttl) // the kind of NSEC3 we need
break;
}
}
for (;;) {
if (co.getQType(key.getNoStripHeader<StringView>()) == QType::NSEC3) {
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (!lrr.ttl)
break;
}
}
for (;;) {
if (co.getQType(key.getNoStripHeader<StringView>()) == QType::NSEC3) {
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (!lrr.ttl)
break;
}
// cout<<"Potentially stopping traverse at "<< co.getQName(key.get<StringView>()) <<", " << (co.getQName(key.get<StringView>()).canonCompare(qname))<<endl;
// cout<<"qname = "<<qname<<endl;
// cout<<"here = "<<co.getQName(key.get<StringView>())<<endl;
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (!lrr.ttl)
break;
}
}
if (co.getQType(key.getNoStripHeader<StringView>()) == QType::NSEC3) {
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (!lrr.ttl) // the kind of NSEC3 we need
break;
}
}
for (;;) {
if (co.getQType(key.getNoStripHeader<StringView>()) == QType::NSEC3) {
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (!lrr.ttl)
break;
}
}
for (;;) {
if (co.getQType(key.getNoStripHeader<StringView>()) == QType::NSEC3) {
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (!lrr.ttl)
break;
}
// cout<<"After "<<co.getQName(key.get<StringView>()) <<endl;
if (co.getQType(key.getNoStripHeader<StringView>()) == QType::NSEC3) {
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (!lrr.ttl) {
break;
}
if (co.getDomainID(key.getNoStripHeader<string_view>()) == id && key.getNoStripHeader<StringView>().rfind(matchkey, 0) == 0)
continue;
LMDBResourceRecord lrr;
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (co.getQType(key.getNoStripHeader<string_view>()).getCode() && (lrr.auth || co.getQType(key.getNoStripHeader<string_view>()).getCode() == QType::NS))
break;
}
return false;
}
LMDBResourceRecord lrr;
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (co.getQType(key.getNoStripHeader<string_view>()).getCode() && (lrr.auth || co.getQType(key.getNoStripHeader<string_view>()).getCode() == QType::NS))
break;
}
int skips = 0;
for (;;) {
LMDBResourceRecord lrr;
- serFromString(val.get<StringView>(), lrr);
+ deserializeFromBuffer(val.get<StringView>(), lrr);
if (co.getQType(key.getNoStripHeader<string_view>()).getCode() && (lrr.auth || co.getQType(key.getNoStripHeader<string_view>()).getCode() == QType::NS)) {
after = co.getQName(key.getNoStripHeader<string_view>()) + zonename;
// cout <<"Found auth ("<<lrr.auth<<") or an NS record "<<after<<", type: "<<co.getQType(key.getNoStripHeader<string_view>()).toString()<<", ttl = "<<lrr.ttl<<endl;
}
before = co.getQName(key.getNoStripHeader<string_view>()) + zonename;
LMDBResourceRecord lrr;
- serFromString(val.get<string_view>(), lrr);
+ deserializeFromBuffer(val.get<string_view>(), lrr);
// cout<<"And before to "<<before<<", auth = "<<rr.auth<<endl;
if (co.getQType(key.getNoStripHeader<string_view>()).getCode() && (lrr.auth || co.getQType(key.getNoStripHeader<string_view>()) == QType::NS))
break;
vector<LMDBResourceRecord> lrrs;
if (co.getQType(key.getNoStripHeader<StringView>()) != QType::NSEC3) {
- serFromString(val.get<StringView>(), lrrs);
+ deserializeFromBuffer(val.get<StringView>(), lrrs);
bool changed = false;
vector<LMDBResourceRecord> newRRs;
for (auto& lrr : lrrs) {
newRRs.push_back(std::move(lrr));
}
if (changed) {
- cursor.put(key, serToString(newRRs));
+ cursor.put(key, serializeToBuffer(newRRs));
}
}
// cerr<<"here qname="<<qname<<" ordername="<<ordername<<" qtype="<<qtype<<" matchkey="<<makeHexDump(matchkey)<<endl;
int txngetrc;
if (!(txngetrc = txn->txn->get(txn->db->dbi, matchkey, val))) {
- serFromString(val.get<string_view>(), lrr);
+ deserializeFromBuffer(val.get<string_view>(), lrr);
if (needNSEC3) {
if (hasOrderName && lrr.content != ordername.toDNSStringLC()) {
lrr.auth = 0;
lrr.content = rel.toDNSStringLC();
- string str = serToString(lrr);
+ string str = serializeToBuffer(lrr);
txn->txn->put(txn->db->dbi, co(domain_id, ordername, QType::NSEC3), str);
lrr.ttl = 1;
lrr.content = ordername.toDNSStringLC();
- str = serToString(lrr);
+ str = serializeToBuffer(lrr);
txn->txn->put(txn->db->dbi, matchkey, str); // 2
}
lrr.ttl = 0;
lrr.auth = true;
- std::string ser = serToString(lrr);
+ std::string ser = serializeToBuffer(lrr);
txn->txn->put(txn->db->dbi, co(domain_id, lrr.qname, 0), ser);