diff --git a/include/opendht/default_types.h b/include/opendht/default_types.h index 96c5a5a4f082a72d1bc09b54417187f0072aa7da..c6d8907c4bdb89edcf4e4ee6666f98442781cbff 100644 --- a/include/opendht/default_types.h +++ b/include/opendht/default_types.h @@ -150,9 +150,33 @@ struct IceCandidates : public EncryptedValue<IceCandidates> return EncryptedValue::getFilter(); } + template <typename Packer> + void msgpack_pack(Packer& pk) const + { + pk.pack_array(2); + pk.pack(id); +#if 0 + pk.pack_bin(ice_data.size()); + pk.pack_bin_body((const char*)ice_data.data(), ice_data.size()); +#else + // hack for backward compatibility with old opendht compiled with msgpack 1.0 + // remove when enough people have moved to new versions + pk.pack_array(ice_data.size()); + for (uint8_t b : ice_data) + pk.pack(b); +#endif + } + + void msgpack_unpack(msgpack::object o) + { + if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); + if (o.via.array.size < 2) throw msgpack::type_error(); + id = o.via.array.ptr[0].as<Value::Id>(); + ice_data = unpackBlob(o.via.array.ptr[1]); + } + Value::Id id; Blob ice_data; - MSGPACK_DEFINE(id, ice_data); }; diff --git a/include/opendht/value.h b/include/opendht/value.h index 8f98737afd8a855157f25deaa8505fd350ef2a61..2a9a39b074c5a66d17797d5cda4420a9e17e449c 100644 --- a/include/opendht/value.h +++ b/include/opendht/value.h @@ -505,4 +505,9 @@ unpackVector(const std::vector<std::shared_ptr<Value>>& vals) { return ret; } +/** + * Provides backward compatibility with msgpack 1.0 + */ +Blob unpackBlob(msgpack::object& o); + } diff --git a/src/crypto.cpp b/src/crypto.cpp index 4719b67022cdac6221afd836642127c1df28a3ea..122d3fb0074ab1a347ff124e36fa712db374b8d9 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -30,6 +30,7 @@ #include "crypto.h" #include "rng.h" +#include "value.h" extern "C" { #include <gnutls/gnutls.h> @@ -395,9 +396,12 @@ PublicKey::unpack(const uint8_t* data, size_t data_size) void PublicKey::msgpack_unpack(msgpack::object o) { - if (o.type != msgpack::type::BIN) - throw msgpack::type_error(); - unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size); + if (o.type == msgpack::type::BIN) + unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size); + else { + Blob dat = unpackBlob(o); + unpack(dat.data(), dat.size()); + } } bool @@ -521,9 +525,12 @@ Certificate::unpack(const uint8_t* dat, size_t dat_size) void Certificate::msgpack_unpack(msgpack::object o) { - if (o.type != msgpack::type::BIN) - throw msgpack::type_error(); - unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size); + if (o.type == msgpack::type::BIN) + unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size); + else { + Blob dat = unpackBlob(o); + unpack(dat.data(), dat.size()); + } } void diff --git a/src/dht.cpp b/src/dht.cpp index 567952169d066063be6a629cad5baac95b148920..9a1f12856569611f130f132236aeaa9a1f8e918a 100644 --- a/src/dht.cpp +++ b/src/dht.cpp @@ -3114,28 +3114,6 @@ findMapValue(msgpack::object& map, const std::string& key) { return nullptr; } -/** - * Provides backward compatibility with msgpack 1.0 - */ -Blob -getBlob(msgpack::object& o) { - switch (o.type) { - case msgpack::type::BIN: - return {o.via.bin.ptr, o.via.bin.ptr+o.via.bin.size}; - case msgpack::type::STR: - return {o.via.str.ptr, o.via.str.ptr+o.via.str.size}; - case msgpack::type::ARRAY: { - Blob ret(o.via.array.size); - std::transform(o.via.array.ptr, o.via.array.ptr+o.via.array.size, ret.begin(), [](const msgpack::object& b) { - return b.as<uint8_t>(); - }); - return ret; - } - default: - throw msgpack::type_error(); - } -} - void Dht::ParsedMessage::msgpack_unpack(msgpack::object msg) { @@ -3171,16 +3149,16 @@ Dht::ParsedMessage::msgpack_unpack(msgpack::object msg) target = {*rtarget}; if (auto otoken = findMapValue(req, "token")) - token = getBlob(*otoken); + token = unpackBlob(*otoken); if (auto vid = findMapValue(req, "vid")) value_id = vid->as<Value::Id>(); if (auto rnodes4 = findMapValue(req, "n4")) - nodes4 = getBlob(*rnodes4); + nodes4 = unpackBlob(*rnodes4); if (auto rnodes6 = findMapValue(req, "n6")) - nodes6 = getBlob(*rnodes6); + nodes6 = unpackBlob(*rnodes6); if (auto sa = findMapValue(req, "sa")) { if (sa->type != msgpack::type::BIN) diff --git a/src/value.cpp b/src/value.cpp index c80761827c6e7c0dab19b62d6d995e4099313907..dbcb197f51e2161bf1dd4860d15669343c52d186 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -128,8 +128,7 @@ Value::msgpack_unpack_body(const msgpack::object& o) throw msgpack::type_error(); if (auto rdata = findMapValue(*rbody, "data")) { - auto dat = rdata->as<std::vector<char>>(); - data = {dat.begin(), dat.end()}; + data = unpackBlob(*rdata); } else throw msgpack::type_error(); @@ -153,12 +152,30 @@ Value::msgpack_unpack_body(const msgpack::object& o) } if (auto rsig = findMapValue(o, "sig")) { - auto dat = rsig->as<std::vector<char>>(); - signature = {dat.begin(), dat.end()}; + signature = unpackBlob(*rsig); } else throw msgpack::type_error(); } } } +Blob +unpackBlob(msgpack::object& o) { + switch (o.type) { + case msgpack::type::BIN: + return {o.via.bin.ptr, o.via.bin.ptr+o.via.bin.size}; + case msgpack::type::STR: + return {o.via.str.ptr, o.via.str.ptr+o.via.str.size}; + case msgpack::type::ARRAY: { + Blob ret(o.via.array.size); + std::transform(o.via.array.ptr, o.via.array.ptr+o.via.array.size, ret.begin(), [](const msgpack::object& b) { + return b.as<uint8_t>(); + }); + return ret; + } + default: + throw msgpack::type_error(); + } +} + }