mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-08-07 22:02:32 -04:00
Merging branches/v0.5-peernet/libbitdht (Merging r4237 through r4353 into '.')
There are many significant improvements to the DHT here. See commit logs on v0.5-peernet branch for details. This is not the final merge, but brings over the majority of expected v0.5-peernet/libbitdht changes git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4354 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
f517442989
commit
fff40eceac
40 changed files with 6843 additions and 746 deletions
374
libbitdht/src/bitdht/bdquerymgr.cc
Normal file
374
libbitdht/src/bitdht/bdquerymgr.cc
Normal file
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* bitdht/bdnode.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bitdht/bdquerymgr.h"
|
||||
#include "bitdht/bdnode.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#define BITDHT_QUERY_START_PEERS 10
|
||||
#define BITDHT_QUERY_NEIGHBOUR_PEERS 8
|
||||
#define BITDHT_MAX_REMOTE_QUERY_AGE 10
|
||||
|
||||
/****
|
||||
* #define DEBUG_NODE_MULTIPEER 1
|
||||
* #define DEBUG_NODE_MSGS 1
|
||||
* #define DEBUG_NODE_ACTIONS 1
|
||||
|
||||
* #define DEBUG_NODE_MSGIN 1
|
||||
* #define DEBUG_NODE_MSGOUT 1
|
||||
***/
|
||||
|
||||
//#define DEBUG_NODE_MSGS 1
|
||||
|
||||
|
||||
bdQueryManager::bdQueryManager(bdSpace *space, bdDhtFunctions *fns, bdNodePublisher *pub)
|
||||
:mNodeSpace(space), mFns(fns), mPub(pub)
|
||||
{
|
||||
}
|
||||
|
||||
/***** Startup / Shutdown ******/
|
||||
void bdQueryManager::shutdownQueries()
|
||||
{
|
||||
/* clear the queries */
|
||||
std::list<bdQuery *>::iterator it;
|
||||
for(it = mLocalQueries.begin(); it != mLocalQueries.end();it++)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
mLocalQueries.clear();
|
||||
}
|
||||
|
||||
|
||||
void bdQueryManager::printQueries()
|
||||
{
|
||||
std::cerr << "bdQueryManager::printQueries()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
int i = 0;
|
||||
std::list<bdQuery *>::iterator it;
|
||||
for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++, i++)
|
||||
{
|
||||
fprintf(stderr, "Query #%d:\n", i);
|
||||
(*it)->printQuery();
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int bdQueryManager::iterateQueries(int maxQueries)
|
||||
{
|
||||
#ifdef DEBUG_NODE_MULTIPEER
|
||||
std::cerr << "bdQueryManager::iterateQueries() of Peer: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &mOwnId);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* allow each query to send up to one query... until maxMsgs has been reached */
|
||||
int numQueries = mLocalQueries.size();
|
||||
int sentQueries = 0;
|
||||
int i = 0;
|
||||
|
||||
bdId id;
|
||||
bdNodeId targetNodeId;
|
||||
|
||||
while((i < numQueries) && (sentQueries < maxQueries))
|
||||
{
|
||||
bdQuery *query = mLocalQueries.front();
|
||||
mLocalQueries.pop_front();
|
||||
mLocalQueries.push_back(query);
|
||||
|
||||
/* go through the possible queries */
|
||||
if (query->nextQuery(id, targetNodeId))
|
||||
{
|
||||
#ifdef DEBUG_NODE_MSGS
|
||||
std::cerr << "bdQueryManager::iteration() send_query(";
|
||||
mFns->bdPrintId(std::cerr, &id);
|
||||
std::cerr << ",";
|
||||
mFns->bdPrintNodeId(std::cerr, &targetNodeId);
|
||||
std::cerr << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
mPub->send_query(&id, &targetNodeId);
|
||||
sentQueries++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NODE_ACTIONS
|
||||
std::cerr << "bdQueryManager::iteration() maxMsgs: " << maxMsgs << " sentPings: " << sentPings;
|
||||
std::cerr << " / " << allowedPings;
|
||||
std::cerr << " sentQueries: " << sentQueries;
|
||||
std::cerr << " / " << numQueries;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
//printQueries();
|
||||
|
||||
return sentQueries;
|
||||
}
|
||||
|
||||
|
||||
bool bdQueryManager::checkPotentialPeer(bdId *id, bdId *src)
|
||||
{
|
||||
bool isWorthyPeer = false;
|
||||
/* also push to queries */
|
||||
std::list<bdQuery *>::iterator it;
|
||||
for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++)
|
||||
{
|
||||
if ((*it)->addPotentialPeer(id, src, 0))
|
||||
{
|
||||
isWorthyPeer = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isWorthyPeer)
|
||||
{
|
||||
isWorthyPeer = checkWorthyPeerSources(src);
|
||||
}
|
||||
|
||||
return isWorthyPeer;
|
||||
}
|
||||
|
||||
|
||||
void bdQueryManager::addPeer(const bdId *id, uint32_t peerflags)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_NODE_ACTIONS
|
||||
fprintf(stderr, "bdQueryManager::addPeer(");
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
fprintf(stderr, ")\n");
|
||||
#endif
|
||||
|
||||
/* iterate through queries */
|
||||
std::list<bdQuery *>::iterator it;
|
||||
for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++)
|
||||
{
|
||||
(*it)->addPeer(id, peerflags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************ Query Details *************************/
|
||||
void bdQueryManager::addQuery(const bdNodeId *id, uint32_t qflags)
|
||||
{
|
||||
|
||||
std::list<bdId> startList;
|
||||
std::multimap<bdMetric, bdId> nearest;
|
||||
std::multimap<bdMetric, bdId>::iterator it;
|
||||
|
||||
mNodeSpace->find_nearest_nodes(id, BITDHT_QUERY_START_PEERS, nearest);
|
||||
|
||||
fprintf(stderr, "bdQueryManager::addQuery(");
|
||||
mFns->bdPrintNodeId(std::cerr, id);
|
||||
fprintf(stderr, ")\n");
|
||||
|
||||
for(it = nearest.begin(); it != nearest.end(); it++)
|
||||
{
|
||||
startList.push_back(it->second);
|
||||
}
|
||||
|
||||
bdQuery *query = new bdQuery(id, startList, qflags, mFns);
|
||||
mLocalQueries.push_back(query);
|
||||
}
|
||||
|
||||
|
||||
void bdQueryManager::clearQuery(const bdNodeId *rmId)
|
||||
{
|
||||
std::list<bdQuery *>::iterator it;
|
||||
for(it = mLocalQueries.begin(); it != mLocalQueries.end();)
|
||||
{
|
||||
if ((*it)->mId == *rmId)
|
||||
{
|
||||
bdQuery *query = (*it);
|
||||
it = mLocalQueries.erase(it);
|
||||
delete query;
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bdQueryManager::QueryStatus(std::map<bdNodeId, bdQueryStatus> &statusMap)
|
||||
{
|
||||
std::list<bdQuery *>::iterator it;
|
||||
for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++)
|
||||
{
|
||||
bdQueryStatus status;
|
||||
status.mStatus = (*it)->mState;
|
||||
status.mQFlags = (*it)->mQueryFlags;
|
||||
(*it)->result(status.mResults);
|
||||
statusMap[(*it)->mId] = status;
|
||||
}
|
||||
}
|
||||
|
||||
int bdQueryManager::QuerySummary(const bdNodeId *id, bdQuerySummary &query)
|
||||
{
|
||||
std::list<bdQuery *>::iterator it;
|
||||
for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++)
|
||||
{
|
||||
if ((*it)->mId == *id)
|
||||
{
|
||||
query.mId = (*it)->mId;
|
||||
query.mLimit = (*it)->mLimit;
|
||||
query.mState = (*it)->mState;
|
||||
query.mQueryTS = (*it)->mQueryTS;
|
||||
query.mQueryFlags = (*it)->mQueryFlags;
|
||||
query.mSearchTime = (*it)->mSearchTime;
|
||||
query.mClosest = (*it)->mClosest;
|
||||
query.mPotentialPeers = (*it)->mPotentialPeers;
|
||||
query.mProxiesUnknown = (*it)->mProxiesUnknown;
|
||||
query.mProxiesFlagged = (*it)->mProxiesFlagged;
|
||||
query.mQueryIdlePeerRetryPeriod = (*it)->mQueryIdlePeerRetryPeriod;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Extract Results from Peer Queries */
|
||||
|
||||
#define BDQRYMGR_RESULTS 1
|
||||
#define BDQRYMGR_PROXIES 2
|
||||
#define BDQRYMGR_POTPROXIES 3
|
||||
|
||||
int bdQueryManager::getResults(bdNodeId *target, std::list<bdId> &answer, int querytype)
|
||||
{
|
||||
|
||||
/* grab any peers from any existing query */
|
||||
int results = 0;
|
||||
std::list<bdQuery *>::iterator qit;
|
||||
for(qit = mLocalQueries.begin(); qit != mLocalQueries.end(); qit++)
|
||||
{
|
||||
if (!((*qit)->mId == (*target)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NODE_CONNECTION
|
||||
std::cerr << "bdQueryManager::getResults() Found Matching Query";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
switch(querytype)
|
||||
{
|
||||
default:
|
||||
case BDQRYMGR_RESULTS:
|
||||
results = (*qit)->result(answer);
|
||||
break;
|
||||
case BDQRYMGR_PROXIES:
|
||||
results = (*qit)->proxies(answer);
|
||||
break;
|
||||
case BDQRYMGR_POTPROXIES:
|
||||
results = (*qit)->potentialProxies(answer);
|
||||
break;
|
||||
}
|
||||
/* will only be one matching query.. so end loop */
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int bdQueryManager::result(bdNodeId *target, std::list<bdId> &answer)
|
||||
{
|
||||
return getResults(target, answer, BDQRYMGR_RESULTS);
|
||||
}
|
||||
|
||||
int bdQueryManager::proxies(bdNodeId *target, std::list<bdId> &answer)
|
||||
{
|
||||
return getResults(target, answer, BDQRYMGR_PROXIES);
|
||||
}
|
||||
|
||||
int bdQueryManager::potentialProxies(bdNodeId *target, std::list<bdId> &answer)
|
||||
{
|
||||
return getResults(target, answer, BDQRYMGR_POTPROXIES);
|
||||
}
|
||||
|
||||
|
||||
/************ WORTHY PEERS **********/
|
||||
|
||||
#define MAX_WORTHY_PEER_AGE 15
|
||||
|
||||
void bdQueryManager::addWorthyPeerSource(bdId *src)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
bdPeer peer;
|
||||
peer.mPeerId = *src;
|
||||
peer.mFoundTime = now;
|
||||
|
||||
std::cerr << "bdQueryManager::addWorthyPeerSource(";
|
||||
mFns->bdPrintId(std::cerr, src);
|
||||
std::cerr << ")" << std::endl;
|
||||
#ifdef DEBUG_NODE_ACTIONS
|
||||
#endif
|
||||
|
||||
mWorthyPeerSources.push_back(peer);
|
||||
}
|
||||
|
||||
bool bdQueryManager::checkWorthyPeerSources(bdId *src)
|
||||
{
|
||||
if (!src)
|
||||
return false;
|
||||
|
||||
time_t now = time(NULL);
|
||||
std::list<bdPeer>::iterator it;
|
||||
for(it = mWorthyPeerSources.begin(); it != mWorthyPeerSources.end(); )
|
||||
{
|
||||
if (now - it->mFoundTime > MAX_WORTHY_PEER_AGE)
|
||||
{
|
||||
std::cerr << "bdQueryManager::checkWorthyPeerSource() Discard old Source: ";
|
||||
mFns->bdPrintId(std::cerr, &(it->mPeerId));
|
||||
std::cerr << std::endl;
|
||||
|
||||
it = mWorthyPeerSources.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (it->mPeerId == *src)
|
||||
{
|
||||
//std::cerr << "bdQueryManager::checkWorthyPeerSource(";
|
||||
//mFns->bdPrintId(std::cerr, src);
|
||||
//std::cerr << ") = true" << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue