/usr/include/opendht/node.h is in libopendht-dev 1.6.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | /*
* Copyright (C) 2014-2017 Savoir-faire Linux Inc.
* Author(s) : Adrien BĂ©raud <adrien.beraud@savoirfairelinux.com>
* Simon DĂ©saulniers <simon.desaulniers@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "infohash.h" // includes socket structures
#include "utils.h"
#include "sockaddr.h"
#include <list>
#include <map>
namespace dht {
struct Node;
namespace net {
struct Request;
struct Socket;
struct RequestAnswer;
} /* namespace net */
using Tid = uint32_t;
using SocketCb = std::function<void(const Sp<Node>&, net::RequestAnswer&&)>;
struct Socket {
Socket() {}
Socket(SocketCb&& on_receive) :
on_receive(std::move(on_receive)) {}
SocketCb on_receive {};
};
struct Node {
const InfoHash id;
Node(const InfoHash& id, const SockAddr& addr, bool client=false);
Node(const InfoHash& id, const sockaddr* sa, socklen_t salen)
: Node(id, SockAddr(sa, salen)) {}
InfoHash getId() const {
return id;
}
const SockAddr& getAddr() const { return addr; }
std::string getAddrStr() const {
return addr.toString();
}
bool isClient() const { return is_client; }
bool isIncoming() { return time > reply_time; }
const time_point& getTime() const { return time; }
const time_point& getReplyTime() const { return reply_time; }
void setTime(const time_point& t) { time = t; }
/**
* Makes notice about an additionnal authentication error with this node. Up
* to MAX_AUTH_ERRORS errors are accepted in order to let the node recover.
* Upon this limit, the node expires.
*/
void authError() {
if (++auth_errors > MAX_AUTH_ERRORS)
setExpired();
}
void authSuccess() { auth_errors = 0; }
bool isExpired() const { return expired_; }
bool isGood(time_point now) const;
bool isPendingMessage() const;
size_t getPendingMessageCount() const;
bool isOld(const time_point& now) const {
return time + NODE_EXPIRE_TIME < now;
}
bool isRemovable(const time_point& now) const {
return isExpired() and isOld(now);
}
NodeExport exportNode() const {
NodeExport ne;
ne.id = id;
ne.sslen = addr.getLength();
std::memcpy(&ne.ss, addr.get(), ne.sslen);
return ne;
}
sa_family_t getFamily() const { return addr.getFamily(); }
void update(const SockAddr&);
void requested(const Sp<net::Request>& req);
void received(time_point now, const Sp<net::Request>& req);
Sp<net::Request> getRequest(Tid tid);
void cancelRequest(const Sp<net::Request>& req);
void setExpired();
/**
* Opens a socket on which a node will be able allowed to write for further
* additionnal updates following the response to a previous request.
*
* @param node The node which will be allowed to write on this socket.
* @param cb The callback to execute once updates arrive on the socket.
*
* @return the socket.
*/
Tid openSocket(SocketCb&& cb);
Sp<Socket> getSocket(Tid id);
/**
* Closes a socket so that no further data will be red on that socket.
*
* @param socket The socket to close.
*/
void closeSocket(Tid id);
/**
* Resets the state of the node so it's not expired anymore.
*/
void reset() { expired_ = false; reply_time = time_point::min(); }
/**
* Generates a new request id, skipping the invalid id.
*
* @return the new id.
*/
Tid getNewTid() {
++transaction_id;
return transaction_id ? ++transaction_id : transaction_id;
}
std::string toString() const;
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Node& h);
static constexpr const std::chrono::minutes NODE_GOOD_TIME {120};
/* The time after which we consider a node to be expirable. */
static constexpr const std::chrono::minutes NODE_EXPIRE_TIME {10};
/* Time for a request to timeout */
static constexpr const std::chrono::seconds MAX_RESPONSE_TIME {1};
private:
/* Number of times we accept authentication errors from this node. */
static const constexpr unsigned MAX_AUTH_ERRORS {3};
SockAddr addr;
bool is_client {false};
time_point time {time_point::min()}; /* last time eared about */
time_point reply_time {time_point::min()}; /* time of last correct reply received */
unsigned auth_errors {0};
bool expired_ {false};
Tid transaction_id;
using TransactionDist = std::uniform_int_distribution<decltype(transaction_id)>;
std::map<Tid, Sp<net::Request>> requests_ {};
std::map<Tid, Sp<Socket>> sockets_;
};
}
|