My Project 3.2.0
C++ Distributed Hash Table
Loading...
Searching...
No Matches
node.h
1/*
2 * Copyright (C) 2014-2023 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#include "node_export.h"
26
27#include <list>
28#include <map>
29
30namespace dht {
31
32struct Node;
33namespace net {
34struct Request;
35struct Socket;
36struct RequestAnswer;
37} /* namespace net */
38
39using Tid = uint32_t;
40using SocketCb = std::function<void(const Sp<Node>&, net::RequestAnswer&&)>;
41struct Socket {
42 Socket() {}
43 Socket(SocketCb&& on_receive) :
44 on_receive(std::move(on_receive)) {}
45 SocketCb on_receive {};
46};
47
48struct Node {
49 const InfoHash id;
50
51 Node(const InfoHash& id, const SockAddr& addr, std::mt19937_64& rd, bool client=false);
52 Node(const InfoHash& id, SockAddr&& addr, std::mt19937_64& rd, bool client=false);
53 Node(const InfoHash& id, const sockaddr* sa, socklen_t salen, std::mt19937_64& rd)
54 : Node(id, SockAddr(sa, salen), rd) {}
55
56 const InfoHash& getId() const {
57 return id;
58 }
59 const SockAddr& getAddr() const { return addr; }
60 std::string getAddrStr() const {
61 return addr.toString();
62 }
63 bool isClient() const { return is_client; }
64 bool isIncoming() { return time > reply_time; }
65
66 const time_point& getTime() const { return time; }
67 const time_point& getReplyTime() const { return reply_time; }
68 void setTime(const time_point& t) { time = t; }
69
75 void authError() {
76 if (++auth_errors > MAX_AUTH_ERRORS)
77 setExpired();
78 }
79 void authSuccess() { auth_errors = 0; }
80
81 bool isExpired() const { return expired_; }
82 bool isGood(time_point now) const;
83 bool isPendingMessage() const;
84 size_t getPendingMessageCount() const;
85
86 bool isOld(const time_point& now) const {
87 return time + NODE_EXPIRE_TIME < now;
88 }
89 bool isRemovable(const time_point& now) const {
90 return isExpired() and isOld(now);
91 }
92
93 NodeExport exportNode() const {
94 NodeExport ne;
95 ne.id = id;
96 ne.addr = addr;
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}
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:75