mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-08-23 05:05:30 -04:00
Reworking of networking code to enable Net Restart.
* Stun code now runs continually - to check external network state. * Udpsorter controls DHT stun is on/off. (via p3ConnectMgr) * added code to enable threads to join/restart * enabled NetRestart for UDP and TCP. * tweaked networking code for faster startup (now ~30 seconds - can still be improved). * tweaked debug messages for testing networking * Added test for checking external IP address determination. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1492 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
d5581629ef
commit
2bf94b909a
22 changed files with 774 additions and 81 deletions
|
@ -20,7 +20,7 @@ UDP_OBJ = pqissludp.o
|
|||
OTHER_OBJ = p3notify.o
|
||||
|
||||
|
||||
TESTOBJ = net_test.o dht_test.o net_test1.o
|
||||
TESTOBJ = net_test.o dht_test.o net_test1.o
|
||||
#conn_test.o
|
||||
|
||||
TESTS = net_test dht_test net_test1
|
||||
|
|
|
@ -57,8 +57,6 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#define AUTHGPG_DEBUG 1
|
||||
|
||||
|
||||
/* Turn a set of parameters into a string */
|
||||
static std::string setKeyPairParams(bool useRsa, unsigned int blen,
|
||||
|
|
|
@ -53,7 +53,6 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx);
|
|||
/***********
|
||||
** #define AUTHSSL_DEBUG 1
|
||||
**********/
|
||||
#define AUTHSSL_DEBUG 1
|
||||
|
||||
#ifdef PQI_USE_SSLONLY
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ const uint32_t MAX_UPNP_INIT = 10; /* seconds UPnP timeout */
|
|||
/****
|
||||
* #define CONN_DEBUG 1
|
||||
***/
|
||||
#define CONN_DEBUG 1
|
||||
/****
|
||||
* #define P3CONNMGR_NO_TCP_CONNECTIONS 1
|
||||
***/
|
||||
|
@ -104,6 +105,22 @@ peerConnectState::peerConnectState()
|
|||
return;
|
||||
}
|
||||
|
||||
std::string textPeerConnectState(peerConnectState &state)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "Id: " << state.id << std::endl;
|
||||
out << "NetMode: " << state.netMode << std::endl;
|
||||
out << "VisState: " << state.visState << std::endl;
|
||||
out << "laddr: " << inet_ntoa(state.localaddr.sin_addr)
|
||||
<< ":" << ntohs(state.localaddr.sin_port) << std::endl;
|
||||
out << "eaddr: " << inet_ntoa(state.serveraddr.sin_addr)
|
||||
<< ":" << ntohs(state.serveraddr.sin_port) << std::endl;
|
||||
|
||||
std::string output = out.str();
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
p3ConnectMgr::p3ConnectMgr(p3AuthMgr *am)
|
||||
:p3Config(CONFIG_TYPE_PEERS),
|
||||
|
@ -246,6 +263,62 @@ void p3ConnectMgr::setOwnNetConfig(uint32_t netMode, uint32_t visState)
|
|||
*
|
||||
*/
|
||||
|
||||
/* Called to reseet the whole network stack. this call is
|
||||
* triggered by udp stun address tracking.
|
||||
*
|
||||
* must:
|
||||
* - reset UPnP and DHT.
|
||||
* -
|
||||
*/
|
||||
|
||||
void p3ConnectMgr::netReset()
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::netReset()" << std::endl;
|
||||
std::cerr << "p3ConnectMgr::netReset() shutdown" << std::endl;
|
||||
|
||||
shutdown(); /* blocking shutdown call */
|
||||
|
||||
std::cerr << "p3ConnectMgr::netReset() reset NetStatus" << std::endl;
|
||||
{
|
||||
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetStatus = RS_NET_UNKNOWN;
|
||||
}
|
||||
|
||||
std::cerr << "p3ConnectMgr::netReset() checkNetAddress" << std::endl;
|
||||
/* check Network Address */
|
||||
checkNetAddress();
|
||||
|
||||
/* reset udp network - handled by tou_init! */
|
||||
/* reset tcp network - if necessary */
|
||||
{
|
||||
/* NOTE: nNetListeners should be protected via the Mutex.
|
||||
* HOWEVER, as we NEVER change this list - once its setup
|
||||
* we can get away without it - and assume its constant.
|
||||
*
|
||||
* NB: (*it)->reset_listener must be out of the mutex,
|
||||
* as it calls back to p3ConnMgr.
|
||||
*/
|
||||
|
||||
std::cerr << "p3ConnectMgr::netReset() resetting listeners" << std::endl;
|
||||
std::list<pqiNetListener *>::const_iterator it;
|
||||
for(it = mNetListeners.begin(); it != mNetListeners.end(); it++)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::netReset() reset listener" << std::endl;
|
||||
(*it)->reset_listener();
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "p3ConnectMgr::netReset() done" << std::endl;
|
||||
}
|
||||
|
||||
/* to allow resets of network stuff */
|
||||
void p3ConnectMgr::addNetListener(pqiNetListener *listener)
|
||||
{
|
||||
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
|
||||
mNetListeners.push_back(listener);
|
||||
}
|
||||
|
||||
|
||||
void p3ConnectMgr::netStatusReset()
|
||||
{
|
||||
netFlagOk = true;
|
||||
|
@ -284,6 +357,7 @@ void p3ConnectMgr::netStartup()
|
|||
std::cerr << "p3ConnectMgr::netStartup() tou_stunkeepalive() enabled" << std::endl;
|
||||
#endif
|
||||
tou_stunkeepalive(1);
|
||||
mStunMoreRequired = true;
|
||||
|
||||
ownState.netMode &= ~(RS_NET_MODE_ACTUAL);
|
||||
|
||||
|
@ -293,12 +367,6 @@ void p3ConnectMgr::netStartup()
|
|||
case RS_NET_MODE_TRY_EXT: /* v similar to UDP */
|
||||
ownState.netMode |= RS_NET_MODE_EXT;
|
||||
mNetStatus = RS_NET_UDP_SETUP;
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "p3ConnectMgr::netStartup() disabling stunkeepalive() cos EXT" << std::endl;
|
||||
#endif
|
||||
tou_stunkeepalive(0);
|
||||
mStunMoreRequired = false; /* only need to validate address (EXT) */
|
||||
|
||||
break;
|
||||
|
||||
case RS_NET_MODE_TRY_UDP:
|
||||
|
@ -552,10 +620,6 @@ void p3ConnectMgr::netUpnpCheck()
|
|||
/* UPnP Failed us! */
|
||||
mUpnpAddrValid = false;
|
||||
mNetStatus = RS_NET_UDP_SETUP;
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "p3ConnectMgr::netUpnpCheck() enabling stunkeepalive() cos UDP" << std::endl;
|
||||
#endif
|
||||
tou_stunkeepalive(1);
|
||||
|
||||
connMtx.unlock(); /* UNLOCK MUTEX */
|
||||
}
|
||||
|
@ -577,11 +641,6 @@ void p3ConnectMgr::netUpnpCheck()
|
|||
mNetStatus = RS_NET_UDP_SETUP;
|
||||
/* Fix netMode & Clear others! */
|
||||
ownState.netMode = RS_NET_MODE_TRY_UPNP | RS_NET_MODE_UPNP;
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "p3ConnectMgr::netUpnpCheck() disabling stunkeepalive() cos uPnP" << std::endl;
|
||||
#endif
|
||||
tou_stunkeepalive(0);
|
||||
mStunMoreRequired = false; /* only need to validate address (UPNP) */
|
||||
|
||||
connMtx.unlock(); /* UNLOCK MUTEX */
|
||||
}
|
||||
|
@ -645,8 +704,6 @@ void p3ConnectMgr::netUdpCheck()
|
|||
#endif
|
||||
ownState.netMode &= ~(RS_NET_MODE_ACTUAL);
|
||||
ownState.netMode |= RS_NET_MODE_UNREACHABLE;
|
||||
tou_stunkeepalive(0);
|
||||
mStunMoreRequired = false; /* no point -> unreachable (EXT) */
|
||||
|
||||
/* send a system warning message */
|
||||
pqiNotify *notify = getPqiNotify();
|
||||
|
@ -882,44 +939,137 @@ void p3ConnectMgr::stunInit()
|
|||
mStunMoreRequired = true;
|
||||
}
|
||||
|
||||
/* This is continually called
|
||||
*
|
||||
* checks whether the ext address is consistent
|
||||
*
|
||||
* checks if UDP needs more stun peers - or not
|
||||
* The status is passed onto the DHT.
|
||||
*
|
||||
*/
|
||||
|
||||
bool p3ConnectMgr::stunCheck()
|
||||
{
|
||||
/* check if we've got a Stun result */
|
||||
bool stunOk = false;
|
||||
|
||||
#ifdef CONN_DEBUG
|
||||
//std::cerr << "p3ConnectMgr::stunCheck()" << std::endl;
|
||||
std::cerr << "p3ConnectMgr::stunCheck()" << std::endl;
|
||||
#endif
|
||||
|
||||
{
|
||||
RsStackMutex stack(connMtx); /********* LOCK STACK MUTEX ******/
|
||||
/* check udp address stability */
|
||||
|
||||
bool netDone = false;
|
||||
bool doNetReset = false;
|
||||
|
||||
/* if DONE -> return */
|
||||
if (mStunStatus == RS_STUN_DONE)
|
||||
{
|
||||
return true;
|
||||
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
|
||||
mStunStatus = RS_STUN_DHT;
|
||||
netDone = (mNetStatus == RS_NET_DONE);
|
||||
}
|
||||
|
||||
if (mStunFound >= RS_STUN_FOUND_MIN)
|
||||
struct sockaddr_in raddr;
|
||||
socklen_t rlen = sizeof(raddr);
|
||||
struct sockaddr_in eaddr;
|
||||
socklen_t elen = sizeof(eaddr);
|
||||
uint8_t stable;
|
||||
uint32_t failCount;
|
||||
time_t lastSent;
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (netDone)
|
||||
{
|
||||
mStunMoreRequired = false;
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "NetSetupDone: Checking if network is same" << std::endl;
|
||||
#endif
|
||||
|
||||
if (0 < tou_extaddr((struct sockaddr *) &raddr, &rlen, &stable))
|
||||
{
|
||||
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
if ((mStunExtAddr.sin_addr.s_addr != raddr.sin_addr.s_addr) ||
|
||||
(mStunAddrStable != stable))
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "Ext Address Changed -> netReset" << std::endl;
|
||||
#endif
|
||||
|
||||
doNetReset = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "Ext Address Same: ok!" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "No Ext Address -> netReset" << std::endl;
|
||||
#endif
|
||||
|
||||
doNetReset = true;
|
||||
}
|
||||
}
|
||||
stunOk = (!mStunMoreRequired);
|
||||
}
|
||||
|
||||
|
||||
if (udpExtAddressCheck() && (stunOk))
|
||||
if (doNetReset)
|
||||
{
|
||||
/* set external UDP address */
|
||||
netAssistStun(false);
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "Resetting Network" << std::endl;
|
||||
#endif
|
||||
|
||||
netReset();
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for(i = 0; tou_getstunpeer(i, (struct sockaddr *) &raddr, &rlen,
|
||||
(struct sockaddr *) &eaddr, &elen,
|
||||
&failCount, &lastSent); i++)
|
||||
{
|
||||
std::cerr << "STUN PEERS: ";
|
||||
std::cerr << " raddr: " << inet_ntoa(raddr.sin_addr) << ":" << ntohs(raddr.sin_port);
|
||||
std::cerr << " eaddr: " << inet_ntoa(eaddr.sin_addr) << ":" << ntohs(eaddr.sin_port);
|
||||
if (lastSent)
|
||||
{
|
||||
std::cerr << " failCount: " << failCount << " lastSent: " << now-lastSent;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << " Unused ";
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
/* pass on udp status to dht */
|
||||
if (tou_needstunpeers())
|
||||
{
|
||||
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
mStunStatus = RS_STUN_DONE;
|
||||
if (!mStunMoreRequired)
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "Telling DHT More Stun Required" << std::endl;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
netAssistStun(true);
|
||||
mStunMoreRequired = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
if (mStunMoreRequired)
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "Telling DHT No More Stun Required" << std::endl;
|
||||
#endif
|
||||
|
||||
netAssistStun(false);
|
||||
mStunMoreRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void p3ConnectMgr::stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags)
|
||||
|
|
|
@ -162,6 +162,8 @@ class peerConnectState
|
|||
|
||||
};
|
||||
|
||||
std::string textPeerConnectState(peerConnectState &state);
|
||||
|
||||
|
||||
class p3ConnectMgr: public pqiConnectCb, public p3Config
|
||||
{
|
||||
|
@ -177,6 +179,8 @@ void addNetAssistFirewall(uint32_t type, pqiNetAssistFirewall *);
|
|||
|
||||
bool checkNetAddress(); /* check our address is sensible */
|
||||
|
||||
void addNetListener(pqiNetListener *listener);
|
||||
|
||||
/*************** External Control ****************/
|
||||
bool shutdown(); /* blocking shutdown call */
|
||||
|
||||
|
@ -273,6 +277,8 @@ virtual bool netAssistSetAddress( struct sockaddr_in &laddr,
|
|||
|
||||
|
||||
/* Internal Functions */
|
||||
void netReset();
|
||||
|
||||
void statusTick();
|
||||
void netTick();
|
||||
void netStartup();
|
||||
|
@ -342,6 +348,8 @@ private:
|
|||
|
||||
RsMutex connMtx; /* protects below */
|
||||
|
||||
std::list<pqiNetListener *> mNetListeners;
|
||||
|
||||
time_t mNetInitTS;
|
||||
uint32_t mNetStatus;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ const int p3dhtzone = 3892;
|
|||
#define DHT_DEFAULT_WAITTIME 1 /* Std sleep break period */
|
||||
|
||||
#define DHT_NUM_BOOTSTRAP_BINS 8
|
||||
#define DHT_MIN_BOOTSTRAP_REQ_PERIOD 30
|
||||
#define DHT_MIN_BOOTSTRAP_REQ_PERIOD 5
|
||||
|
||||
void printDhtPeerEntry(dhtPeerEntry *ent, std::ostream &out);
|
||||
|
||||
|
@ -1027,20 +1027,21 @@ int p3DhtMgr::checkStunState()
|
|||
}
|
||||
else if (mDhtState == DHT_STATE_FIND_STUN)
|
||||
{
|
||||
/* if we run out of stun peers -> get some more */
|
||||
if (stunIds.size() < 1)
|
||||
{
|
||||
}
|
||||
|
||||
/* if we run out of stun peers -> get some more */
|
||||
if (stunIds.size() < 1)
|
||||
{
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "WARNING: out of Stun Peers - switching to Active Now" << std::endl;
|
||||
std::cerr << "WARNING: out of Stun Peers - Fetching some more" << std::endl;
|
||||
#endif
|
||||
mDhtState = DHT_STATE_ACTIVE;
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
mDhtState = DHT_STATE_ACTIVE;
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
/* this is a locked function */
|
||||
getDhtBootstrapList();
|
||||
/* this is a locked function */
|
||||
getDhtBootstrapList();
|
||||
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
}
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
|
|
@ -134,5 +134,15 @@ virtual void peerConnectRequest(std::string id,
|
|||
virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags);
|
||||
};
|
||||
|
||||
|
||||
/* network listener interface - used to reset network addresses */
|
||||
class pqiNetListener
|
||||
{
|
||||
public:
|
||||
virtual int reset_listener() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // PQI_MONITOR_H
|
||||
|
||||
|
|
|
@ -186,6 +186,8 @@ int pqipersongrp::init_listener()
|
|||
|
||||
int pqipersongrp::restart_listener()
|
||||
{
|
||||
std::cerr << "pqipersongrp::restart_listener()" << std::endl;
|
||||
|
||||
// stop it,
|
||||
// change the address.
|
||||
// restart.
|
||||
|
@ -197,6 +199,8 @@ int pqipersongrp::restart_listener()
|
|||
|
||||
if (haveListener)
|
||||
{
|
||||
std::cerr << "pqipersongrp::restart_listener() haveListener" << std::endl;
|
||||
|
||||
peerConnectState state;
|
||||
mConnMgr->getOwnNetStatus(state);
|
||||
|
||||
|
@ -205,6 +209,9 @@ int pqipersongrp::restart_listener()
|
|||
pqil -> resetlisten();
|
||||
pqil -> setListenAddr(state.localaddr);
|
||||
pqil -> setuplisten();
|
||||
|
||||
std::cerr << "pqipersongrp::restart_listener() done!" << std::endl;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -46,13 +46,15 @@ const unsigned long PQIPERSON_NO_LISTENER = 0x0001;
|
|||
|
||||
const unsigned long PQIPERSON_ALL_BW_LIMITED = 0x0010;
|
||||
|
||||
class pqipersongrp: public pqihandler, public pqiMonitor, public p3ServiceServer
|
||||
class pqipersongrp: public pqihandler, public pqiMonitor, public p3ServiceServer, public pqiNetListener
|
||||
{
|
||||
public:
|
||||
pqipersongrp(SecurityPolicy *, unsigned long flags);
|
||||
|
||||
/*************************** Setup *************************/
|
||||
/* pqilistener */
|
||||
|
||||
virtual int reset_listener() { return restart_listener(); }
|
||||
int init_listener();
|
||||
int restart_listener();
|
||||
|
||||
|
|
|
@ -171,7 +171,27 @@ int pqissllistenbase::setuplisten()
|
|||
out << "\tSetup Port: " << ntohs(laddr.sin_port);
|
||||
|
||||
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
|
||||
std::cerr << out.str() << std::endl;
|
||||
}
|
||||
|
||||
/* added a call to REUSEADDR, so that we can re-open an existing socket
|
||||
* when we restart_listener.
|
||||
*/
|
||||
|
||||
{
|
||||
int on = 1;
|
||||
if (setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "pqissllistenbase::setuplisten()";
|
||||
out << " Cannot setsockopt SO_REUSEADDR!" << std::endl;
|
||||
showSocketError(out);
|
||||
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
|
||||
std::cerr << out.str() << std::endl;
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != (err = bind(lsock, (struct sockaddr *) &laddr, sizeof(laddr))))
|
||||
{
|
||||
|
@ -180,6 +200,7 @@ int pqissllistenbase::setuplisten()
|
|||
out << " Cannot Bind to Local Address!" << std::endl;
|
||||
showSocketError(out);
|
||||
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
|
||||
std::cerr << out.str() << std::endl;
|
||||
|
||||
exit(1);
|
||||
return -1;
|
||||
|
@ -198,6 +219,7 @@ int pqissllistenbase::setuplisten()
|
|||
out << err << std::endl;
|
||||
showSocketError(out);
|
||||
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
|
||||
std::cerr << out.str() << std::endl;
|
||||
|
||||
exit(1);
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue