Completed basics of the new p3bitdht system.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-netupgrade@4418 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2011-07-10 00:39:15 +00:00
parent 21145a29bb
commit 6eb27c9a1a
8 changed files with 3262 additions and 415 deletions

View file

@ -28,9 +28,6 @@
#include "bitdht/bdstddht.h"
#include "pqi/p3linkmgr.h" // FOR FLAGS... move elsewhere
#include "pqi/p3peermgr.h"
#include "tcponudp/udprelay.h"
#include "tcponudp/udpstunner.h"
@ -79,8 +76,9 @@ virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdI
};
p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, UdpStack *udpstack, std::string bootstrapfile)
:pqiNetAssistConnect(id, cb), dhtMtx("p3BitDht")
p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
UdpStack *udpstack, std::string bootstrapfile)
:pqiNetAssistConnect(id, cb), mNetMgr(nm), dhtMtx("p3BitDht")
{
mDhtStunner = NULL;
mProxyStunner = NULL;
@ -100,8 +98,8 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, UdpStack *udpstack, std::st
#endif
/* setup ownId */
storeTranslation(id);
lookupNodeId(id, &ownId);
storeTranslation_locked(id);
lookupNodeId_locked(id, &ownId);
#ifdef DEBUG_BITDHT
@ -202,6 +200,7 @@ bool p3BitDht::getNetworkStats(uint32_t &netsize, uint32_t &localnetsize)
return true;
}
#if 0
/* pqiNetAssistConnect - external interface functions */
/* add / remove peers */
bool p3BitDht::findPeer(std::string pid)
@ -283,6 +282,9 @@ bool p3BitDht::dropPeer(std::string pid)
return true ;
}
#endif
/* extract current peer status */
bool p3BitDht::getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
@ -311,396 +313,3 @@ bool p3BitDht::getExternalInterface(struct sockaddr_in &raddr,
}
/* Adding a little bit of fixed test...
* This allows us to ensure that only compatible peers will find each other
*/
const uint8_t RS_DHT_VERSION_LEN = 17;
const uint8_t rs_dht_version_data[RS_DHT_VERSION_LEN] = "RS_VERSION_0.5.1";
/******************** Conversion Functions **************************/
int p3BitDht::calculateNodeId(const std::string pid, bdNodeId *id)
{
/* generate node id from pid */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::calculateNodeId() " << pid;
#endif
/* use a hash to make it impossible to reverse */
uint8_t sha_hash[SHA_DIGEST_LENGTH];
memset(sha_hash,0,SHA_DIGEST_LENGTH*sizeof(uint8_t)) ;
SHA_CTX *sha_ctx = new SHA_CTX;
SHA1_Init(sha_ctx);
SHA1_Update(sha_ctx, rs_dht_version_data, RS_DHT_VERSION_LEN);
SHA1_Update(sha_ctx, pid.c_str(), pid.length());
SHA1_Final(sha_hash, sha_ctx);
for(int i = 0; i < SHA_DIGEST_LENGTH && (i < BITDHT_KEY_LEN); i++)
{
id->data[i] = sha_hash[i];
}
delete sha_ctx;
#ifdef DEBUG_BITDHT
std::cerr << " => ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::lookupNodeId(const std::string pid, bdNodeId *id)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupNodeId() for : " << pid;
std::cerr << std::endl;
#endif
RsStackMutex stack(dhtMtx);
std::map<std::string, bdNodeId>::iterator it;
it = mTransToNodeId.find(pid);
if (it == mTransToNodeId.end())
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupNodeId() failed";
std::cerr << std::endl;
#endif
return 0;
}
*id = it->second;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupNodeId() Found NodeId: ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::lookupRsId(const bdNodeId *id, std::string &pid)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupRsId() for : ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
RsStackMutex stack(dhtMtx);
std::map<bdNodeId, std::string>::iterator nit;
nit = mTransToRsId.find(*id);
if (nit == mTransToRsId.end())
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupRsId() failed";
std::cerr << std::endl;
#endif
return 0;
}
pid = nit->second;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupRsId() Found Matching RsId: " << pid;
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::storeTranslation(const std::string pid)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::storeTranslation(" << pid << ")";
std::cerr << std::endl;
#endif
bdNodeId nid;
calculateNodeId(pid, &nid);
RsStackMutex stack(dhtMtx);
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::storeTranslation() Converts to NodeId: ";
bdStdPrintNodeId(std::cerr, &(nid));
std::cerr << std::endl;
#endif
mTransToNodeId[pid] = nid;
mTransToRsId[nid] = pid;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::storeTranslation() Success";
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::removeTranslation(const std::string pid)
{
RsStackMutex stack(dhtMtx);
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::removeTranslation(" << pid << ")";
std::cerr << std::endl;
#endif
std::map<std::string, bdNodeId>::iterator it = mTransToNodeId.find(pid);
it = mTransToNodeId.find(pid);
if (it == mTransToNodeId.end())
{
std::cerr << "p3BitDht::removeTranslation() ERROR MISSING TransToNodeId";
std::cerr << std::endl;
/* missing */
return 0;
}
bdNodeId nid = it->second;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::removeTranslation() Found Translation: NodeId: ";
bdStdPrintNodeId(std::cerr, &(nid));
std::cerr << std::endl;
#endif
std::map<bdNodeId, std::string>::iterator nit;
nit = mTransToRsId.find(nid);
if (nit == mTransToRsId.end())
{
std::cerr << "p3BitDht::removeTranslation() ERROR MISSING TransToRsId";
std::cerr << std::endl;
/* inconsistent!!! */
return 0;
}
mTransToNodeId.erase(it);
mTransToRsId.erase(nit);
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::removeTranslation() SUCCESS";
std::cerr << std::endl;
#endif
return 1;
}
/********************** Callback Functions **************************/
uint32_t translatebdcbflgs(uint32_t peerflags);
int p3BitDht::NodeCallback(const bdId *id, uint32_t peerflags)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::NodeCallback()";
std::cerr << std::endl;
#endif
// XXX THIS IS A BAD HACK TO PREVENT connection attempt to MEDIASENTRY (dht spies)
// peers... These peers appear to masquerade as your OwnNodeId!!!!
// which means peers could attempt to connect too?? not sure about this?
// Anyway they don't appear to REPLY to FIND_NODE requests...
// So if we ignore these peers, we'll only get the true RS peers!
// This should be fixed by a collaborative IP filter system,
// EACH peer identifies dodgey IP (ones spoofing yourself), and shares them
// This are distributed around RS via a service, and the UDP ignores
// all comms from these sources. (AT a low level).
if (peerflags != BITDHT_PEER_STATUS_RECV_NODES)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::NodeCallback() Ignoring !FIND_NODE callback from:";
bdStdPrintNodeId(std::cerr, &(id->id));
std::cerr << " flags: " << peerflags;
std::cerr << std::endl;
#endif
return 0;
}
/* is it one that we are interested in? */
std::string pid;
/* check for translation */
if (lookupRsId(&(id->id), pid))
{
#ifdef DEBUG_BITDHT
/* we found it ... do callback to p3connmgr */
std::cerr << "p3BitDht::NodeCallback() FOUND NODE!!!: ";
bdStdPrintNodeId(std::cerr, &(id->id));
std::cerr << "-> " << pid << " flags: " << peerflags;
std::cerr << std::endl;
#endif
/* send status info to p3connmgr */
pqiIpAddress dhtpeer;
dhtpeer.mSrc = RS_CB_DHT;
dhtpeer.mSeenTime = time(NULL);
dhtpeer.mAddr = id->addr;
pqiIpAddrSet addrs;
addrs.updateExtAddrs(dhtpeer);
uint32_t type = RS_NET_CONN_UDP_DHT_SYNC;
uint32_t flags = translatebdcbflgs(peerflags);
uint32_t source = RS_CB_DHT;
mConnCb->peerStatus(pid, addrs, type, flags, source);
return 1;
}
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::NodeCallback() FAILED TO FIND NODE: ";
bdStdPrintNodeId(std::cerr, &(id->id));
std::cerr << std::endl;
#endif
return 0;
}
uint32_t translatebdcbflgs(uint32_t peerflags)
{
uint32_t outflags = 0;
outflags |= RS_NET_FLAGS_ONLINE;
return outflags;
#if 0
// The input flags.
#define BITDHT_PEER_STATUS_RECV_PONG 0x00000001
#define BITDHT_PEER_STATUS_RECV_NODES 0x00000002
#define BITDHT_PEER_STATUS_RECV_HASHES 0x00000004
#define BITDHT_PEER_STATUS_DHT_ENGINE 0x00000100
#define BITDHT_PEER_STATUS_DHT_APPL 0x00000200
#define BITDHT_PEER_STATUS_DHT_VERSION 0x00000400
if (peerflags & ONLINE)
{
outflags |= RS_NET_FLAGS_ONLINE;
}
if (peerflags & ONLINE)
{
outflags |= RS_NET_FLAGS_EXTERNAL_ADDR | RS_NET_FLAGS_STABLE_UDP;
}
#endif
}
int p3BitDht::PeerCallback(const bdId *id, uint32_t status)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() bdId: ";
bdStdPrintId(std::cerr, id);
std::cerr << std::endl;
#endif
/* is it one that we are interested in? */
std::string pid;
/* check for translation */
if (lookupRsId(&(id->id), pid))
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() => RsId: ";
std::cerr << pid << " status: " << status;
std::cerr << " NOOP for NOW";
std::cerr << std::endl;
#endif
bool connect = false;
switch(status)
{
case BITDHT_MGR_QUERY_FAILURE:
/* do nothing */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() QUERY FAILURE ... do nothin ";
std::cerr << std::endl;
#endif
break;
case BITDHT_MGR_QUERY_PEER_OFFLINE:
/* do nothing */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() QUERY PEER OFFLINE ... do nothin ";
std::cerr << std::endl;
#endif
break;
case BITDHT_MGR_QUERY_PEER_UNREACHABLE:
/* do nothing */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() QUERY PEER UNREACHABLE ... flag? / do nothin ";
std::cerr << std::endl;
#endif
break;
case BITDHT_MGR_QUERY_PEER_ONLINE:
/* do something */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() QUERY PEER ONLINE ... try udp connection";
std::cerr << std::endl;
#endif
connect = true;
break;
}
if (connect)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() mConnCb->peerConnectRequest()";
std::cerr << std::endl;
#endif
mConnCb->peerConnectRequest(pid, id->addr, RS_CB_DHT);
return 1;
}
else
{
return 0;
}
}
else
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback()";
std::cerr << " FAILED TO TRANSLATE ID ";
std::cerr << " status: " << status;
std::cerr << " NOOP for NOW";
std::cerr << std::endl;
#endif
}
return 0;
}
int p3BitDht::ValueCallback(const bdNodeId *id, std::string key, uint32_t status)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::ValueCallback() NOOP for NOW";
std::cerr << std::endl;
#endif
/* ignore for now */
return 0;
}