My Project 2.4.4
C++ Distributed Hash Table
Loading...
Searching...
No Matches
node.h
1/*
2 * Copyright (C) 2014-2022 Savoir-faire Linux Inc.
3 * Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
4 * Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include "infohash.h" // includes socket structures
23#include "utils.h"
24#include "sockaddr.h"
25
26#include <list>
27#include <map>
28
29namespace dht {
30
31struct Node;
32namespace net {
33struct Request;
34struct Socket;
35struct RequestAnswer;
36} /* namespace net */
37
38using Tid = uint32_t;
39using SocketCb = std::function<void(const Sp<Node>&, net::RequestAnswer&&)>;
40struct Socket {
41 Socket() {}
42 Socket(SocketCb&& on_receive) :
43 on_receive(std::move(on_receive)) {}
44 SocketCb on_receive {};
45};
46
47struct Node {
48 const InfoHash id;
49
50 Node(const InfoHash& id, const SockAddr& addr, std::mt19937_64& rd, bool client=false);
51 Node(const InfoHash& id, SockAddr&& addr, std::mt19937_64& rd, bool client=false);
52 Node(const InfoHash& id, const sockaddr* sa, socklen_t salen, std::mt19937_64& rd)
53 : Node(id, SockAddr(sa, salen), rd) {}
54
55 InfoHash getId() const {
56 return id;
57 }
58 const SockAddr& getAddr() const { return addr; }
59 std::string getAddrStr() const {
60 return addr.toString();
61 }
62 bool isClient() const { return is_client; }
63 bool isIncoming() { return time > reply_time; }
64
65 const time_point& getTime() const { return time; }
66 const time_point& getReplyTime() const { return reply_time; }
67 void setTime(const time_point& t) { time = t; }
68
74 void authError() {
75 if (++auth_errors > MAX_AUTH_ERRORS)
76 setExpired();
77 }
78 void authSuccess() { auth_errors = 0; }
79
80 bool isExpired() const { return expired_; }
81 bool isGood(time_point now) const;
82 bool isPendingMessage() const;
83 size_t getPendingMessageCount() const;
84
85 bool isOld(const time_point& now) const {
86 return time + NODE_EXPIRE_TIME < now;
87 }
88 bool isRemovable(const time_point& now) const {
89 return isExpired() and isOld(now);
90 }
91
92 NodeExport exportNode() const {
93 NodeExport ne;
94 ne.id = id;
95 ne.sslen = addr.getLength();
96 std::memcpy(&ne.ss, addr.get(), ne.sslen);
97 return ne;
98 }
99 sa_family_t getFamily() const { return addr.getFamily(); }
100
101 void update(const SockAddr&);
102
103 void requested(const Sp<net::Request>& req);
104 void received(time_point now, const Sp<net::Request>& req);
105 Sp<net::Request> getRequest(Tid tid);
106 void cancelRequest(const Sp<net::Request>& req);
107
108 void setExpired();
109
119 Tid openSocket(SocketCb&& cb);
120
121 Sp<Socket> getSocket(Tid id);
122
128 void closeSocket(Tid id);
129
133 void reset() { expired_ = false; reply_time = time_point::min(); }
134
140 Tid getNewTid() {
141 ++transaction_id;
142 return transaction_id ? ++transaction_id : transaction_id;
143 }
144
145 std::string toString() const;
146
147 OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Node& h);
148
149 static constexpr const std::chrono::minutes NODE_GOOD_TIME {120};
150
151 /* The time after which we consider a node to be expirable. */
152 static constexpr const std::chrono::minutes NODE_EXPIRE_TIME {10};
153
154 /* Time for a request to timeout */
155 static constexpr const std::chrono::seconds MAX_RESPONSE_TIME {1};
156
157private:
158 /* Number of times we accept authentication errors from this node. */
159 static const constexpr unsigned MAX_AUTH_ERRORS {3};
160
161 SockAddr addr;
162 bool is_client {false};
163 time_point time {time_point::min()}; /* last time eared about */
164 time_point reply_time {time_point::min()}; /* time of last correct reply received */
165 unsigned auth_errors {0};
166 bool expired_ {false};
167 Tid transaction_id;
168 using TransactionDist = std::uniform_int_distribution<decltype(transaction_id)>;
169
170 std::map<Tid, Sp<net::Request>> requests_ {};
171 std::map<Tid, Sp<Socket>> sockets_;
172};
173
174}
const sockaddr * get() const
Definition: sockaddr.h:218
socklen_t getLength() const
Definition: sockaddr.h:205
sa_family_t getFamily() const
Definition: sockaddr.h:123
Definition: callbacks.h:35
Definition: node.h:47
Tid getNewTid()
Definition: node.h:140
void closeSocket(Tid id)
void reset()
Definition: node.h:133
Tid openSocket(SocketCb &&cb)
void authError()
Definition: node.h:74