diff --git a/src/network_engine.cpp b/src/network_engine.cpp index db4bc1fd1d478cc890e4f8650708ffa2aa00492e..d3ea1293956f441a5f49045ac7464599794303c8 100644 --- a/src/network_engine.cpp +++ b/src/network_engine.cpp @@ -191,23 +191,23 @@ NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&, msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); - pk.pack(std::string("u")); + pk.pack(KEY_U); pk.pack_map(1 + (not values.empty()?1:0) + (not token.empty()?1:0)); - pk.pack(std::string("id")); pk.pack(myid); + pk.pack(KEY_REQ_ID); pk.pack(myid); if (not token.empty()) { - pk.pack(std::string("token")); packToken(pk, token); + pk.pack(KEY_REQ_TOKEN); packToken(pk, token); } if (not values.empty()) { - pk.pack(std::string("re")); + pk.pack(KEY_REQ_REFRESHED); pk.pack(values); DHT_LOG.d(n->id, "[node %s] sending %zu refreshed values", n->toString().c_str(), values.size()); } - pk.pack(std::string("t")); pk.pack(socket_id); - pk.pack(std::string("y")); pk.pack(std::string("r")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_TID); pk.pack(socket_id); + pk.pack(KEY_Y); pk.pack(KEY_R); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } // send response @@ -221,23 +221,23 @@ NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, c msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); - pk.pack(std::string("u")); + pk.pack(KEY_U); pk.pack_map(1 + (not values.empty()?1:0) + (not token.empty()?1:0)); - pk.pack(std::string("id")); pk.pack(myid); + pk.pack(KEY_REQ_ID); pk.pack(myid); if (not token.empty()) { - pk.pack(std::string("token")); packToken(pk, token); + pk.pack(KEY_REQ_TOKEN); packToken(pk, token); } if (not values.empty()) { - pk.pack(std::string("exp")); + pk.pack(KEY_REQ_EXPIRED); pk.pack(values); DHT_LOG.d(n->id, "[node %s] sending %zu expired values", n->toString().c_str(), values.size()); } - pk.pack(std::string("t")); pk.pack(socket_id); - pk.pack(std::string("y")); pk.pack(std::string("r")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_TID); pk.pack(socket_id); + pk.pack(KEY_Y); pk.pack(KEY_R); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } // send response @@ -687,16 +687,16 @@ NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& o msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(5+(network?1:0)); - pk.pack(std::string("a")); pk.pack_map(1); - pk.pack(std::string("id")); pk.pack(myid); + pk.pack(KEY_A); pk.pack_map(1); + pk.pack(KEY_REQ_ID); pk.pack(myid); - pk.pack(std::string("q")); pk.pack(std::string("ping")); - pk.pack(std::string("t")); pk.pack_bin(tid.size()); + pk.pack(KEY_Q); pk.pack(QUERY_PING); + pk.pack(KEY_TID); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); - pk.pack(std::string("y")); pk.pack(std::string("q")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_Q); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } auto req = std::make_shared<Request>(MessageType::Ping, tid.toInt(), node, @@ -724,17 +724,17 @@ NetworkEngine::sendPong(const SockAddr& addr, Tid tid) { msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); - pk.pack(std::string("r")); pk.pack_map(2); - pk.pack(std::string("id")); pk.pack(myid); + pk.pack(KEY_R); pk.pack_map(2); + pk.pack(KEY_REQ_ID); pk.pack(myid); insertAddr(pk, addr); TransId t (tid); - pk.pack(std::string("t")); pk.pack_bin(t.size()); + pk.pack(KEY_TID); pk.pack_bin(t.size()); pk.pack_bin_body((const char*)t.data(), t.size()); - pk.pack(std::string("y")); pk.pack(std::string("r")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_R); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } send(buffer.data(), buffer.size(), 0, addr); @@ -748,23 +748,23 @@ NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want, msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(5+(network?1:0)); - pk.pack(std::string("a")); pk.pack_map(2 + (want>0?1:0)); - pk.pack(std::string("id")); pk.pack(myid); - pk.pack(std::string("target")); pk.pack(target); + pk.pack(KEY_A); pk.pack_map(2 + (want>0?1:0)); + pk.pack(KEY_REQ_ID); pk.pack(myid); + pk.pack(KEY_REQ_TARGET); pk.pack(target); if (want > 0) { - pk.pack(std::string("w")); + pk.pack(KEY_REQ_WANT); pk.pack_array(((want & WANT4)?1:0) + ((want & WANT6)?1:0)); if (want & WANT4) pk.pack(AF_INET); if (want & WANT6) pk.pack(AF_INET6); } - pk.pack(std::string("q")); pk.pack(std::string("find")); - pk.pack(std::string("t")); pk.pack_bin(tid.size()); + pk.pack(KEY_Q); pk.pack(QUERY_FIND); + pk.pack(KEY_TID); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); - pk.pack(std::string("y")); pk.pack(std::string("q")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_Q); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } auto req = std::make_shared<Request>(MessageType::FindNode, tid.toInt(), n, @@ -794,26 +794,26 @@ NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query& msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(5+(network?1:0)); - pk.pack(std::string("a")); pk.pack_map(2 + + pk.pack(KEY_A); pk.pack_map(2 + (query.where.getFilter() or not query.select.getSelection().empty() ? 1:0) + (want>0?1:0)); - pk.pack(std::string("id")); pk.pack(myid); - pk.pack(std::string("h")); pk.pack(info_hash); - pk.pack(std::string("q")); pk.pack(query); + pk.pack(KEY_REQ_ID); pk.pack(myid); + pk.pack(KEY_REQ_H); pk.pack(info_hash); + pk.pack(KEY_Q); pk.pack(query); if (want > 0) { - pk.pack(std::string("w")); + pk.pack(KEY_REQ_WANT); pk.pack_array(((want & WANT4)?1:0) + ((want & WANT6)?1:0)); if (want & WANT4) pk.pack(AF_INET); if (want & WANT6) pk.pack(AF_INET6); } - pk.pack(std::string("q")); pk.pack(std::string("get")); - pk.pack(std::string("t")); pk.pack_bin(tid.size()); + pk.pack(KEY_Q); pk.pack(QUERY_GET); + pk.pack(KEY_TID); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); - pk.pack(std::string("y")); pk.pack(std::string("q")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_Q); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } auto req = std::make_shared<Request>(MessageType::GetValues, tid.toInt(), n, @@ -901,7 +901,7 @@ NetworkEngine::packValueHeader(msgpack::sbuffer& buffer, const std::vector<Sp<Va total_size += v.size(); msgpack::packer<msgpack::sbuffer> pk(&buffer); - pk.pack(std::string("values")); + pk.pack(KEY_REQ_VALUES); pk.pack_array(svals.size()); // try to put everything in a single UDP packet if (svals.size() < 50 && total_size < MAX_PACKET_VALUE_SIZE) { @@ -929,12 +929,12 @@ NetworkEngine::sendValueParts(const TransId& tid, const std::vector<Blob>& svals msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(3+(network?1:0)); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } - pk.pack(std::string("y")); pk.pack(std::string("v")); - pk.pack(std::string("t")); pk.pack_bin(tid.size()); + pk.pack(KEY_Y); pk.pack(KEY_V); + pk.pack(KEY_TID); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); - pk.pack(std::string("p")); pk.pack_map(1); + pk.pack(KEY_V); pk.pack_map(1); pk.pack(i); pk.pack_map(2); pk.pack(std::string("o")); pk.pack(start); pk.pack(std::string("d")); pk.pack_bin(end-start); @@ -954,22 +954,22 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes, msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); - pk.pack(std::string("r")); + pk.pack(KEY_R); pk.pack_map(2 + (not st.empty()?1:0) + (nodes.size()>0?1:0) + (nodes6.size()>0?1:0) + (not token.empty()?1:0)); - pk.pack(std::string("id")); pk.pack(myid); + pk.pack(KEY_REQ_ID); pk.pack(myid); insertAddr(pk, addr); if (nodes.size() > 0) { - pk.pack(std::string("n4")); + pk.pack(KEY_REQ_NODES4); pk.pack_bin(nodes.size()); pk.pack_bin_body((const char*)nodes.data(), nodes.size()); } if (nodes6.size() > 0) { - pk.pack(std::string("n6")); + pk.pack(KEY_REQ_NODES6); pk.pack_bin(nodes6.size()); pk.pack_bin_body((const char*)nodes6.data(), nodes6.size()); } if (not token.empty()) { - pk.pack(std::string("token")); packToken(pk, token); + pk.pack(KEY_REQ_TOKEN); packToken(pk, token); } std::vector<Blob> svals {}; if (not st.empty()) { /* pack complete values */ @@ -977,7 +977,7 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes, if (fields.empty()) { svals = packValueHeader(buffer, st); } else { /* pack fields */ - pk.pack(std::string("fields")); + pk.pack(KEY_REQ_FIELDS); pk.pack_map(2); pk.pack(std::string("f")); pk.pack(fields); pk.pack(std::string("v")); pk.pack_array(st.size()*fields.size()); @@ -989,12 +989,12 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes, } TransId t (tid); - pk.pack(std::string("t")); pk.pack_bin(t.size()); - pk.pack_bin_body((const char*)t.data(), t.size()); - pk.pack(std::string("y")); pk.pack(std::string("r")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_TID); pk.pack_bin(t.size()); + pk.pack_bin_body((const char*)t.data(), t.size()); + pk.pack(KEY_Y); pk.pack(KEY_R); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } // send response @@ -1086,23 +1086,23 @@ NetworkEngine::sendListen(Sp<Node> n, pk.pack_map(5+(network?1:0)); auto has_query = query.where.getFilter() or not query.select.getSelection().empty(); - pk.pack(std::string("a")); pk.pack_map(4 + has_query); - pk.pack(std::string("id")); pk.pack(myid); - pk.pack(std::string("h")); pk.pack(hash); - pk.pack(std::string("token")); packToken(pk, token); - pk.pack(std::string("sid")); pk.pack_bin(sid.size()); - pk.pack_bin_body((const char*)sid.data(), sid.size()); + pk.pack(KEY_A); pk.pack_map(4 + has_query); + pk.pack(KEY_REQ_ID); pk.pack(myid); + pk.pack(KEY_REQ_H); pk.pack(hash); + pk.pack(KEY_REQ_TOKEN); packToken(pk, token); + pk.pack(KEY_REQ_SID); pk.pack_bin(sid.size()); + pk.pack_bin_body((const char*)sid.data(), sid.size()); if (has_query) { - pk.pack(std::string("q")); pk.pack(query); + pk.pack(KEY_REQ_QUERY); pk.pack(query); } - pk.pack(std::string("q")); pk.pack(std::string("listen")); - pk.pack(std::string("t")); pk.pack_bin(tid.size()); + pk.pack(KEY_Q); pk.pack(QUERY_LISTEN); + pk.pack(KEY_TID); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); - pk.pack(std::string("y")); pk.pack(std::string("q")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_Q); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } auto req = std::make_shared<Request>(MessageType::Listen, tid.toInt(), n, @@ -1128,17 +1128,17 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) { msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); - pk.pack(std::string("r")); pk.pack_map(2); - pk.pack(std::string("id")); pk.pack(myid); + pk.pack(KEY_R); pk.pack_map(2); + pk.pack(KEY_REQ_ID); pk.pack(myid); insertAddr(pk, addr); TransId t (tid); - pk.pack(std::string("t")); pk.pack_bin(t.size()); + pk.pack(KEY_TID); pk.pack_bin(t.size()); pk.pack_bin_body((const char*)t.data(), t.size()); - pk.pack(std::string("y")); pk.pack(std::string("r")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_R); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } send(buffer.data(), buffer.size(), 0, addr); @@ -1158,23 +1158,23 @@ NetworkEngine::sendAnnounceValue(Sp<Node> n, msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(5+(network?1:0)); - pk.pack(std::string("a")); pk.pack_map((created < scheduler.time() ? 5 : 4)); - pk.pack(std::string("id")); pk.pack(myid); - pk.pack(std::string("h")); pk.pack(infohash); + pk.pack(KEY_A); pk.pack_map((created < scheduler.time() ? 5 : 4)); + pk.pack(KEY_REQ_ID); pk.pack(myid); + pk.pack(KEY_REQ_H); pk.pack(infohash); auto v = packValueHeader(buffer, {value}); if (created < scheduler.time()) { - pk.pack(std::string("c")); + pk.pack(KEY_REQ_CREATION); pk.pack(to_time_t(created)); } - pk.pack(std::string("token")); pk.pack(token); + pk.pack(KEY_REQ_TOKEN); pk.pack(token); - pk.pack(std::string("q")); pk.pack(std::string("put")); - pk.pack(std::string("t")); pk.pack_bin(tid.size()); - pk.pack_bin_body((const char*)tid.data(), tid.size()); - pk.pack(std::string("y")); pk.pack(std::string("q")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Q); pk.pack(QUERY_PUT); + pk.pack(KEY_TID); pk.pack_bin(tid.size()); + pk.pack_bin_body((const char*)tid.data(), tid.size()); + pk.pack(KEY_Y); pk.pack(KEY_Q); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } auto req = std::make_shared<Request>(MessageType::AnnounceValue, tid.toInt(), n, @@ -1216,19 +1216,19 @@ NetworkEngine::sendRefreshValue(Sp<Node> n, msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(5+(network?1:0)); - pk.pack(std::string("a")); pk.pack_map(4); - pk.pack(std::string("id")); pk.pack(myid); - pk.pack(std::string("h")); pk.pack(infohash); - pk.pack(std::string("vid")); pk.pack(vid); - pk.pack(std::string("token")); pk.pack(token); + pk.pack(KEY_A); pk.pack_map(4); + pk.pack(KEY_REQ_ID); pk.pack(myid); + pk.pack(KEY_REQ_H); pk.pack(infohash); + pk.pack(KEY_REQ_VALUE_ID); pk.pack(vid); + pk.pack(KEY_REQ_TOKEN); pk.pack(token); - pk.pack(std::string("q")); pk.pack(std::string("refresh")); - pk.pack(std::string("t")); pk.pack_bin(tid.size()); + pk.pack(KEY_Q); pk.pack(QUERY_REFRESH); + pk.pack(KEY_TID); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); - pk.pack(std::string("y")); pk.pack(std::string("q")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_Q); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } auto req = std::make_shared<Request>(MessageType::Refresh, tid.toInt(), n, @@ -1261,18 +1261,18 @@ NetworkEngine::sendValueAnnounced(const SockAddr& addr, Tid tid, Value::Id vid) msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); - pk.pack(std::string("r")); pk.pack_map(3); - pk.pack(std::string("id")); pk.pack(myid); - pk.pack(std::string("vid")); pk.pack(vid); + pk.pack(KEY_R); pk.pack_map(3); + pk.pack(KEY_REQ_ID); pk.pack(myid); + pk.pack(KEY_REQ_VALUE_ID); pk.pack(vid); insertAddr(pk, addr); TransId t(tid); - pk.pack(std::string("t")); pk.pack_bin(t.size()); + pk.pack(KEY_TID); pk.pack_bin(t.size()); pk.pack_bin_body((const char*)t.data(), t.size()); - pk.pack(std::string("y")); pk.pack(std::string("r")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_R); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } send(buffer.data(), buffer.size(), 0, addr); @@ -1289,22 +1289,22 @@ NetworkEngine::sendError(const SockAddr& addr, msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4 + (include_id?1:0)); - pk.pack(std::string("e")); pk.pack_array(2); + pk.pack(KEY_E); pk.pack_array(2); pk.pack(code); pk.pack(message); if (include_id) { - pk.pack(std::string("r")); pk.pack_map(1); - pk.pack(std::string("id")); pk.pack(myid); + pk.pack(KEY_R); pk.pack_map(1); + pk.pack(KEY_REQ_ID); pk.pack(myid); } TransId t(tid); - pk.pack(std::string("t")); pk.pack_bin(t.size()); + pk.pack(KEY_TID); pk.pack_bin(t.size()); pk.pack_bin_body((const char*)t.data(), t.size()); - pk.pack(std::string("y")); pk.pack(std::string("e")); - pk.pack(std::string("v")); pk.pack(my_v); + pk.pack(KEY_Y); pk.pack(KEY_E); + pk.pack(KEY_UA); pk.pack(my_v); if (network) { - pk.pack(std::string("n")); pk.pack(network); + pk.pack(KEY_NETID); pk.pack(network); } send(buffer.data(), buffer.size(), 0, addr); diff --git a/src/parsed_message.h b/src/parsed_message.h index 206e826cd30fed250d0ac25280f778eee3b0e684..6b568f5579b2a25514f68fef0468420a813567a5 100644 --- a/src/parsed_message.h +++ b/src/parsed_message.h @@ -26,6 +26,42 @@ namespace dht { namespace net { +static const std::string KEY_Y {"y"}; +static const std::string KEY_R {"r"}; +static const std::string KEY_U {"u"}; +static const std::string KEY_E {"e"}; +static const std::string KEY_V {"p"}; +static const std::string KEY_TID {"t"}; +static const std::string KEY_UA {"v"}; +static const std::string KEY_NETID {"n"}; +static const std::string KEY_ISCLIENT {"s"}; +static const std::string KEY_Q {"q"}; +static const std::string KEY_A {"a"}; + +static const std::string KEY_REQ_SID {"sid"}; +static const std::string KEY_REQ_ID {"id"}; +static const std::string KEY_REQ_H {"h"}; +static const std::string KEY_REQ_TARGET {"target"}; +static const std::string KEY_REQ_QUERY {"q"}; +static const std::string KEY_REQ_TOKEN {"token"}; +static const std::string KEY_REQ_VALUE_ID {"vid"}; +static const std::string KEY_REQ_NODES4 {"n4"}; +static const std::string KEY_REQ_NODES6 {"n6"}; +static const std::string KEY_REQ_CREATION {"c"}; +static const std::string KEY_REQ_ADDRESS {"sa"}; +static const std::string KEY_REQ_VALUES {"values"}; +static const std::string KEY_REQ_EXPIRED {"exp"}; +static const std::string KEY_REQ_REFRESHED {"re"}; +static const std::string KEY_REQ_FIELDS {"fileds"}; +static const std::string KEY_REQ_WANT {"w"}; + +static const std::string QUERY_PING {"ping"}; +static const std::string QUERY_FIND {"find"}; +static const std::string QUERY_GET {"get"}; +static const std::string QUERY_PUT {"put"}; +static const std::string QUERY_LISTEN {"listen"}; +static const std::string QUERY_REFRESH {"refresh"}; + Tid unpackTid(const msgpack::object& o) { switch (o.type) { case msgpack::type::POSITIVE_INTEGER: @@ -78,7 +114,7 @@ struct ParsedMessage { /* reported address by the distant node */ std::string ua; SockAddr addr; - void msgpack_unpack(msgpack::object o); + void msgpack_unpack(const msgpack::object& o); bool append(const ParsedMessage& block); bool complete(); @@ -123,63 +159,79 @@ ParsedMessage::complete() } void -ParsedMessage::msgpack_unpack(msgpack::object msg) +ParsedMessage::msgpack_unpack(const msgpack::object& msg) { - auto y = findMapValue(msg, "y"); - auto r = findMapValue(msg, "r"); - auto u = findMapValue(msg, "u"); - auto e = findMapValue(msg, "e"); - auto v = findMapValue(msg, "p"); - - if (auto t = findMapValue(msg, "t")) - tid = unpackTid(*t); - - if (auto rv = findMapValue(msg, "v")) - ua = rv->as<std::string>(); - - if (auto netid = findMapValue(msg, "n")) - network = netid->as<NetId>(); - - if (auto is_client_v = findMapValue(msg, "s")) - is_client = is_client_v->as<bool>(); - - std::string q; - if (auto rq = findMapValue(msg, "q")) { - if (rq->type != msgpack::type::STR) - throw msgpack::type_error(); - q = rq->as<std::string>(); + if (msg.type != msgpack::type::MAP) throw msgpack::type_error(); + + struct ParsedMsg { + msgpack::object* y; + msgpack::object* r; + msgpack::object* u; + msgpack::object* e; + msgpack::object* v; + msgpack::object* a; + std::string q; + } parsed {}; + + for (unsigned i = 0; i < msg.via.map.size; i++) { + auto& o = msg.via.map.ptr[i]; + if (o.key.type != msgpack::type::STR) + continue; + auto key = o.key.as<std::string>(); + if (key == KEY_Y) + parsed.y = &o.val; + else if (key == KEY_R) + parsed.r = &o.val; + else if (key == KEY_U) + parsed.u = &o.val; + else if (key == KEY_E) + parsed.e = &o.val; + else if (key == KEY_V) + parsed.v = &o.val; + else if (key == KEY_TID) + tid = unpackTid(o.val); + else if (key == KEY_UA) + ua = o.val.as<std::string>(); + else if (key == KEY_NETID) + network = o.val.as<NetId>(); + else if (key == KEY_ISCLIENT) + is_client = o.val.as<bool>(); + else if (key == KEY_Q) + parsed.q = o.val.as<std::string>(); + else if (key == KEY_A) + parsed.a = &o.val; } - if (e) + if (parsed.e) type = MessageType::Error; - else if (r) + else if (parsed.r) type = MessageType::Reply; - else if (v) + else if (parsed.v) type = MessageType::ValueData; - else if (u) + else if (parsed.u) type = MessageType::ValueUpdate; - else if (y and y->as<std::string>() != "q") + else if (parsed.y and parsed.y->as<std::string>() != "q") throw msgpack::type_error(); - else if (q == "ping") + else if (parsed.q == QUERY_PING) type = MessageType::Ping; - else if (q == "find") + else if (parsed.q == QUERY_FIND) type = MessageType::FindNode; - else if (q == "get") + else if (parsed.q == QUERY_GET) type = MessageType::GetValues; - else if (q == "listen") + else if (parsed.q == QUERY_LISTEN) type = MessageType::Listen; - else if (q == "put") + else if (parsed.q == QUERY_PUT) type = MessageType::AnnounceValue; - else if (q == "refresh") + else if (parsed.q == QUERY_REFRESH) type = MessageType::Refresh; else throw msgpack::type_error(); if (type == MessageType::ValueData) { - if (v->type != msgpack::type::MAP) + if (parsed.v->type != msgpack::type::MAP) throw msgpack::type_error(); - for (size_t i = 0; i < v->via.map.size; ++i) { - auto& vdat = v->via.map.ptr[i]; + for (size_t i = 0; i < parsed.v->via.map.size; ++i) { + auto& vdat = parsed.v->via.map.ptr[i]; auto o = findMapValue(vdat.val, "o"); auto d = findMapValue(vdat.val, "d"); if (not o or not d) @@ -189,70 +241,85 @@ ParsedMessage::msgpack_unpack(msgpack::object msg) return; } - auto a = findMapValue(msg, "a"); - if (!a && !r && !e && !u) + if (!parsed.a && !parsed.r && !parsed.e && !parsed.u) throw msgpack::type_error(); - auto& req = a ? *a : (r ? *r : (u ? *u : *e)); + auto& req = parsed.a ? *parsed.a : (parsed.r ? *parsed.r : (parsed.u ? *parsed.u : *parsed.e)); - if (e) { - if (e->type != msgpack::type::ARRAY) + if (parsed.e) { + if (parsed.e->type != msgpack::type::ARRAY) throw msgpack::type_error(); - error_code = e->via.array.ptr[0].as<uint16_t>(); + error_code = parsed.e->via.array.ptr[0].as<uint16_t>(); } - if (auto t = findMapValue(req, "sid")) - socket_id = unpackTid(*t); - - if (auto rid = findMapValue(req, "id")) - id = {*rid}; + struct ParsedReq { + msgpack::object* values; + msgpack::object* fields; + msgpack::object* sa; + msgpack::object* want; + } parsedReq {}; - if (auto rh = findMapValue(req, "h")) - info_hash = {*rh}; - - if (auto rtarget = findMapValue(req, "target")) - target = {*rtarget}; - - if (auto rquery = findMapValue(req, "q")) - query.msgpack_unpack(*rquery); - - if (auto otoken = findMapValue(req, "token")) - token = unpackBlob(*otoken); - - if (auto vid = findMapValue(req, "vid")) - value_id = vid->as<Value::Id>(); - - if (auto rnodes4 = findMapValue(req, "n4")) - nodes4_raw = unpackBlob(*rnodes4); - - if (auto rnodes6 = findMapValue(req, "n6")) - nodes6_raw = unpackBlob(*rnodes6); + for (unsigned i = 0; i < req.via.map.size; i++) { + auto& o = req.via.map.ptr[i]; + if (o.key.type != msgpack::type::STR) + continue; + auto key = o.key.as<std::string>(); + if (key == KEY_REQ_SID) + socket_id = unpackTid(o.val); + else if (key == KEY_REQ_ID) + id = {o.val}; + else if (key == KEY_REQ_H) + info_hash = {o.val}; + else if (key == KEY_REQ_TARGET) + target = {o.val}; + else if (key == KEY_REQ_QUERY) + query.msgpack_unpack(o.val); + else if (key == KEY_REQ_TOKEN) + token = unpackBlob(o.val); + else if (key == KEY_REQ_VALUE_ID) + value_id = o.val.as<Value::Id>(); + else if (key == KEY_REQ_NODES4) + nodes4_raw = unpackBlob(o.val); + else if (key == KEY_REQ_NODES6) + nodes6_raw = unpackBlob(o.val); + else if (key == KEY_REQ_ADDRESS) + parsedReq.sa = &o.val; + else if (key == KEY_REQ_CREATION) + created = from_time_t(o.val.as<std::time_t>()); + else if (key == KEY_REQ_VALUES) + parsedReq.values = &o.val; + else if (key == KEY_REQ_EXPIRED) + expired_values = o.val.as<decltype(expired_values)>(); + else if (key == KEY_REQ_REFRESHED) + refreshed_values = o.val.as<decltype(refreshed_values)>(); + else if (key == KEY_REQ_FIELDS) + parsedReq.fields = &o.val; + else if (key == KEY_REQ_WANT) + parsedReq.want = &o.val; + } - if (auto sa = findMapValue(req, "sa")) { - if (sa->type != msgpack::type::BIN) + if (parsedReq.sa) { + if (parsedReq.sa->type != msgpack::type::BIN) throw msgpack::type_error(); - auto l = sa->via.bin.size; + auto l = parsedReq.sa->via.bin.size; if (l == sizeof(in_addr)) { addr.setFamily(AF_INET); auto& a = addr.getIPv4(); a.sin_port = 0; - std::copy_n(sa->via.bin.ptr, l, (char*)&a.sin_addr); + std::copy_n(parsedReq.sa->via.bin.ptr, l, (char*)&a.sin_addr); } else if (l == sizeof(in6_addr)) { addr.setFamily(AF_INET6); auto& a = addr.getIPv6(); a.sin6_port = 0; - std::copy_n(sa->via.bin.ptr, l, (char*)&a.sin6_addr); + std::copy_n(parsedReq.sa->via.bin.ptr, l, (char*)&a.sin6_addr); } } else addr = {}; - if (auto rcreated = findMapValue(req, "c")) - created = from_time_t(rcreated->as<std::time_t>()); - - if (auto rvalues = findMapValue(req, "values")) { - if (rvalues->type != msgpack::type::ARRAY) + if (parsedReq.values) { + if (parsedReq.values->type != msgpack::type::ARRAY) throw msgpack::type_error(); - for (size_t i = 0; i < rvalues->via.array.size; i++) { - auto& packed_v = rvalues->via.array.ptr[i]; + for (size_t i = 0; i < parsedReq.values->via.array.size; i++) { + auto& packed_v = parsedReq.values->via.array.ptr[i]; if (packed_v.type == msgpack::type::POSITIVE_INTEGER) { // Skip oversize values with a small margin for header overhead if (packed_v.via.u64 > MAX_VALUE_SIZE + 32) @@ -260,16 +327,16 @@ ParsedMessage::msgpack_unpack(msgpack::object msg) value_parts.emplace(i, std::make_pair(packed_v.via.u64, Blob{})); } else { try { - values.emplace_back(std::make_shared<Value>(rvalues->via.array.ptr[i])); + values.emplace_back(std::make_shared<Value>(parsedReq.values->via.array.ptr[i])); } catch (const std::exception& e) { //DHT_LOG_WARN("Error reading value: %s", e.what()); } } } - } else if (auto raw_fields = findMapValue(req, "fields")) { - if (auto rfields = findMapValue(*raw_fields, "f")) { + } else if (parsedReq.fields) { + if (auto rfields = findMapValue(*parsedReq.fields, "f")) { auto vfields = rfields->as<std::set<Value::Field>>(); - if (auto rvalues = findMapValue(*raw_fields, "v")) { + if (auto rvalues = findMapValue(*parsedReq.fields, "v")) { if (rvalues->type != msgpack::type::ARRAY) throw msgpack::type_error(); size_t val_num = rvalues->via.array.size / vfields.size(); @@ -284,18 +351,14 @@ ParsedMessage::msgpack_unpack(msgpack::object msg) } else { throw msgpack::type_error(); } - } else if (auto raw_fields = findMapValue(req, "exp")) { - expired_values = raw_fields->as<decltype(expired_values)>(); - } else if (auto raw_fields = findMapValue(req, "re")) { - refreshed_values = raw_fields->as<decltype(refreshed_values)>(); } - if (auto w = findMapValue(req, "w")) { - if (w->type != msgpack::type::ARRAY) + if (parsedReq.want) { + if (parsedReq.want->type != msgpack::type::ARRAY) throw msgpack::type_error(); want = 0; - for (unsigned i=0; i<w->via.array.size; i++) { - auto& val = w->via.array.ptr[i]; + for (unsigned i=0; i<parsedReq.want->via.array.size; i++) { + auto& val = parsedReq.want->via.array.ptr[i]; try { auto w = val.as<sa_family_t>(); if (w == AF_INET)