mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-15 12:32:37 -04:00
Significant improvements to DHT behaviour, and reconnection attempts.
* Added GUI interface for auto connect state. * Added HTTP retrieval and storage of DHT peers update. * Added code for partial recv() from DHT peers. * Disabled Chat/Disc/Udplayer/tcpstream debug output. * Added Unreachable Check to connMgr. * Added auto reconnect functions to connMgr (#define to disable). * Restructured DHT notify code... much cleaner. * DHT now flags out of date DHT results. * DHT notifies ConnMgr on any results (same or diff). * Added Fns to cleanup old udp connection. * other bugfixes. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@369 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
7b3fc2976e
commit
63828f77a8
20 changed files with 708 additions and 203 deletions
|
@ -66,8 +66,8 @@
|
|||
#define DHT_DEFAULT_WAITTIME 1 /* Std sleep break period */
|
||||
|
||||
/* TTLs for DHTs posts */
|
||||
#define DHT_TTL_PUBLISH (DHT_PUBLISH_PERIOD + 30)
|
||||
#define DHT_TTL_NOTIFY DHT_NOTIFY_PERIOD
|
||||
#define DHT_TTL_PUBLISH (DHT_PUBLISH_PERIOD + 120) // for a little overlap.
|
||||
#define DHT_TTL_NOTIFY (DHT_NOTIFY_PERIOD + 60) // for time to find it...
|
||||
|
||||
|
||||
void printDhtPeerEntry(dhtPeerEntry *ent, std::ostream &out);
|
||||
|
@ -185,45 +185,41 @@ bool p3DhtMgr::setExternalInterface(
|
|||
/* add / remove peers */
|
||||
bool p3DhtMgr::findPeer(std::string id)
|
||||
{
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
mDhtModifications = true;
|
||||
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
it = peers.find(id);
|
||||
if (it == peers.end())
|
||||
if (it != peers.end())
|
||||
{
|
||||
/* if they are not in the list -> add */
|
||||
dhtPeerEntry ent;
|
||||
ent.id = id;
|
||||
ent.state = DHT_PEER_INIT;
|
||||
ent.type = DHT_ADDR_INVALID;
|
||||
ent.lastTS = 0;
|
||||
|
||||
ent.notifyPending = 0;
|
||||
ent.notifyTS = 0;
|
||||
|
||||
/* fill in hashes */
|
||||
ent.hash1 = RsUtil::HashId(id, false);
|
||||
ent.hash2 = RsUtil::HashId(id, true);
|
||||
|
||||
/* other fields don't matter */
|
||||
|
||||
peers[id] = ent;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ignore */
|
||||
return true;
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
/* if they are not in the list -> add */
|
||||
dhtPeerEntry ent;
|
||||
ent.id = id;
|
||||
ent.state = DHT_PEER_INIT;
|
||||
ent.type = DHT_ADDR_INVALID;
|
||||
ent.lastTS = 0;
|
||||
|
||||
ent.notifyPending = 0;
|
||||
ent.notifyTS = 0;
|
||||
|
||||
/* fill in hashes */
|
||||
ent.hash1 = RsUtil::HashId(id, false);
|
||||
ent.hash2 = RsUtil::HashId(id, true);
|
||||
|
||||
/* other fields don't matter */
|
||||
|
||||
peers[id] = ent;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3DhtMgr::dropPeer(std::string id)
|
||||
{
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
mDhtModifications = true;
|
||||
|
||||
|
@ -232,15 +228,11 @@ bool p3DhtMgr::dropPeer(std::string id)
|
|||
it = peers.find(id);
|
||||
if (it == peers.end())
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* remove */
|
||||
peers.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
/* remove */
|
||||
peers.erase(it);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -248,31 +240,46 @@ bool p3DhtMgr::dropPeer(std::string id)
|
|||
/* post DHT key saying we should connect */
|
||||
bool p3DhtMgr::notifyPeer(std::string id)
|
||||
{
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::notifyPeer() " << id << std::endl;
|
||||
#endif
|
||||
|
||||
mDhtModifications = true;
|
||||
|
||||
/* once we are connected ... don't worry about them anymore */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
it = peers.find(id);
|
||||
bool ret = true;
|
||||
if (it == peers.end())
|
||||
{
|
||||
/* ignore */
|
||||
ret = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (now - it->second.notifyTS < 2 * DHT_NOTIFY_PERIOD)
|
||||
{
|
||||
it->second.notifyPending = RS_CONNECT_ACTIVE;
|
||||
it->second.notifyTS = time(NULL);
|
||||
/* drop the notify (too soon) */
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::notifyPeer() TO SOON - DROPPING" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
it->second.notifyPending = RS_CONNECT_ACTIVE;
|
||||
it->second.notifyTS = time(NULL);
|
||||
|
||||
return ret;
|
||||
/* Trigger search if not found! */
|
||||
if (it->second.state != DHT_PEER_FOUND)
|
||||
{
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::notifyPeer() PEER NOT FOUND - Trigger search" << std::endl;
|
||||
#endif
|
||||
it->second.lastTS = 0;
|
||||
}
|
||||
|
||||
mDhtModifications = true; /* no wait! */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* extract current peer status */
|
||||
bool p3DhtMgr::getPeerStatus(std::string id,
|
||||
struct sockaddr_in &laddr,
|
||||
|
@ -680,12 +687,12 @@ int p3DhtMgr::checkPeerDHTKeys()
|
|||
return repeatPeriod;
|
||||
}
|
||||
|
||||
/* update timestamp */
|
||||
/* update timestamp
|
||||
* clear FOUND or INIT state.
|
||||
* */
|
||||
|
||||
pit->second.lastTS = now;
|
||||
if (pit->second.state == DHT_PEER_INIT)
|
||||
{
|
||||
pit->second.state = DHT_PEER_SEARCH;
|
||||
}
|
||||
pit->second.state = DHT_PEER_SEARCH;
|
||||
|
||||
dhtPeerEntry peer = (pit->second);
|
||||
|
||||
|
@ -705,8 +712,12 @@ int p3DhtMgr::checkNotifyDHT()
|
|||
std::cerr << "p3DhtMgr::checkNotifyDHT()" << std::endl;
|
||||
#endif
|
||||
/* now loop through the peers */
|
||||
uint32_t notifyType = 0;
|
||||
dhtPeerEntry peer;
|
||||
dhtPeerEntry own;
|
||||
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
/* iterate through and find min time and suitable candidate */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
|
@ -716,46 +727,68 @@ int p3DhtMgr::checkNotifyDHT()
|
|||
/* find the first with a notify flag */
|
||||
for(it = peers.begin(); it != peers.end(); it++)
|
||||
{
|
||||
if ((it->second.state == DHT_PEER_FOUND) &&
|
||||
(it->second.notifyPending == RS_CONNECT_ACTIVE))
|
||||
if (it->second.notifyPending)
|
||||
{
|
||||
break;
|
||||
if (it->second.state == DHT_PEER_FOUND)
|
||||
{
|
||||
notifyType = it->second.notifyPending;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if very old drop it */
|
||||
if (now - it->second.notifyTS > DHT_NOTIFY_PERIOD)
|
||||
{
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::checkNotifyDHT() Dropping OLD Notify: ";
|
||||
std::cerr << it->first << std::endl;
|
||||
#endif
|
||||
it->second.notifyPending = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now have - peer to handle */
|
||||
if (it == peers.end())
|
||||
{
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
return repeatPeriod;
|
||||
}
|
||||
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::checkNotifyDHT() Notify From: ";
|
||||
std::cerr << it->first << std::endl;
|
||||
#endif
|
||||
|
||||
/* update timestamp */
|
||||
it->second.notifyTS = now;
|
||||
it->second.notifyPending = 0;
|
||||
|
||||
dhtPeerEntry peer = (it->second);
|
||||
dhtPeerEntry own = ownEntry;
|
||||
peer = (it->second);
|
||||
own = ownEntry;
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
} /******* UNLOCK ******/
|
||||
|
||||
/* publish notification (publish Our Id)
|
||||
* We publish the connection attempt on peers hash,
|
||||
* using our alternative hash..
|
||||
* */
|
||||
|
||||
if (dhtNotify(peer.hash1, own.hash2, ""))
|
||||
if (notifyType == RS_CONNECT_ACTIVE)
|
||||
{
|
||||
/* feedback to say we started it! */
|
||||
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
|
||||
connCb->peerConnectRequest(peer.id, peer.laddr, RS_CB_DHT);
|
||||
#else
|
||||
connCb->peerConnectRequest(peer.id, peer.raddr, RS_CB_DHT);
|
||||
/* publish notification (publish Our Id)
|
||||
* We publish the connection attempt on peers hash,
|
||||
* using our alternative hash..
|
||||
* */
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::checkNotifyDHT() Posting Active Notify";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
dhtNotify(peer.hash1, own.hash2, "");
|
||||
}
|
||||
|
||||
/* feedback to say we started it! */
|
||||
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
|
||||
connCb->peerConnectRequest(peer.id, peer.laddr, RS_CB_DHT);
|
||||
#else
|
||||
connCb->peerConnectRequest(peer.id, peer.raddr, RS_CB_DHT);
|
||||
#endif
|
||||
|
||||
repeatPeriod = DHT_MIN_PERIOD;
|
||||
return repeatPeriod;
|
||||
return DHT_MIN_PERIOD;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1239,14 +1272,13 @@ bool p3DhtMgr::resultDHT(std::string key, std::string value)
|
|||
|
||||
bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
||||
{
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::dhtResultNotify() from idhash: ";
|
||||
std::cerr << RsUtil::BinToHex(idhash) << std::endl;
|
||||
#endif
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
bool doNotify = false;
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* if notify - we must match on the second hash */
|
||||
|
@ -1254,7 +1286,6 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
|||
|
||||
/* update data */
|
||||
std::string peerid;
|
||||
struct sockaddr_in raddr, laddr;
|
||||
|
||||
if (it != peers.end())
|
||||
{
|
||||
|
@ -1263,22 +1294,14 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
|||
#endif
|
||||
/* delay callback -> if they are not found */
|
||||
it->second.notifyTS = now;
|
||||
it->second.notifyPending = RS_CONNECT_PASSIVE;
|
||||
mDhtModifications = true; /* no wait! */
|
||||
|
||||
if (it->second.state != DHT_PEER_FOUND)
|
||||
{
|
||||
doNotify = false;
|
||||
it->second.notifyPending = RS_CONNECT_PASSIVE;
|
||||
/* flag for immediate search */
|
||||
mDhtModifications = true; /* no wait! */
|
||||
it->second.lastTS = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
doNotify = true;
|
||||
it->second.notifyPending = 0;
|
||||
peerid = (it->second).id;
|
||||
raddr = (it->second).raddr;
|
||||
laddr = (it->second).laddr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1288,18 +1311,6 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
|||
#endif
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
/* do callback */
|
||||
if (doNotify)
|
||||
{
|
||||
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
|
||||
connCb->peerConnectRequest(peerid, laddr, RS_CB_DHT);
|
||||
#else
|
||||
connCb->peerConnectRequest(peerid, raddr, RS_CB_DHT);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1316,7 +1327,6 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
|
|||
#endif
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
bool doCb = false;
|
||||
bool doNotify = false;
|
||||
bool doStun = false;
|
||||
uint32_t stunFlags = 0;
|
||||
time_t now = time(NULL);
|
||||
|
@ -1334,39 +1344,25 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
|
|||
#endif
|
||||
it->second.lastTS = now;
|
||||
|
||||
/* has it changed??? */
|
||||
if ((it->second.state != DHT_PEER_FOUND) ||
|
||||
(0 != sockaddr_cmp(it->second.laddr,laddr)) ||
|
||||
(0 != sockaddr_cmp(it->second.raddr,raddr)) ||
|
||||
(it->second.type != type))
|
||||
/* Do callback all the time */
|
||||
ent = it->second;
|
||||
doCb = true;
|
||||
|
||||
/* update info .... always */
|
||||
it->second.state = DHT_PEER_FOUND;
|
||||
it->second.laddr = laddr;
|
||||
it->second.raddr = raddr;
|
||||
it->second.type = type;
|
||||
|
||||
if (it->second.notifyPending)
|
||||
{
|
||||
it->second.state = DHT_PEER_FOUND;
|
||||
it->second.laddr = laddr;
|
||||
it->second.raddr = raddr;
|
||||
it->second.type = type;
|
||||
ent = it->second;
|
||||
doCb = true;
|
||||
/* no wait if we have pendingNotification */
|
||||
mDhtModifications = true;
|
||||
}
|
||||
|
||||
/* do we have a pending notify */
|
||||
if ((it->second.state == DHT_PEER_FOUND) &&
|
||||
(it->second.notifyPending == RS_CONNECT_PASSIVE))
|
||||
{
|
||||
it->second.notifyPending = 0;
|
||||
doNotify = true;
|
||||
}
|
||||
|
||||
/* if stun not happy yet - doStun as well..
|
||||
* as the DHT doesn't know if the Stun is happy - send
|
||||
* it through always!
|
||||
* if ((mDhtState != DHT_STATE_OFF) &&
|
||||
* (mDhtState != DHT_STATE_ACTIVE))
|
||||
*/
|
||||
if (mDhtState != DHT_STATE_OFF)
|
||||
{
|
||||
doStun = true;
|
||||
stunFlags = RS_STUN_FRIEND | RS_STUN_ONLINE;
|
||||
}
|
||||
/* do Stun always */
|
||||
doStun = true;
|
||||
stunFlags = RS_STUN_FRIEND | RS_STUN_ONLINE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1381,21 +1377,10 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
|
|||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
/* if changed - do callback */
|
||||
if (doCb)
|
||||
{
|
||||
connCb->peerStatus(ent.id,
|
||||
ent.laddr, ent.raddr,
|
||||
connCb->peerStatus(ent.id, ent.laddr, ent.raddr,
|
||||
ent.type, 0, RS_CB_DHT);
|
||||
//ent.type, RS_CB_LOCAL_ADDR | RS_CB_REMOTE_ADDR, RS_CB_DHT);
|
||||
if (doNotify)
|
||||
{
|
||||
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
|
||||
connCb->peerConnectRequest(ent.id, ent.laddr, RS_CB_DHT);
|
||||
#else
|
||||
connCb->peerConnectRequest(ent.id, ent.raddr, RS_CB_DHT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (doStun)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue