dht/node: don't allow more than 3 auth errors

This commit is contained in:
Simon Désaulniers committed 2016-09-23 19:27:59 -04:00
1 parent ca6aa6706d
commit 87cf6faedd
3 files changed
+23 -3

No files matched your search

+16
View File
@@ -50,6 +50,18 @@ struct Node {
std::string getAddrStr() const {
return addr.toString();
}
/**
* 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;
@@ -83,7 +95,11 @@ struct Node {
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};
std::list<std::weak_ptr<Request>> requests_ {};
unsigned auth_errors {0};
bool expired_ {false};
void clearPendingQueue() {
+4 -3
View File
@@ -408,9 +408,9 @@ struct Dht::SearchNode {
or not gs->second or not gs->second->pending()))
return time_point::min();
return ((gs != getStatus.cend() and gs->second and gs->second->pending())
or ack == acked.cend() or not ack->second or ack->second->pending()) ?
time_point::max() :
ack->second->reply_time + type.expiration - REANNOUNCE_MARGIN;
or ack == acked.cend() or not ack->second or ack->second->pending())
? time_point::max()
: ack->second->reply_time + type.expiration - REANNOUNCE_MARGIN;
}
/**
@@ -3000,6 +3000,7 @@ void
Dht::onError(std::shared_ptr<Request> req, DhtProtocolException e) {
if (e.getCode() == DhtProtocolException::UNAUTHORIZED) {
DHT_LOG.ERR("[node %s] token flush", req->node->toString().c_str());
req->node->authError();
network_engine.cancelRequest(req);
for (auto& srp : req->node->getFamily() == AF_INET ? searches4 : searches6) {
auto& sr = srp.second;
+3
View File
@@ -377,6 +377,9 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const SockAddr&
break;
}
case MessageType::Reply:
if (msg.type == MessageType::AnnounceValue or msg.type == MessageType::Listen)
req->node->authSuccess();
// erase before calling callback to make sure iterator is still valid
if (not req->persistent)
requests.erase(reqp);