Skip to content
Snippets Groups Projects
Commit d3b9c4b7 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

network engine: improve node packing

parent d26a34f4
No related branches found
No related tags found
No related merge requests found
...@@ -477,12 +477,13 @@ private: ...@@ -477,12 +477,13 @@ private:
const Blob& nodes6, const Blob& nodes6,
const std::vector<std::shared_ptr<Value>>& st, const std::vector<std::shared_ptr<Value>>& st,
const Blob& token); const Blob& token);
unsigned insertClosestNode(uint8_t *nodes, unsigned numnodes, const InfoHash& id, const Node& n); Blob bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::shared_ptr<Node>>& nodes);
std::pair<Blob, Blob> bufferNodes(sa_family_t af, std::pair<Blob, Blob> bufferNodes(sa_family_t af,
const InfoHash& id, const InfoHash& id,
want_t want, want_t want,
const std::vector<std::shared_ptr<Node>>& nodes, std::vector<std::shared_ptr<Node>>& nodes,
const std::vector<std::shared_ptr<Node>>& nodes6); std::vector<std::shared_ptr<Node>>& nodes6);
/* answer to a listen request */ /* answer to a listen request */
void sendListenConfirmation(const sockaddr* sa, socklen_t salen, TransId tid); void sendListenConfirmation(const sockaddr* sa, socklen_t salen, TransId tid);
/* answer to put request */ /* answer to put request */
......
...@@ -81,17 +81,6 @@ struct ParsedMessage { ...@@ -81,17 +81,6 @@ struct ParsedMessage {
NetworkEngine::RequestAnswer::RequestAnswer(ParsedMessage&& msg) NetworkEngine::RequestAnswer::RequestAnswer(ParsedMessage&& msg)
: ntoken(std::move(msg.token)), values(std::move(msg.values)), nodes4(std::move(msg.nodes4)), nodes6(std::move(msg.nodes6)) {} : ntoken(std::move(msg.token)), values(std::move(msg.values)), nodes4(std::move(msg.nodes4)), nodes6(std::move(msg.nodes6)) {}
/* Called whenever we send a request to a node, increases the ping count
and, if that reaches 3, sends a ping to a new candidate. */
/*void
NetworkEngine::pinged(Node& n)
{
const auto& now = scheduler.time();
if (not n.isExpired(now))
n.requested(now);
}*/
void void
NetworkEngine::tellListener(std::shared_ptr<Node> node, uint16_t rid, InfoHash hash, want_t want, NetworkEngine::tellListener(std::shared_ptr<Node> node, uint16_t rid, InfoHash hash, want_t want,
Blob ntoken, std::vector<std::shared_ptr<Node>> nodes, std::vector<std::shared_ptr<Node>> nodes6, Blob ntoken, std::vector<std::shared_ptr<Node>> nodes, std::vector<std::shared_ptr<Node>> nodes6,
...@@ -650,76 +639,54 @@ NetworkEngine::sendNodesValues(const sockaddr* sa, socklen_t salen, TransId tid, ...@@ -650,76 +639,54 @@ NetworkEngine::sendNodesValues(const sockaddr* sa, socklen_t salen, TransId tid,
send(buffer.data(), buffer.size(), 0, sa, salen); send(buffer.data(), buffer.size(), 0, sa, salen);
} }
unsigned Blob
NetworkEngine::insertClosestNode(uint8_t *nodes, unsigned numnodes, const InfoHash& id, const Node& n) NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::shared_ptr<Node>>& nodes)
{ {
unsigned i, size; std::sort(nodes.begin(), nodes.end(), [&](const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b){
return id.xorCmp(a->id, b->id) < 0;
if (n.ss.ss_family == AF_INET) });
size = HASH_LEN + sizeof(in_addr) + sizeof(in_port_t); // 26 size_t nnode = std::min<size_t>(TARGET_NODES, nodes.size());
else if (n.ss.ss_family == AF_INET6) Blob bnodes;
size = HASH_LEN + sizeof(in6_addr) + sizeof(in_port_t); // 38 if (af == AF_INET) {
else bnodes.resize(NODE4_INFO_BUF_LEN * nnode);
return numnodes; const constexpr size_t size = HASH_LEN + sizeof(in_addr) + sizeof(in_port_t); // 26
for (size_t i=0; i<nnode; i++) {
for (i = 0; i < numnodes; i++) { const Node& n = *nodes[i];
const InfoHash* nid = reinterpret_cast<const InfoHash*>(nodes + size * i);
if (InfoHash::cmp(n.id, *nid) == 0)
return numnodes;
if (id.xorCmp(n.id, *nid) < 0)
break;
}
if (i >= TARGET_NODES)
return numnodes;
if (numnodes < TARGET_NODES)
++numnodes;
if (i < numnodes - 1)
memmove(nodes + size * (i + 1), nodes + size * i, size * (numnodes - i - 1));
if (n.ss.ss_family == AF_INET) {
sockaddr_in *sin = (sockaddr_in*)&n.ss; sockaddr_in *sin = (sockaddr_in*)&n.ss;
memcpy(nodes + size * i, n.id.data(), HASH_LEN); auto dest = bnodes.data() + size * i;
memcpy(nodes + size * i + HASH_LEN, &sin->sin_addr, sizeof(in_addr)); memcpy(dest, n.id.data(), HASH_LEN);
memcpy(nodes + size * i + HASH_LEN + sizeof(in_addr), &sin->sin_port, 2); memcpy(dest + HASH_LEN, &sin->sin_addr, sizeof(in_addr));
} memcpy(dest + HASH_LEN + sizeof(in_addr), &sin->sin_port, 2);
else if (n.ss.ss_family == AF_INET6) { }
} else if (af == AF_INET6) {
bnodes.resize(NODE6_INFO_BUF_LEN * nnode);
const constexpr size_t size = HASH_LEN + sizeof(in6_addr) + sizeof(in_port_t); // 38
for (size_t i=0; i<nnode; i++) {
const Node& n = *nodes[i];
sockaddr_in6 *sin6 = (sockaddr_in6*)&n.ss; sockaddr_in6 *sin6 = (sockaddr_in6*)&n.ss;
memcpy(nodes + size * i, n.id.data(), HASH_LEN); auto dest = bnodes.data() + size * i;
memcpy(nodes + size * i + HASH_LEN, &sin6->sin6_addr, sizeof(in6_addr)); memcpy(dest, n.id.data(), HASH_LEN);
memcpy(nodes + size * i + HASH_LEN + sizeof(in6_addr), &sin6->sin6_port, 2); memcpy(dest + HASH_LEN, &sin6->sin6_addr, sizeof(in6_addr));
memcpy(dest + HASH_LEN + sizeof(in6_addr), &sin6->sin6_port, 2);
} }
}
return numnodes; return bnodes;
} }
std::pair<Blob, Blob> std::pair<Blob, Blob>
NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, want_t want, NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, want_t want,
const std::vector<std::shared_ptr<Node>>& nodes, const std::vector<std::shared_ptr<Node>>& nodes6) std::vector<std::shared_ptr<Node>>& nodes4, std::vector<std::shared_ptr<Node>>& nodes6)
{ {
if (want < 0) if (want < 0)
want = af == AF_INET ? WANT4 : WANT6; want = af == AF_INET ? WANT4 : WANT6;
auto buff = [=](Blob& nodes, const InfoHash& id, const std::vector<std::shared_ptr<Node>>& closest_nodes) {
size_t numnodes = 0;
for (const auto& n : closest_nodes)
numnodes = insertClosestNode(nodes.data(), numnodes, id, *n);
return numnodes;
};
Blob bnodes4; Blob bnodes4;
if (want & WANT4) { if (want & WANT4)
bnodes4.resize(NODE4_INFO_BUF_LEN * TARGET_NODES); bnodes4 = bufferNodes(AF_INET, id, nodes4);
bnodes4.resize(NODE4_INFO_BUF_LEN * buff(bnodes4, id, nodes));
}
Blob bnodes6; Blob bnodes6;
if (want & WANT6) { if (want & WANT6)
bnodes6.resize(NODE6_INFO_BUF_LEN * TARGET_NODES); bnodes6 = bufferNodes(AF_INET6, id, nodes6);
bnodes6.resize(NODE6_INFO_BUF_LEN * buff(bnodes6, id, nodes6));
}
return {std::move(bnodes4), std::move(bnodes6)}; return {std::move(bnodes4), std::move(bnodes6)};
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment