mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-04-22 16:09:18 -04:00
Rework of part of bdQuery.
* Cleaned up PotentialPeers and Proxy Lists and handling. * Split Proxies into Good & Potential, depending on whether we have IDed them as BitDHT peers. * Added MAX len limit to proxy lists, sorted them but most recently seen. * Extended Potential List to variable length ... back to mClosest.end(). This reduces excessive pings. * added Retry Pings for potential List. * Added bdSimilarId Functions to ignore multiple ports of NATted peers. * Changed bdQuery to use bdSimilarId Fns. * Added ID updates for both Potentials and Proxies. Still to do: * proxy extraction in bdconnection. * cleanup up mClosest in bdQuery. * Create a OneShot bdQuery for DHT Store/Retreive functionality. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-peernet@4324 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
4c7beaa5c7
commit
27c3f10fd2
@ -434,7 +434,9 @@ int bdNode::requestConnection_proxy(struct sockaddr_in *laddr, bdNodeId *target,
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* matching query */
|
||||
(*qit)->proxies(proxies);
|
||||
// XXX to finish off!
|
||||
//(*qit)->proxies(proxies);
|
||||
(*qit)->potentialProxies(proxies);
|
||||
|
||||
/* will only be one matching query.. so end loop */
|
||||
break;
|
||||
|
@ -95,7 +95,8 @@ virtual int bdDistance(const bdNodeId *n1, const bdNodeId *n2, bdMetric *metric)
|
||||
virtual int bdBucketDistance(const bdNodeId *n1, const bdNodeId *n2) = 0;
|
||||
virtual int bdBucketDistance(const bdMetric *metric) = 0;
|
||||
|
||||
virtual uint32_t bdLikelySameNode(const bdId *id1, const bdId *id2) = 0;
|
||||
virtual uint32_t bdSimilarId(const bdId *id1, const bdId *id2) = 0;
|
||||
virtual void bdUpdateSimilarId(bdId *dest, const bdId *src) = 0;
|
||||
|
||||
virtual void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid) = 0;
|
||||
|
||||
@ -233,8 +234,9 @@ class bdQuerySummary
|
||||
|
||||
// closest peers
|
||||
std::multimap<bdMetric, bdPeer> mClosest;
|
||||
std::multimap<bdMetric, bdPeer> mPotentialClosest;
|
||||
std::list<bdPeer> mPotentialProxies;
|
||||
std::multimap<bdMetric, bdPeer> mPotentialPeers;
|
||||
std::list<bdPeer> mProxiesUnknown;
|
||||
std::list<bdPeer> mProxiesFlagged;
|
||||
};
|
||||
|
||||
|
||||
|
@ -712,8 +712,9 @@ int bdNode::QuerySummary(const bdNodeId *id, bdQuerySummary &query)
|
||||
query.mQueryFlags = (*it)->mQueryFlags;
|
||||
query.mSearchTime = (*it)->mSearchTime;
|
||||
query.mClosest = (*it)->mClosest;
|
||||
query.mPotentialClosest = (*it)->mPotentialClosest;
|
||||
query.mPotentialProxies = (*it)->mPotentialProxies;
|
||||
query.mPotentialPeers = (*it)->mPotentialPeers;
|
||||
query.mProxiesUnknown = (*it)->mProxiesUnknown;
|
||||
query.mProxiesFlagged = (*it)->mProxiesFlagged;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ bdQuery::bdQuery(const bdNodeId *id, std::list<bdId> &startList, uint32_t queryF
|
||||
bdPeer peer;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = 0;
|
||||
peer.mPeerFlags = 0;
|
||||
peer.mFoundTime = now;
|
||||
peer.mPeerId = *it;
|
||||
|
||||
@ -83,6 +84,7 @@ bdQuery::bdQuery(const bdNodeId *id, std::list<bdId> &startList, uint32_t queryF
|
||||
mSearchTime = 0;
|
||||
|
||||
mQueryIdlePeerRetryPeriod = QUERY_IDLE_RETRY_PEER_PERIOD;
|
||||
mRequiredPeerFlags = BITDHT_PEER_STATUS_DHT_ENGINE_VERSION; // XXX to update later.
|
||||
|
||||
/* setup the limit of the search
|
||||
* by default it is setup to 000000 = exact match
|
||||
@ -104,17 +106,6 @@ bool bdQuery::result(std::list<bdId> &answer)
|
||||
return (i > 0);
|
||||
}
|
||||
|
||||
bool bdQuery::proxies(std::list<bdId> &answer)
|
||||
{
|
||||
/* get all the matches to our query */
|
||||
std::list<bdPeer>::iterator it;
|
||||
int i = 0;
|
||||
for(it = mPotentialProxies.begin(); it != mPotentialProxies.end(); it++, i++)
|
||||
{
|
||||
answer.push_back(it->mPeerId);
|
||||
}
|
||||
return (i > 0);
|
||||
}
|
||||
|
||||
int bdQuery::nextQuery(bdId &id, bdNodeId &targetNodeId)
|
||||
{
|
||||
@ -252,7 +243,7 @@ int bdQuery::nextQuery(bdId &id, bdNodeId &targetNodeId)
|
||||
{
|
||||
mState = BITDHT_QUERY_SUCCESS;
|
||||
}
|
||||
else if ((mPotentialClosest.begin()->second).mPeerId.id == mId)
|
||||
else if ((mPotentialPeers.begin()->second).mPeerId.id == mId)
|
||||
{
|
||||
mState = BITDHT_QUERY_PEER_UNREACHABLE;
|
||||
}
|
||||
@ -268,7 +259,7 @@ int bdQuery::nextQuery(bdId &id, bdNodeId &targetNodeId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
int bdQuery::addClosestPeer(const bdId *id, uint32_t mode)
|
||||
{
|
||||
bdMetric dist;
|
||||
time_t ts = time(NULL);
|
||||
@ -287,7 +278,9 @@ int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
int i = 0;
|
||||
int actualCloser = 0;
|
||||
int toDrop = 0;
|
||||
for(it = mClosest.begin(); it != sit; it++, i++, actualCloser++)
|
||||
// switched end condition to upper_bound to provide stability for NATTED peers.
|
||||
// we will favour the older entries!
|
||||
for(it = mClosest.begin(); it != eit; it++, i++, actualCloser++)
|
||||
{
|
||||
time_t sendts = ts - it->second.mLastSendTime;
|
||||
bool hasSent = (it->second.mLastSendTime != 0);
|
||||
@ -315,11 +308,16 @@ int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
for(it = sit; it != eit; it++, i++)
|
||||
{
|
||||
/* full id check */
|
||||
if (it->second.mPeerId == *id)
|
||||
if (mFns->bdSimilarId(id, &(it->second.mPeerId)))
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer Already here!\n");
|
||||
#endif
|
||||
if (mode)
|
||||
{
|
||||
/* also update port from incoming id, as we have definitely recved from it */
|
||||
mFns->bdUpdateSimilarId(&(it->second.mPeerId), id);
|
||||
}
|
||||
if (mode & BITDHT_PEER_STATUS_RECV_NODES)
|
||||
{
|
||||
/* only update recvTime if sendTime > checkTime.... (then its our query) */
|
||||
@ -327,6 +325,7 @@ int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
fprintf(stderr, "Updating LastRecvTime\n");
|
||||
#endif
|
||||
it->second.mLastRecvTime = ts;
|
||||
it->second.mPeerFlags |= mode;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -390,6 +389,7 @@ int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
/* add it in */
|
||||
bdPeer peer;
|
||||
peer.mPeerId = *id;
|
||||
peer.mPeerFlags = mode;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = 0;
|
||||
peer.mFoundTime = ts;
|
||||
@ -404,17 +404,71 @@ int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
}
|
||||
|
||||
|
||||
/* we also want to track unreachable node ... this allows us
|
||||
* to detect if peer are online - but uncontactible by dht.
|
||||
*
|
||||
* simple list of closest.
|
||||
/*******************************************************************************************
|
||||
********************************* Add Peer Interface *************************************
|
||||
*******************************************************************************************/
|
||||
|
||||
/**** These functions are called by bdNode to add peers to the query
|
||||
* They add/update the three sets of lists.
|
||||
*
|
||||
* int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
* Proper message from a peer.
|
||||
*
|
||||
* int bdQuery::addPotentialPeer(const bdId *id, const bdId *src, uint32_t srcmode)
|
||||
* This returns 1 if worthy of pinging, 0 if to ignore.
|
||||
*/
|
||||
|
||||
int bdQuery::addPotentialPeer(const bdId *id, const bdId *src, uint32_t mode)
|
||||
#define PEER_MESSAGE 0
|
||||
#define FIND_NODE_RESPONSE 1
|
||||
|
||||
int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
{
|
||||
addClosestPeer(id, mode);
|
||||
updatePotentialPeer(id, mode, PEER_MESSAGE);
|
||||
updateProxy(id, mode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bdQuery::addPotentialPeer(const bdId *id, const bdId *src, uint32_t srcmode)
|
||||
{
|
||||
// is it a Potential Proxy? Always Check This.
|
||||
addProxy(id, src, srcmode);
|
||||
|
||||
int worthy = worthyPotentialPeer(id);
|
||||
int shouldPing = 0;
|
||||
if (worthy)
|
||||
{
|
||||
shouldPing = updatePotentialPeer(id, 0, FIND_NODE_RESPONSE);
|
||||
}
|
||||
return shouldPing;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************************
|
||||
********************************* Closest Peer ********************************************
|
||||
*******************************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************************
|
||||
******************************** Potential Peer *******************************************
|
||||
*******************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/*******
|
||||
* Potential Peers are a list of the closest answers to our queries.
|
||||
* Lots of these peers will not be reachable.... so will only exist in this list.
|
||||
* They will also never have there PeerFlags set ;(
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*** utility functions ***/
|
||||
|
||||
int bdQuery::worthyPotentialPeer(const bdId *id)
|
||||
{
|
||||
bdMetric dist;
|
||||
time_t ts = time(NULL);
|
||||
|
||||
mFns->bdDistance(&mId, &(id->id), &dist);
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
@ -423,7 +477,7 @@ int bdQuery::addPotentialPeer(const bdId *id, const bdId *src, uint32_t mode)
|
||||
fprintf(stderr, ", %u)\n", mode);
|
||||
#endif
|
||||
|
||||
/* first we check if this is a worthy potential peer....
|
||||
/* we check if this is a worthy potential peer....
|
||||
* if it is already in mClosest -> false. old peer.
|
||||
* if it is > mClosest.rbegin() -> false. too far way.
|
||||
*/
|
||||
@ -433,167 +487,391 @@ int bdQuery::addPotentialPeer(const bdId *id, const bdId *src, uint32_t mode)
|
||||
sit = mClosest.lower_bound(dist);
|
||||
eit = mClosest.upper_bound(dist);
|
||||
|
||||
for(it = sit; it != eit; it++)
|
||||
{
|
||||
if (it->second.mPeerId == *id)
|
||||
{
|
||||
/* already there */
|
||||
retval = 0;
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer already in mClosest\n");
|
||||
#endif
|
||||
}
|
||||
//empty loop.
|
||||
}
|
||||
|
||||
/* check if outside range, & bucket is full */
|
||||
if ((sit == mClosest.end()) && (mClosest.size() >= mFns->bdNodesPerBucket()))
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer to far away for Potential\n");
|
||||
#endif
|
||||
retval = 0; /* too far way */
|
||||
return 0; /* too far way */
|
||||
}
|
||||
|
||||
/* return if false; */
|
||||
if (!retval)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Flagging as Not a Potential Peer!\n");
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* finally if a worthy & new peer -> add into potential closest
|
||||
* and repeat existance tests with PotentialPeers
|
||||
*/
|
||||
|
||||
sit = mPotentialClosest.lower_bound(dist);
|
||||
eit = mPotentialClosest.upper_bound(dist);
|
||||
int i = 0;
|
||||
for(it = mPotentialClosest.begin(); it != sit; it++, i++)
|
||||
for(it = sit; it != eit; it++)
|
||||
{
|
||||
//empty loop.
|
||||
}
|
||||
|
||||
if (i > mFns->bdNodesPerBucket() - 1)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Distance to far... dropping\n");
|
||||
fprintf(stderr, "Flagging as Potential Peer!\n");
|
||||
#endif
|
||||
/* outside the list - so we won't add to mPotentialClosest
|
||||
* but inside mClosest still - so should still try it
|
||||
*/
|
||||
retval = 1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
for(it = sit; it != eit; it++, i++)
|
||||
{
|
||||
if (it->second.mPeerId == *id)
|
||||
if (mFns->bdSimilarId(id, &(it->second.mPeerId)))
|
||||
{
|
||||
/* this means its already been pinged */
|
||||
// Not updating Full Peer Id here... as inspection function.
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer Already here in mPotentialClosest!\n");
|
||||
fprintf(stderr, "Peer already in mClosest\n");
|
||||
#endif
|
||||
if (mode & BITDHT_PEER_STATUS_RECV_NODES)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1; /* either within mClosest Range (but not there!), or there aren't enough peers */
|
||||
}
|
||||
|
||||
|
||||
/*****
|
||||
*
|
||||
* mLastSendTime ... is the last FIND_NODE_RESPONSE that we returned 1. (indicating to PING).
|
||||
* mLastRecvTime ... is the last time we received an updatei about/from them
|
||||
*
|
||||
* The update is dependent on the flags passed in the function call. (saves duplicate code).
|
||||
*
|
||||
*
|
||||
* XXX IMPORTANT TO DECIDE WHAT IS RETURNED HERE.
|
||||
* original algorithm return 0 if exists in potential peers, 1 if unknown.
|
||||
* This is used to limit the number of pings to non-responding potentials.
|
||||
*
|
||||
* MUST think about this. Need to install HISTORY tracking again. to look at the statistics.
|
||||
*
|
||||
* It is important that the potential Peers list extends all the way back to == mClosest().end().
|
||||
* Otherwise we end up with [TARGET] .... [ POTENTIAL ] ..... [ CLOSEST ] ......
|
||||
* and the gap between POT and CLOSEST will get hammered with pings.
|
||||
*
|
||||
*/
|
||||
|
||||
#define MIN_PING_POTENTIAL_PERIOD 300
|
||||
|
||||
int bdQuery::updatePotentialPeer(const bdId *id, uint32_t mode, uint32_t addType)
|
||||
{
|
||||
bdMetric dist;
|
||||
time_t now = time(NULL);
|
||||
|
||||
mFns->bdDistance(&mId, &(id->id), &dist);
|
||||
|
||||
std::multimap<bdMetric, bdPeer>::iterator it, sit, eit;
|
||||
sit = mPotentialPeers.lower_bound(dist);
|
||||
eit = mPotentialPeers.upper_bound(dist);
|
||||
|
||||
bool found = false;
|
||||
for(it = sit; it != eit; it++)
|
||||
{
|
||||
if (mFns->bdSimilarId(id, &(it->second.mPeerId)))
|
||||
{
|
||||
found = true;
|
||||
|
||||
it->second.mPeerFlags |= mode;
|
||||
it->second.mLastRecvTime = now;
|
||||
if (addType == FIND_NODE_RESPONSE)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Updating LastRecvTime\n");
|
||||
#endif
|
||||
it->second.mLastRecvTime = ts;
|
||||
// We could lose peers here by not updating port... but should be okay.
|
||||
if (now - it->second.mLastSendTime > MIN_PING_POTENTIAL_PERIOD)
|
||||
{
|
||||
it->second.mLastSendTime = now;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Flagging as Not a Potential Peer!\n");
|
||||
#endif
|
||||
retval = 0;
|
||||
return retval;
|
||||
else if (mode)
|
||||
{
|
||||
/* also update port from incoming id, as we have definitely recved from it */
|
||||
mFns->bdUpdateSimilarId(&(it->second.mPeerId), id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer not in Query\n");
|
||||
#endif
|
||||
// Removing this check - so that we can have varying length PotentialPeers.
|
||||
// Peer will always be added, then probably removed straight away.
|
||||
|
||||
|
||||
/* trim it back */
|
||||
while(mPotentialClosest.size() > (uint32_t) (mFns->bdNodesPerBucket() - 1))
|
||||
#if 0
|
||||
/* check if outside range, & bucket is full */
|
||||
if ((sit == mPotentialPeers.end()) && (mPotentialPeers.size() >= mFns->bdNodesPerBucket()))
|
||||
{
|
||||
std::multimap<bdMetric, bdPeer>::iterator it;
|
||||
it = mPotentialClosest.end();
|
||||
|
||||
if(!mPotentialClosest.empty())
|
||||
{
|
||||
--it;
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Removing Furthest Peer: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Peer to far away for Potential\n");
|
||||
#endif
|
||||
mPotentialClosest.erase(it);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "bdQuery::addPotentialPeer(): Closer Peer!: ");
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
/* add it in */
|
||||
bdPeer peer;
|
||||
peer.mPeerId = *id;
|
||||
peer.mPeerFlags = mode;
|
||||
peer.mFoundTime = now;
|
||||
peer.mLastRecvTime = now;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = ts;
|
||||
peer.mFoundTime = ts;
|
||||
mPotentialClosest.insert(std::pair<bdMetric, bdPeer>(dist, peer));
|
||||
if (addType == FIND_NODE_RESPONSE)
|
||||
{
|
||||
peer.mLastSendTime = now;
|
||||
}
|
||||
|
||||
mPotentialPeers.insert(std::pair<bdMetric, bdPeer>(dist, peer));
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Flagging as Potential Peer!\n");
|
||||
#endif
|
||||
|
||||
trimPotentialPeers_toClosest();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int bdQuery::trimPotentialPeers_FixedLength()
|
||||
{
|
||||
/* trim it back */
|
||||
while(mPotentialPeers.size() > (uint32_t) (mFns->bdNodesPerBucket()))
|
||||
{
|
||||
std::multimap<bdMetric, bdPeer>::iterator it;
|
||||
it = mPotentialPeers.end();
|
||||
it--; // must be more than 1 peer here?
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Removing Furthest Peer: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
mPotentialPeers.erase(it);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int bdQuery::trimPotentialPeers_toClosest()
|
||||
{
|
||||
if (mPotentialPeers.size() <= (uint32_t) (mFns->bdNodesPerBucket()))
|
||||
return 1;
|
||||
|
||||
std::multimap<bdMetric, bdPeer>::reverse_iterator it;
|
||||
it = mClosest.rbegin();
|
||||
bdMetric lastClosest = it->first;
|
||||
|
||||
/* trim it back */
|
||||
while(mPotentialPeers.size() > (uint32_t) (mFns->bdNodesPerBucket()))
|
||||
{
|
||||
std::multimap<bdMetric, bdPeer>::iterator it;
|
||||
it = mPotentialPeers.end();
|
||||
it--; // must be more than 1 peer here?
|
||||
if (lastClosest < it->first)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Removing Furthest Peer: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
mPotentialPeers.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************************
|
||||
******************************** Potential Proxies ****************************************
|
||||
*******************************************************************************************/
|
||||
|
||||
/********
|
||||
* Potential Proxies. a list of peers that have returned our target in response to a query.
|
||||
*
|
||||
* We are particularly interested in peers with specific flags...
|
||||
* But all the peers have been pinged already by the time they reach this list.
|
||||
* So there are two options:
|
||||
* 1) Track everythings mode history - which is a waste of resources.
|
||||
* 2) Store the list, and ping later.
|
||||
*
|
||||
* We will store these in two lists: Flags & Unknown.
|
||||
* we keep the most recent of each, and move around as required.
|
||||
*
|
||||
* we could also check the Closest/PotentialPeer lists to grab the flags,
|
||||
* for an unknown peer?
|
||||
*
|
||||
* All Functions manipulating PotentialProxies are here.
|
||||
* We need several functions:
|
||||
*
|
||||
* For Extracting Proxies.
|
||||
bool bdQuery::proxies(std::list<bdId> &answer)
|
||||
bool bdQuery::potentialProxies(std::list<bdId> &answer)
|
||||
*
|
||||
* For Adding/Updating Proxies.
|
||||
int bdQuery::addProxy(const bdId *id, const bdId *src, uint32_t srcmode)
|
||||
int bdQuery::updateProxy(const bdId *id, uint32_t mode)
|
||||
*
|
||||
*/
|
||||
|
||||
/*** Two Functions to extract Proxies... ***/
|
||||
bool bdQuery::proxies(std::list<bdId> &answer)
|
||||
{
|
||||
/* get all the matches to our query */
|
||||
std::list<bdPeer>::iterator it;
|
||||
int i = 0;
|
||||
for(it = mProxiesFlagged.begin(); it != mProxiesFlagged.end(); it++, i++)
|
||||
{
|
||||
answer.push_back(it->mPeerId);
|
||||
}
|
||||
return (i > 0);
|
||||
}
|
||||
|
||||
bool bdQuery::potentialProxies(std::list<bdId> &answer)
|
||||
{
|
||||
/* get all the matches to our query */
|
||||
std::list<bdPeer>::iterator it;
|
||||
int i = 0;
|
||||
for(it = mProxiesUnknown.begin(); it != mProxiesUnknown.end(); it++, i++)
|
||||
{
|
||||
answer.push_back(it->mPeerId);
|
||||
}
|
||||
return (i > 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int bdQuery::addProxy(const bdId *id, const bdId *src, uint32_t srcmode)
|
||||
{
|
||||
bdMetric dist;
|
||||
time_t now = time(NULL);
|
||||
|
||||
mFns->bdDistance(&mId, &(id->id), &dist);
|
||||
|
||||
/* finally if it is an exact match, add as potential proxy */
|
||||
int bucket = mFns->bdBucketDistance(&dist);
|
||||
if ((bucket == 0) && (src != NULL))
|
||||
if ((bucket != 0) || (src == NULL))
|
||||
{
|
||||
/* not a potential proxy */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Bucket = 0, Have Potential Proxy!\n");
|
||||
fprintf(stderr, "Bucket = 0, Have Potential Proxy!\n");
|
||||
#endif
|
||||
std::list<bdPeer>::iterator it;
|
||||
for(it = mPotentialProxies.begin(); it != mPotentialProxies.end(); it++)
|
||||
{
|
||||
if (*src == it->mPeerId)
|
||||
{
|
||||
/* found it ;( */
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Source Already in Potential Proxy List, updating timestamp!\n");
|
||||
#endif
|
||||
it->mLastRecvTime = ts;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it == mPotentialProxies.end())
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Adding Source to Potential Proxy List:\n");
|
||||
#endif
|
||||
/* add it in */
|
||||
bdPeer peer;
|
||||
peer.mPeerId = *src;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = ts;
|
||||
peer.mFoundTime = ts;
|
||||
|
||||
mPotentialProxies.push_back(peer);
|
||||
bool found = false;
|
||||
if (updateProxyList(src, srcmode, mProxiesUnknown))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (updateProxyList(src, srcmode, mProxiesFlagged))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
retval = 1;
|
||||
return retval;
|
||||
if (!found)
|
||||
{
|
||||
/* if we get here. its not in the list */
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Adding Source to Proxy List:\n");
|
||||
#endif
|
||||
bdPeer peer;
|
||||
peer.mPeerId = *src;
|
||||
peer.mPeerFlags = srcmode;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = now;
|
||||
peer.mFoundTime = now;
|
||||
|
||||
/* add it in */
|
||||
if ((srcmode & mRequiredPeerFlags) == mRequiredPeerFlags)
|
||||
{
|
||||
mProxiesFlagged.push_front(peer);
|
||||
}
|
||||
else
|
||||
{
|
||||
mProxiesUnknown.push_front(peer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
trimProxies();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int bdQuery::updateProxy(const bdId *id, uint32_t mode)
|
||||
{
|
||||
if (!updateProxyList(id, mode, mProxiesUnknown))
|
||||
{
|
||||
updateProxyList(id, mode, mProxiesFlagged);
|
||||
}
|
||||
|
||||
trimProxies();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**** Utility functions that do all the work! ****/
|
||||
|
||||
int bdQuery::updateProxyList(const bdId *id, uint32_t mode, std::list<bdPeer> &searchProxyList)
|
||||
{
|
||||
std::list<bdPeer>::iterator it;
|
||||
for(it = searchProxyList.begin(); it != searchProxyList.end(); it++)
|
||||
{
|
||||
if (mFns->bdSimilarId(id, &(it->mPeerId)))
|
||||
{
|
||||
/* found it ;( */
|
||||
#ifdef DEBUG_QUERY
|
||||
std::cerr << "bdQuery::updateProxyList() Found peer, updating";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
time_t now = time(NULL);
|
||||
if (mode)
|
||||
{
|
||||
/* also update port from incoming id, as we have definitely recved from it */
|
||||
mFns->bdUpdateSimilarId(&(it->mPeerId), id);
|
||||
}
|
||||
it->mPeerFlags |= mode;
|
||||
it->mLastRecvTime = now;
|
||||
|
||||
/* now move it to the front of required list...
|
||||
* note this could be exactly the same list as &searchProxyList, or a different one!
|
||||
*/
|
||||
|
||||
bdPeer peer = *it;
|
||||
it = searchProxyList.erase(it);
|
||||
|
||||
if ((peer.mPeerFlags & mRequiredPeerFlags) == mRequiredPeerFlags)
|
||||
{
|
||||
mProxiesFlagged.push_front(peer);
|
||||
}
|
||||
else
|
||||
{
|
||||
mProxiesUnknown.push_front(peer);
|
||||
}
|
||||
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_POTENTIAL_PROXIES 10
|
||||
|
||||
int bdQuery::trimProxies()
|
||||
{
|
||||
|
||||
/* drop excess Potential Proxies */
|
||||
while(mProxiesUnknown.size() > MAX_POTENTIAL_PROXIES)
|
||||
{
|
||||
mProxiesUnknown.pop_back();
|
||||
}
|
||||
|
||||
while(mProxiesFlagged.size() > MAX_POTENTIAL_PROXIES)
|
||||
{
|
||||
mProxiesFlagged.pop_back();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************************
|
||||
******************************** Potential Proxies ****************************************
|
||||
*******************************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* print query.
|
||||
*/
|
||||
|
||||
@ -659,6 +937,7 @@ int bdQuery::printQuery()
|
||||
{
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, " Bucket: %d ", mFns->bdBucketDistance(&(it->first)));
|
||||
fprintf(stderr," Flags: %x", it->second.mPeerFlags);
|
||||
fprintf(stderr," Found: %ld ago", ts-it->second.mFoundTime);
|
||||
fprintf(stderr," LastSent: %ld ago", ts-it->second.mLastSendTime);
|
||||
fprintf(stderr," LastRecv: %ld ago", ts-it->second.mLastRecvTime);
|
||||
@ -666,11 +945,12 @@ int bdQuery::printQuery()
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Closest Potential Peer: ");
|
||||
it = mPotentialClosest.begin();
|
||||
if (it != mPotentialClosest.end())
|
||||
it = mPotentialPeers.begin();
|
||||
if (it != mPotentialPeers.end())
|
||||
{
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, " Bucket: %d ", mFns->bdBucketDistance(&(it->first)));
|
||||
fprintf(stderr," Flags: %x", it->second.mPeerFlags);
|
||||
fprintf(stderr," Found: %ld ago", ts-it->second.mFoundTime);
|
||||
fprintf(stderr," LastSent: %ld ago", ts-it->second.mLastSendTime);
|
||||
fprintf(stderr," LastRecv: %ld ago", ts-it->second.mLastRecvTime);
|
||||
@ -678,11 +958,24 @@ int bdQuery::printQuery()
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
std::list<bdPeer>::iterator lit;
|
||||
fprintf(stderr, "Potential Proxies:\n");
|
||||
for(lit = mPotentialProxies.begin(); lit != mPotentialProxies.end(); lit++)
|
||||
fprintf(stderr, "Flagged Proxies:\n");
|
||||
for(lit = mProxiesFlagged.begin(); lit != mProxiesFlagged.end(); lit++)
|
||||
{
|
||||
fprintf(stderr, "ProxyId: ");
|
||||
mFns->bdPrintId(std::cerr, &(lit->mPeerId));
|
||||
fprintf(stderr," Flags: %x", it->second.mPeerFlags);
|
||||
fprintf(stderr," Found: %ld ago", ts-lit->mFoundTime);
|
||||
fprintf(stderr," LastSent: %ld ago", ts-lit->mLastSendTime);
|
||||
fprintf(stderr," LastRecv: %ld ago", ts-lit->mLastRecvTime);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "Potential Proxies:\n");
|
||||
for(lit = mProxiesUnknown.begin(); lit != mProxiesUnknown.end(); lit++)
|
||||
{
|
||||
fprintf(stderr, "ProxyId: ");
|
||||
mFns->bdPrintId(std::cerr, &(lit->mPeerId));
|
||||
fprintf(stderr," Flags: %x", it->second.mPeerFlags);
|
||||
fprintf(stderr," Found: %ld ago", ts-lit->mFoundTime);
|
||||
fprintf(stderr," LastSent: %ld ago", ts-lit->mLastSendTime);
|
||||
fprintf(stderr," LastRecv: %ld ago", ts-lit->mLastRecvTime);
|
||||
|
@ -45,12 +45,13 @@ class bdQuery
|
||||
// get the answer.
|
||||
bool result(std::list<bdId> &answer);
|
||||
bool proxies(std::list<bdId> &answer);
|
||||
bool potentialProxies(std::list<bdId> &answer);
|
||||
|
||||
// returning results get passed to all queries.
|
||||
//void addNode(const bdId *id, int mode);
|
||||
int nextQuery(bdId &id, bdNodeId &targetId);
|
||||
int addPeer(const bdId *id, uint32_t mode);
|
||||
int addPotentialPeer(const bdId *id, const bdId *src, uint32_t mode);
|
||||
int addPotentialPeer(const bdId *id, const bdId *src, uint32_t srcmode);
|
||||
int printQuery();
|
||||
|
||||
// searching for
|
||||
@ -65,10 +66,29 @@ int printQuery();
|
||||
|
||||
//private:
|
||||
|
||||
// closest peers
|
||||
// Closest Handling Fns.
|
||||
int addClosestPeer(const bdId *id, uint32_t mode);
|
||||
|
||||
// Potential Handling Fns.
|
||||
int worthyPotentialPeer(const bdId *id);
|
||||
int updatePotentialPeer(const bdId *id, uint32_t mode, uint32_t addType);
|
||||
int trimPotentialPeers_FixedLength();
|
||||
int trimPotentialPeers_toClosest();
|
||||
|
||||
// Proxy Handling Fns.
|
||||
int addProxy(const bdId *id, const bdId *src, uint32_t srcmode);
|
||||
int updateProxy(const bdId *id, uint32_t mode);
|
||||
int updateProxyList(const bdId *id, uint32_t mode, std::list<bdPeer> &searchProxyList);
|
||||
int trimProxies();
|
||||
|
||||
|
||||
// closest peers.
|
||||
std::multimap<bdMetric, bdPeer> mClosest;
|
||||
std::multimap<bdMetric, bdPeer> mPotentialClosest;
|
||||
std::list<bdPeer> mPotentialProxies;
|
||||
std::multimap<bdMetric, bdPeer> mPotentialPeers;
|
||||
|
||||
uint32_t mRequiredPeerFlags;
|
||||
std::list<bdPeer> mProxiesUnknown;
|
||||
std::list<bdPeer> mProxiesFlagged;
|
||||
|
||||
bdDhtFunctions *mFns;
|
||||
};
|
||||
|
@ -70,15 +70,29 @@ void bdStdZeroNodeId(bdNodeId *id)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bdStdLikelySameNode(const bdId *n1, const bdId *n2)
|
||||
// Ignore differences in port....
|
||||
// must be careful which one we accept after this.
|
||||
// can could end-up with the wrong port.
|
||||
// However this only matters with firewalled peers anyway.
|
||||
// So not too serious.
|
||||
uint32_t bdStdSimilarId(const bdId *n1, const bdId *n2)
|
||||
{
|
||||
if (*n1 == *n2)
|
||||
if (n1->id == n2->id)
|
||||
{
|
||||
return 1;
|
||||
if (n1->addr.sin_addr.s_addr == n2->addr.sin_addr.s_addr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bdStdUpdateSimilarId(bdId *dest, const bdId *src)
|
||||
{
|
||||
/* only difference that's currently allowed */
|
||||
dest->addr.sin_port = src->addr.sin_port;
|
||||
}
|
||||
|
||||
|
||||
/* fills in bdNodeId r, with XOR of a and b */
|
||||
int bdStdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r)
|
||||
@ -260,9 +274,15 @@ int bdStdDht::bdBucketDistance(const bdMetric *metric)
|
||||
}
|
||||
|
||||
|
||||
uint32_t bdStdDht::bdLikelySameNode(const bdId *id1, const bdId *id2)
|
||||
uint32_t bdStdDht::bdSimilarId(const bdId *id1, const bdId *id2)
|
||||
{
|
||||
return bdStdLikelySameNode(id1, id2);
|
||||
return bdStdSimilarId(id1, id2);
|
||||
}
|
||||
|
||||
|
||||
void bdStdDht::bdUpdateSimilarId(bdId *dest, const bdId *src)
|
||||
{
|
||||
return bdStdUpdateSimilarId(dest, src);
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,7 +59,7 @@ void bdStdPrintNodeId(std::ostream &out, const bdNodeId *a);
|
||||
|
||||
std::string bdStdConvertToPrintable(std::string input);
|
||||
|
||||
uint32_t bdStdLikelySameNode(const bdId*, const bdId*);
|
||||
//uint32_t bdStdSimilarNode(const bdId*, const bdId*);
|
||||
|
||||
|
||||
class bdStdDht: public bdDhtFunctions
|
||||
@ -76,7 +76,8 @@ virtual int bdDistance(const bdNodeId *n1, const bdNodeId *n2, bdMetric *metric)
|
||||
virtual int bdBucketDistance(const bdNodeId *n1, const bdNodeId *n2);
|
||||
virtual int bdBucketDistance(const bdMetric *metric);
|
||||
|
||||
virtual uint32_t bdLikelySameNode(const bdId *id1, const bdId *id2);
|
||||
virtual uint32_t bdSimilarId(const bdId *id1, const bdId *id2);
|
||||
virtual void bdUpdateSimilarId(bdId *dest, const bdId *src);
|
||||
|
||||
virtual void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user