diff --git a/libretroshare/src/dht/p3bitdht.cc b/libretroshare/src/dht/p3bitdht.cc index 01296a896..964319c57 100644 --- a/libretroshare/src/dht/p3bitdht.cc +++ b/libretroshare/src/dht/p3bitdht.cc @@ -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 { diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 80642360a..a32db5def 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -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 \ diff --git a/libretroshare/src/pqi/p3connmgr.cc b/libretroshare/src/pqi/p3connmgr.cc index a83dd648d..d10858a3a 100644 --- a/libretroshare/src/pqi/p3connmgr.cc +++ b/libretroshare/src/pqi/p3connmgr.cc @@ -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::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::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 &addrList, peerConnectAddress &pca) +{ + /* iterate through the list, and make sure it isn't already + * in the list + */ + + bool found = false; + + std::list::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 diff --git a/libretroshare/src/pqi/p3connmgr.h b/libretroshare/src/pqi/p3connmgr.h index f01d80342..56d7773ed 100644 --- a/libretroshare/src/pqi/p3connmgr.h +++ b/libretroshare/src/pqi/p3connmgr.h @@ -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 &addrList, + peerConnectAddress &pca); + + protected: /*****************************************************************/ /*********************** p3config ******************************/ diff --git a/libretroshare/src/pqi/pqipersongrp.cc b/libretroshare/src/pqi/pqipersongrp.cc index 96a93d7bb..079ea17d8 100644 --- a/libretroshare/src/pqi/pqipersongrp.cc +++ b/libretroshare/src/pqi/pqipersongrp.cc @@ -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