Lots of improvements / bugfixes to BitDHT

* Added "WorthyPeerSources" to allow pinging of potential BitDHT peers.
 * Added SearchForLocalNet() to find BitDHT peers if local net is small.
 * Fixed up printing of Statistics.
 * Increased MIN_START_PROXY_COUNT => 10
 * Improved Query Search, by extending the bucket size, but only worrying about the first N.
 * Delayed QueryFinish until peers have had time to respond.
 * Added Random Searchs 20% of the time in QueryRandomLocalNet. (increase fill of bitDht peers).



git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-peernet@4349 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2011-06-28 15:54:12 +00:00
parent 3a7f95812d
commit 70ff44f9ef
11 changed files with 218 additions and 26 deletions

View File

@ -99,13 +99,14 @@ void bdAccount::doStats()
void bdAccount::printStats(std::ostream &out)
{
int i;
out << " Send Recv: ";
out << std::endl;
for(i = 0; i < mNoStats; i++)
{
out << " Send Recv: ";
out << std::endl;
out << "Send " << mLabel[i] << " : " << std::setw(10) << mLpfOut[i];
out << "Recv " << mLabel[i] << " : " << std::setw(10) << mLpfRecv[i];
out << "Send" << mLabel[i] << " : " << std::setw(10) << mLpfOut[i];
out << " ";
out << "Recv" << mLabel[i] << " : " << std::setw(10) << mLpfRecv[i];
out << std::endl;
}
}

View File

@ -243,8 +243,8 @@ int bdConnectManager::killConnectionRequest(struct sockaddr_in *laddr, bdNodeId
#define MIN_START_DIRECT_COUNT 1
#define MIN_START_PROXY_COUNT 3
#define MIN_START_DIRECT_COUNT 1
#define MIN_START_PROXY_COUNT 10
#define CONNECT_NUM_PROXY_ATTEMPTS 10

View File

@ -269,10 +269,12 @@ class bdQuerySummary
#define BITDHT_QUERY_SUCCESS 6
/* Query Flags */
#define BITDHT_QFLAGS_NONE 0
#define BITDHT_QFLAGS_DISGUISE 1
#define BITDHT_QFLAGS_DO_IDLE 2
#define BITDHT_QFLAGS_INTERNAL 4 // means it runs through startup.
#define BITDHT_QFLAGS_NONE 0x0000
#define BITDHT_QFLAGS_DISGUISE 0x0001
#define BITDHT_QFLAGS_DO_IDLE 0x0002
#define BITDHT_QFLAGS_INTERNAL 0x0004 // means it runs through startup.
#define BITDHT_QFLAGS_QUICK 0x0008 // ONE Request per peer.
#define BITDHT_QFLAGS_UPDATES 0x0010 // Do regular updates.
/* Connect Callback Flags */
#define BITDHT_CONNECT_CB_AUTH 1

View File

@ -44,12 +44,12 @@
#include "bitdht/bencode.h"
#include "bitdht/bdquerymgr.h"
#include <algorithm>
#include <sstream>
#include <iomanip>
#include "util/bdnet.h"
#include "util/bdrandom.h"
/***
* #define DEBUG_MGR 1
@ -113,6 +113,10 @@ int bdNodeManager::startDht()
mMode = BITDHT_MGR_STATE_STARTUP;
mModeTS = now;
mStartTS = now;
mSearchingDone = false;
mSearchTS = now;
return 1;
}
@ -347,6 +351,26 @@ void bdNodeManager::iteration()
/* run a random search for ourselves, from own App DHT peer */
QueryRandomLocalNet();
#define SEARCH_MAX_SIZE 10
if (mBdNetworkSize < SEARCH_MAX_SIZE)
{
std::cerr << "Local Netsize: " << mBdNetworkSize << " to small...searching";
std::cerr << std::endl;
/* if the network size is very small */
SearchForLocalNet();
mSearchingDone = false;
}
else
{
if (!mSearchingDone)
{
mSearchingDone = true;
mSearchTS = now;
std::cerr << "Completed LocalNet Search in : " << mSearchTS-mStartTS;
std::cerr << std::endl;
}
}
#ifdef DEBUG_MGR
std::cerr << "bdNodeManager::iteration(): REFRESH ";
@ -354,6 +378,9 @@ void bdNodeManager::iteration()
#endif
status();
mAccount.printStats(std::cerr);
}
break;
@ -395,7 +422,10 @@ void bdNodeManager::iteration()
/* NB: This is a bit of a hack, the code is duplicated from bdnode & bdquery.
* should use fn calls into their functions for good generality
*/
void bdNodeManager::QueryRandomLocalNet()
#define RANDOM_SEARCH_FRAC (0.2)
int bdNodeManager::QueryRandomLocalNet()
{
bdId id;
bdNodeId targetNodeId;
@ -403,27 +433,102 @@ void bdNodeManager::QueryRandomLocalNet()
uint32_t withFlag = LOCAL_NET_FLAG;
if (mNodeSpace.findRandomPeerWithFlag(id, withFlag))
{
/* calculate mid point */
mFns->bdRandomMidId(&mOwnId, &(id.id), &targetNodeId);
/* if we've got a very small network size... then ask them about a random peer.
* (so we get there 159/158 boxes!
*/
bool isRandom = false;
if ((mBdNetworkSize < SEARCH_MAX_SIZE) || (RANDOM_SEARCH_FRAC > bdRandom::random_f32()))
{
bdStdRandomNodeId(&targetNodeId);
isRandom = true;
}
else
{
/* calculate mid point */
mFns->bdRandomMidId(&mOwnId, &(id.id), &targetNodeId);
}
/* do standard find_peer message */
mQueryMgr->addWorthyPeerSource(&id); /* Tell BitDHT that we really want to ping their peers */
send_query(&id, &targetNodeId);
#ifdef DEBUG_NODE_MSGS
std::cerr << "bdNodeManager::QueryRandomLocalNet() Querying : ";
mFns->bdPrintId(std::cerr, &id);
std::cerr << " searching for : ";
mFns->bdPrintNodeId(std::cerr, &targetNodeId);
std::cerr << std::endl;
if (isRandom)
{
std::cerr << "bdNodeManager::QueryRandomLocalNet() Search is Random!";
std::cerr << std::endl;
}
#ifdef DEBUG_NODE_MSGS
#endif
return 1;
}
else
{
#ifdef DEBUG_NODE_MSGS
#endif
std::cerr << "bdNodeManager::QueryRandomLocalNet() No LocalNet Peer Found";
std::cerr << std::endl;
}
return 0;
}
void bdNodeManager::SearchForLocalNet()
{
#ifdef DEBUG_MGR
#endif
std::cerr << "bdNodeManager::SearchForLocalNet()";
std::cerr << std::endl;
/* Check how many "Search Queries" we've got going. */
/* check queries */
std::map<bdNodeId, bdQueryStatus>::iterator it;
std::map<bdNodeId, bdQueryStatus> queryStatus;
mQueryMgr->QueryStatus(queryStatus);
int numSearchQueries = 0;
for(it = queryStatus.begin(); it != queryStatus.end(); it++)
{
if (it->second.mQFlags & BITDHT_QFLAGS_INTERNAL)
{
std::cerr << "bdNodeManager::SearchForLocalNet() Existing Internal Search: ";
mFns->bdPrintNodeId(std::cerr, &(it->first));
std::cerr << std::endl;
numSearchQueries++;
}
}
#define MAX_SEARCH_QUERIES 5
for(;numSearchQueries < MAX_SEARCH_QUERIES; numSearchQueries++)
{
/* install a new query */
bdNodeId targetNodeId;
bdStdRandomNodeId(&targetNodeId);
uint32_t qflags = BITDHT_QFLAGS_INTERNAL | BITDHT_QFLAGS_DISGUISE;
mQueryMgr->addQuery(&targetNodeId, qflags);
#ifdef DEBUG_NODE_MSGS
#endif
std::cerr << "bdNodeManager::SearchForLocalNet() Adding New Internal Search: ";
mFns->bdPrintNodeId(std::cerr, &(targetNodeId));
std::cerr << std::endl;
}
}

View File

@ -152,7 +152,9 @@ int checkStatus();
int checkPingStatus();
int SearchOutOfDate();
void startQueries();
void QueryRandomLocalNet();
int QueryRandomLocalNet();
void SearchForLocalNet();
std::map<bdNodeId, bdQueryPeer> mActivePeers;
std::list<BitDhtCallback *> mCallbacks;
@ -160,6 +162,10 @@ void QueryRandomLocalNet();
uint32_t mMode;
time_t mModeTS;
time_t mStartTS;
time_t mSearchTS;
bool mSearchingDone;
bdDhtFunctions *mFns;
uint32_t mNetworkSize;

View File

@ -83,7 +83,7 @@ void bdNode::init()
}
#define ATTACH_NUMBER 10
#define ATTACH_NUMBER 5
void bdNode::setNodeOptions(uint32_t optFlags)
{
mNodeOptionFlags = optFlags;
@ -440,6 +440,7 @@ void bdNode::addPeer(const bdId *id, uint32_t peerflags)
mFns->bdPrintId(std::cerr, id);
std::cerr << ", " << std::hex << peerflags << std::dec;
std::cerr << ") FAILED the BAD PEER FILTER!!!! DISCARDING MSG";
std::cerr << std::endl;
std::list<struct sockaddr_in> filteredIPs;
mFilterPeers->filteredIPs(filteredIPs);

View File

@ -600,8 +600,8 @@ int bdSpace::scanOutOfDatePeers(std::list<bdId> &peerIds)
if ((ts - mAttachTS > ATTACH_UPDATE_PERIOD) || (attachedCount != mAttachedCount))
{
std::cerr << "Updating ATTACH Stuff";
std::cerr << std::endl;
//std::cerr << "Updating ATTACH Stuff";
//std::cerr << std::endl;
updateAttachedPeers(); /* XXX TEMP HACK to look at stability */
mAttachTS = ts;
}

View File

@ -37,7 +37,7 @@
**/
#define EXPECTED_REPLY 20
#define EXPECTED_REPLY 10 // Speed up queries
#define QUERY_IDLE_RETRY_PEER_PERIOD 300 // 5min = (mFns->bdNodesPerBucket() * 30)
@ -82,6 +82,7 @@ bdQuery::bdQuery(const bdNodeId *id, std::list<bdId> &startList, uint32_t queryF
mQueryFlags = queryFlags;
mQueryTS = now;
mSearchTime = 0;
mClosestListSize = (int) (1.5 * mFns->bdNodesPerBucket());
mQueryIdlePeerRetryPeriod = QUERY_IDLE_RETRY_PEER_PERIOD;
mRequiredPeerFlags = BITDHT_PEER_STATUS_DHT_ENGINE_VERSION; // XXX to update later.
@ -128,7 +129,8 @@ int bdQuery::nextQuery(bdId &id, bdNodeId &targetNodeId)
bool notFinished = false;
std::multimap<bdMetric, bdPeer>::iterator it;
for(it = mClosest.begin(); it != mClosest.end(); it++)
int i = 0;
for(it = mClosest.begin(); it != mClosest.end(); it++, i++)
{
bool queryPeer = false;
@ -158,11 +160,15 @@ int bdQuery::nextQuery(bdId &id, bdNodeId &targetNodeId)
/* expecting every peer to be up-to-date is too hard...
* enough just to have received lists from each
* - replacement policy will still work.
*
* Need to wait at least EXPECTED_REPLY, to make sure their answers are pinged
*/
if (it->second.mLastRecvTime == 0)
if (((it->second.mLastRecvTime == 0) || (now - it->second.mLastRecvTime < EXPECTED_REPLY)) &&
(i < mFns->bdNodesPerBucket()))
{
#ifdef DEBUG_QUERY
fprintf(stderr, "NextQuery() Never Received: notFinished = true: ");
fprintf(stderr, "NextQuery() Never Received @Idx(%d) notFinished = true: ", i);
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
std::cerr << std::endl;
#endif
@ -296,7 +302,8 @@ int bdQuery::addClosestPeer(const bdId *id, uint32_t mode)
fprintf(stderr, "Searching.... %di = %d - %d peers closer than this one\n", i, actualCloser, toDrop);
#endif
if (i > mFns->bdNodesPerBucket() - 1)
if (i > mClosestListSize - 1)
{
#ifdef DEBUG_QUERY
fprintf(stderr, "Distance to far... dropping\n");
@ -367,7 +374,7 @@ int bdQuery::addClosestPeer(const bdId *id, uint32_t mode)
}
/* trim it back */
while(mClosest.size() > (uint32_t) (mFns->bdNodesPerBucket() - 1))
while(mClosest.size() > (uint32_t) (mClosestListSize - 1))
{
std::multimap<bdMetric, bdPeer>::iterator it;
it = mClosest.end();

View File

@ -90,6 +90,7 @@ int trimProxies();
std::list<bdPeer> mProxiesUnknown;
std::list<bdPeer> mProxiesFlagged;
int mClosestListSize;
bdDhtFunctions *mFns;
};

View File

@ -150,6 +150,12 @@ bool bdQueryManager::checkPotentialPeer(bdId *id, bdId *src)
isWorthyPeer = true;
}
}
if (!isWorthyPeer)
{
isWorthyPeer = checkWorthyPeerSources(src);
}
return isWorthyPeer;
}
@ -244,6 +250,7 @@ int bdQueryManager::QuerySummary(const bdNodeId *id, bdQuerySummary &query)
query.mPotentialPeers = (*it)->mPotentialPeers;
query.mProxiesUnknown = (*it)->mProxiesUnknown;
query.mProxiesFlagged = (*it)->mProxiesFlagged;
query.mQueryIdlePeerRetryPeriod = (*it)->mQueryIdlePeerRetryPeriod;
return 1;
}
@ -307,4 +314,61 @@ 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;
}

View File

@ -54,6 +54,10 @@ class bdQueryManager
int proxies(bdNodeId *target, std::list<bdId> &answer);
int potentialProxies(bdNodeId *target, std::list<bdId> &answer);
// extra "Worthy Peers" we will want to ping.
void addWorthyPeerSource(bdId *src);
bool checkWorthyPeerSources(bdId *src);
private:
int getResults(bdNodeId *target, std::list<bdId> &answer, int querytype);
@ -66,6 +70,7 @@ class bdQueryManager
bdNodePublisher *mPub;
std::list<bdQuery *> mLocalQueries;
std::list<bdPeer> mWorthyPeerSources;
};