* Added hack to remove DODGEY peers. (This should probably be moved to libbitdht).

* NOTE about how to correctly implement Peer filtering.
 * added peerConnectRequest() when PeerCallback(success) happens... starts UDP connection.
 * Split the p3conmgr::tryConnect() functions into sub functions.
 * added p3ConnMgr functions for UDP connections.
 * Added AddifUnique(conect_address), to ConnMgr, this should reduce the number of connection attempts, by removing dups.
 * Disabled bitdht in libretroshare.pro for the moment.




git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3605 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2010-10-04 21:42:31 +00:00
parent 20a49a59cf
commit 0ea899de29
5 changed files with 277 additions and 46 deletions

View File

@ -411,6 +411,26 @@ int p3BitDht::NodeCallback(const bdId *id, uint32_t peerflags)
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)
{
std::cerr << "p3BitDht::NodeCallback() Ignoring !FIND_NODE callback from:";
bdStdPrintNodeId(std::cerr, &(id->id));
std::cerr << " flags: " << peerflags;
std::cerr << std::endl;
return 0;
}
/* is it one that we are interested in? */
std::string pid;
/* check for translation */
@ -466,15 +486,66 @@ int p3BitDht::PeerCallback(const bdNodeId *id, uint32_t status)
std::cerr << " NOOP for NOW";
std::cerr << std::endl;
bool connect = false;
switch(status)
{
case BITDHT_MGR_QUERY_FAILURE:
/* do nothing */
std::cerr << "p3BitDht::PeerCallback() QUERY FAILURE ... do nothin ";
std::cerr << std::endl;
/* we found it ... do callback to p3connmgr */
//uint32_t cbflags = ONLINE | REACHABLE;
break;
/* callback to say they are online */
//mConnCb->peerStatus(ent.id, addrs, ent.type, 0, RS_CB_DHT);
//mConnCb->peerConnectRequest(peer.id, peer.laddr, RS_CB_DHT);
case BITDHT_MGR_QUERY_PEER_OFFLINE:
/* do nothing */
return 1;
std::cerr << "p3BitDht::PeerCallback() QUERY PEER OFFLINE ... do nothin ";
std::cerr << std::endl;
break;
case BITDHT_MGR_QUERY_PEER_UNREACHABLE:
/* do nothing */
std::cerr << "p3BitDht::PeerCallback() QUERY PEER UNREACHABLE ... flag? / do nothin ";
std::cerr << std::endl;
break;
case BITDHT_MGR_QUERY_PEER_ONLINE:
/* do something */
std::cerr << "p3BitDht::PeerCallback() QUERY PEER ONLINE ... try udp connection";
std::cerr << std::endl;
connect = true;
break;
}
if (connect)
{
std::cerr << "p3BitDht::PeerCallback() checking getDhtPeerAddress()";
std::cerr << std::endl;
/* get dht address */
/* we found it ... do callback to p3connmgr */
struct sockaddr_in dhtAddr;
if (mUdpBitDht->getDhtPeerAddress(id, dhtAddr))
{
std::cerr << "p3BitDht::PeerCallback() getDhtPeerAddress() == true";
std::cerr << std::endl;
std::cerr << "p3BitDht::PeerCallback() mConnCb->peerConnectRequest()";
std::cerr << std::endl;
mConnCb->peerConnectRequest(pid, dhtAddr, RS_CB_DHT);
}
return 1;
}
else
{
return 0;
}
}
else
{

View File

@ -1,7 +1,7 @@
TEMPLATE = lib
#CONFIG += staticlib release
#CONFIG += staticlib testnetwork
CONFIG += staticlib testnetwork bitdht
CONFIG += staticlib testnetwork
#CONFIG += staticlib testnetwork bitdht
CONFIG -= qt
TARGET = retroshare
@ -28,7 +28,7 @@ release {
testnetwork {
# DEFINES *= PQI_DISABLE_UDP
DEFINES *= PQI_DISABLE_UDP
DEFINES *= PQI_DISABLE_TUNNEL
# DEFINES *= AUTHSSL_DEBUG GPG_DEBUG
@ -67,6 +67,7 @@ bitdht {
HEADERS += dht/p3bitdht.h
SOURCES += dht/p3bitdht.cc
HEADERS += tcponudp/udppeer.h \
tcponudp/bio_tou.h \
tcponudp/tcppacket.h \
@ -499,6 +500,7 @@ SOURCES += services/p3channels.cc \
SOURCES += tcponudp/extaddrfinder.cc \
SOURCES += turtle/p3turtle.cc \
turtle/rsturtleitem.cc
# turtle/turtlerouting.cc \

View File

@ -2068,7 +2068,20 @@ void p3ConnectMgr::peerConnectRequest(std::string id, struct sockaddr_in radd
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::peerConnectRequest() Try TCP first" << std::endl;
#endif
retryConnect(id);
if (source == RS_CB_DHT)
{
std::cerr << "p3ConnectMgr::peerConnectRequest() source DHT ==> retryConnectUDP()" << std::endl;
retryConnectUDP(id, raddr);
return;
}
else
{ // IS THIS USED???
std::cerr << "p3ConnectMgr::peerConnectRequest() source OTHER ==> retryConnect()" << std::endl;
retryConnect(id);
return;
}
}
@ -2342,6 +2355,78 @@ bool p3ConnectMgr::retryConnect(std::string id)
}
bool p3ConnectMgr::retryConnectUDP(std::string id, struct sockaddr_in &rUdpAddr)
{
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
/* push all available addresses onto the connect addr stack */
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::retryConnectTCP() id: " << id << std::endl;
#endif
if (id == getOwnId()) {
#ifdef CONN_DEBUG
rslog(RSL_WARNING, p3connectzone, "p3ConnectMgr::retryConnectUDP() Failed, connecting to own id: ");
#endif
return false;
}
/* look up the id */
std::map<std::string, peerConnectState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::retryConnectUDP() Peer is not Friend" << std::endl;
#endif
return false;
}
/* if already connected -> done */
if (it->second.state & RS_PEER_S_CONNECTED)
{
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::retryConnectUDP() Peer Already Connected" << std::endl;
#endif
if (it->second.connecttype & RS_NET_CONN_TUNNEL) {
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::retryConnectUDP() Peer Connected through a tunnel connection, let's try a normal connection." << std::endl;
#endif
} else {
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::retryConnectUDP() Peer Connected no more connection attempts" << std::endl;
#endif
return false;
}
}
/* Explicit Request to start the UDP connection */
if (isValidNet(&(rUdpAddr.sin_addr)))
{
#ifdef CONN_DEBUG
std::cerr << "Adding udp connection attempt: ";
std::cerr << "Addr: " << rs_inet_ntoa(rUdpAddr.sin_addr);
std::cerr << ":" << ntohs(rUdpAddr.sin_port);
std::cerr << std::endl;
#endif
peerConnectAddress pca;
pca.addr = rUdpAddr;
pca.type = RS_NET_CONN_UDP_PEER_SYNC;
pca.delay = P3CONNMGR_UDP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_UDP_DEFAULT_PERIOD;
addAddressIfUnique(it->second.connAddrs, pca);
}
/* finish it off */
return locked_ConnectAttempt_Complete(&(it->second));
}
bool p3ConnectMgr::retryConnectTCP(std::string id)
{
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
@ -2388,47 +2473,65 @@ bool p3ConnectMgr::retryConnectTCP(std::string id)
/* UDP automatically searches -> no need to push start */
locked_ConnectAttempt_CurrentAddresses(&(it->second));
locked_ConnectAttempt_HistoricalAddresses(&(it->second));
locked_ConnectAttempt_AddDynDNS(&(it->second));
locked_ConnectAttempt_AddTunnel(&(it->second));
/* finish it off */
return locked_ConnectAttempt_Complete(&(it->second));
}
void p3ConnectMgr::locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer)
{
// Just push all the addresses onto the stack.
/* try "current addresses" first */
if (isValidNet(&(it->second.currentlocaladdr.sin_addr)))
if (isValidNet(&(peer->currentlocaladdr.sin_addr)))
{
#ifdef CONN_DEBUG
std::cerr << "Adding tcp connection attempt: ";
std::cerr << "Current Local Addr: " << rs_inet_ntoa(it->second.currentlocaladdr.sin_addr);
std::cerr << ":" << ntohs(it->second.currentlocaladdr.sin_port);
std::cerr << "Current Local Addr: " << rs_inet_ntoa(peer->currentlocaladdr.sin_addr);
std::cerr << ":" << ntohs(peer->currentlocaladdr.sin_port);
std::cerr << std::endl;
#endif
peerConnectAddress pca;
pca.addr = it->second.currentlocaladdr;
pca.addr = peer->currentlocaladdr;
pca.type = RS_NET_CONN_TCP_LOCAL;
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
it->second.connAddrs.push_back(pca);
addAddressIfUnique(peer->connAddrs, pca);
}
if (isValidNet(&(it->second.currentserveraddr.sin_addr)))
if (isValidNet(&(peer->currentserveraddr.sin_addr)))
{
#ifdef CONN_DEBUG
std::cerr << "Adding tcp connection attempt: ";
std::cerr << "Current Ext Addr: " << rs_inet_ntoa(it->second.currentserveraddr.sin_addr);
std::cerr << ":" << ntohs(it->second.currentserveraddr.sin_port);
std::cerr << "Current Ext Addr: " << rs_inet_ntoa(peer->currentserveraddr.sin_addr);
std::cerr << ":" << ntohs(peer->currentserveraddr.sin_port);
std::cerr << std::endl;
#endif
peerConnectAddress pca;
pca.addr = it->second.currentserveraddr;
pca.addr = peer->currentserveraddr;
pca.type = RS_NET_CONN_TCP_EXTERNAL;
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
it->second.connAddrs.push_back(pca);
}
addAddressIfUnique(peer->connAddrs, pca);
}
}
void p3ConnectMgr::locked_ConnectAttempt_HistoricalAddresses(peerConnectState *peer)
{
/* now try historical addresses */
/* try local addresses first */
std::list<pqiIpAddress>::iterator ait;
for(ait = it->second.ipAddrs.mLocal.mAddrs.begin();
ait != it->second.ipAddrs.mLocal.mAddrs.end(); ait++)
for(ait = peer->ipAddrs.mLocal.mAddrs.begin();
ait != peer->ipAddrs.mLocal.mAddrs.end(); ait++)
{
#ifdef CONN_DEBUG
std::cerr << "Adding tcp connection attempt: ";
@ -2442,11 +2545,12 @@ bool p3ConnectMgr::retryConnectTCP(std::string id)
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
it->second.connAddrs.push_back(pca);
addAddressIfUnique(peer->connAddrs, pca);
}
for(ait = it->second.ipAddrs.mExt.mAddrs.begin();
ait != it->second.ipAddrs.mExt.mAddrs.end(); ait++)
for(ait = peer->ipAddrs.mExt.mAddrs.begin();
ait != peer->ipAddrs.mExt.mAddrs.end(); ait++)
{
#ifdef CONN_DEBUG
std::cerr << "Adding tcp connection attempt: ";
@ -2460,18 +2564,23 @@ bool p3ConnectMgr::retryConnectTCP(std::string id)
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
it->second.connAddrs.push_back(pca);
}
addAddressIfUnique(peer->connAddrs, pca);
}
}
void p3ConnectMgr::locked_ConnectAttempt_AddDynDNS(peerConnectState *peer)
{
/* try dyndns address too */
if (!it->second.dyndns.empty()) {
if (!peer->dyndns.empty()) {
struct in_addr addr;
u_short port = it->second.currentserveraddr.sin_port ? it->second.currentserveraddr.sin_port : it->second.currentlocaladdr.sin_port;
u_short port = peer->currentserveraddr.sin_port ? peer->currentserveraddr.sin_port : peer->currentlocaladdr.sin_port;
#ifdef CONN_DEBUG
std::cerr << "Looking up DynDNS address" << std::endl;
#endif
if (port) {
if (getIPAddressFromString (it->second.dyndns.c_str (), &addr))
if (getIPAddressFromString (peer->dyndns.c_str (), &addr))
{
#ifdef CONN_DEBUG
std::cerr << "Adding tcp connection attempt: ";
@ -2488,15 +2597,17 @@ bool p3ConnectMgr::retryConnectTCP(std::string id)
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
it->second.connAddrs.push_back(pca);
addAddressIfUnique(peer->connAddrs, pca);
}
}
}
}
if (!(it->second.state & RS_PEER_S_CONNECTED) && mAllowTunnelConnection)
void p3ConnectMgr::locked_ConnectAttempt_AddTunnel(peerConnectState *peer)
{
if (!(peer->state & RS_PEER_S_CONNECTED) && mAllowTunnelConnection)
{
#ifdef CONN_DEBUG
std::cerr << "Adding TUNNEL Connection Attempt";
@ -2509,38 +2620,70 @@ bool p3ConnectMgr::retryConnectTCP(std::string id)
sockaddr_clear(&pca.addr);
it->second.connAddrs.push_back(pca);
addAddressIfUnique(peer->connAddrs, pca);
}
}
bool p3ConnectMgr::addAddressIfUnique(std::list<peerConnectAddress> &addrList, peerConnectAddress &pca)
{
/* iterate through the list, and make sure it isn't already
* in the list
*/
bool found = false;
std::list<peerConnectAddress>::iterator it;
for(it = addrList.begin(); it != addrList.end(); it++)
{
if ((pca.addr.sin_addr.s_addr == it->addr.sin_addr.s_addr) &&
(pca.addr.sin_port == it->addr.sin_port) &&
(pca.type == it->type))
{
/* already */
return false;
}
}
addrList.push_back(pca);
return true;
}
bool p3ConnectMgr::locked_ConnectAttempt_Complete(peerConnectState *peer)
{
/* flag as last attempt to prevent loop */
//add a random perturbation between 0 and 2 sec.
it->second.lastattempt = time(NULL) + rand() % MAX_RANDOM_ATTEMPT_OFFSET;
peer->lastattempt = time(NULL) + rand() % MAX_RANDOM_ATTEMPT_OFFSET;
if (it->second.inConnAttempt) {
if (peer->inConnAttempt) {
/* -> it'll automatically use the addresses we added */
#ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::retryConnectTCP() Already in CONNECT ATTEMPT";
std::cerr << "p3ConnectMgr::locked_ConnectAttempt_Complete() Already in CONNECT ATTEMPT";
std::cerr << std::endl;
std::cerr << "p3ConnectMgr::retryConnectTCP() Remaining ConnAddr Count: " << it->second.connAddrs.size();
std::cerr << "p3ConnectMgr::locked_ConnectAttempt_Complete() Remaining ConnAddr Count: " << it->second.connAddrs.size();
std::cerr << std::endl;
#endif
return true;
}
/* start a connection attempt */
if (it->second.connAddrs.size() > 0)
if (peer->connAddrs.size() > 0)
{
#ifdef CONN_DEBUG
std::ostringstream out;
out << "p3ConnectMgr::retryConnectTCP() Started CONNECT ATTEMPT! " << " id: " << id ;
out << "p3ConnectMgr::locked_ConnectAttempt_Complete() Started CONNECT ATTEMPT! " << " id: " << id ;
out << std::endl;
out << "p3ConnectMgr::retryConnectTCP() ConnAddr Count: " << it->second.connAddrs.size();
out << "p3ConnectMgr::locked_ConnectAttempt_Complete() ConnAddr Count: " << peer->connAddrs.size();
rslog(RSL_DEBUG_ALERT, p3connectzone, out.str());
std::cerr << out.str() << std::endl;
#endif
it->second.actions |= RS_PEER_CONNECT_REQ;
peer->actions |= RS_PEER_CONNECT_REQ;
mStatusChanged = true;
return true;
}
@ -2548,7 +2691,7 @@ bool p3ConnectMgr::retryConnectTCP(std::string id)
{
#ifdef CONN_DEBUG
std::ostringstream out;
out << "p3ConnectMgr::retryConnectTCP() No addr in the connect attempt list. Not suitable for CONNECT ATTEMPT! " << " id: " << id;
out << "p3ConnectMgr::locked_ConnectAttempt_Complete() No addr in the connect attempt list. Not suitable for CONNECT ATTEMPT! " << " id: " << id;
rslog(RSL_DEBUG_ALERT, p3connectzone, out.str());
std::cerr << out.str() << std::endl;
#endif

View File

@ -361,9 +361,23 @@ void networkConsistencyCheck();
/* monitor control */
void tickMonitors();
/* connect attempts */
/* connect attempts UDP */
bool retryConnectUDP(std::string id, struct sockaddr_in &rUdpAddr);
/* connect attempts TCP */
bool retryConnectTCP(std::string id);
void locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer);
void locked_ConnectAttempt_HistoricalAddresses(peerConnectState *peer);
void locked_ConnectAttempt_AddDynDNS(peerConnectState *peer);
void locked_ConnectAttempt_AddTunnel(peerConnectState *peer);
bool locked_ConnectAttempt_Complete(peerConnectState *peer);
bool addAddressIfUnique(std::list<peerConnectAddress> &addrList,
peerConnectAddress &pca);
protected:
/*****************************************************************/
/*********************** p3config ******************************/

View File

@ -35,6 +35,7 @@ const int pqipersongrpzone = 354;
/****
*#define PGRP_DEBUG 1
****/
#define PGRP_DEBUG 1
/* MUTEX NOTES:
* Functions like GetRsRawItem() lock itself (pqihandler) and