mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-25 23:49:35 -05:00
Additions to tcponudp to add a TouKeepAlive system.
This is only used if we are in 'firewalled' mode. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@360 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
31454138b7
commit
6dd3d30d8e
@ -75,7 +75,7 @@ peerConnectState::peerConnectState()
|
|||||||
|
|
||||||
name("nameless"), state(0), actions(0),
|
name("nameless"), state(0), actions(0),
|
||||||
source(0),
|
source(0),
|
||||||
inConnAttempt(0), connAttemptTS(0)
|
inConnAttempt(0), lastattempt(0)
|
||||||
{
|
{
|
||||||
sockaddr_clear(&localaddr);
|
sockaddr_clear(&localaddr);
|
||||||
sockaddr_clear(&serveraddr);
|
sockaddr_clear(&serveraddr);
|
||||||
@ -215,6 +215,9 @@ void p3ConnectMgr::netStartup()
|
|||||||
/* StunInit gets a list of peers, and asks the DHT to find them...
|
/* StunInit gets a list of peers, and asks the DHT to find them...
|
||||||
* This is needed for all systems so startup straight away
|
* This is needed for all systems so startup straight away
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONN_DEBUG
|
||||||
|
std::cerr << "p3ConnectMgr::netStartup()" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
loadConfiguration();
|
loadConfiguration();
|
||||||
netDhtInit();
|
netDhtInit();
|
||||||
@ -228,18 +231,27 @@ void p3ConnectMgr::netStartup()
|
|||||||
|
|
||||||
mNetInitTS = time(NULL);
|
mNetInitTS = time(NULL);
|
||||||
|
|
||||||
|
#ifdef CONN_DEBUG
|
||||||
|
std::cerr << "p3ConnectMgr::netStartup() tou_stunkeepalive() enabled" << std::endl;
|
||||||
|
#endif
|
||||||
|
tou_stunkeepalive(1);
|
||||||
|
|
||||||
ownState.netMode &= ~(RS_NET_MODE_ACTUAL);
|
ownState.netMode &= ~(RS_NET_MODE_ACTUAL);
|
||||||
|
|
||||||
switch(ownState.netMode & RS_NET_MODE_TRYMODE)
|
switch(ownState.netMode & RS_NET_MODE_TRYMODE)
|
||||||
{
|
{
|
||||||
case RS_NET_MODE_TRY_UPNP:
|
case RS_NET_MODE_TRY_UPNP:
|
||||||
mNetStatus = RS_NET_UPNP_INIT;
|
|
||||||
ownState.netMode |= RS_NET_MODE_UDP;
|
ownState.netMode |= RS_NET_MODE_UDP;
|
||||||
|
mNetStatus = RS_NET_UPNP_INIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RS_NET_MODE_TRY_EXT: /* v similar to UDP */
|
case RS_NET_MODE_TRY_EXT: /* v similar to UDP */
|
||||||
ownState.netMode |= RS_NET_MODE_EXT;
|
ownState.netMode |= RS_NET_MODE_EXT;
|
||||||
mNetStatus = RS_NET_UDP_SETUP;
|
mNetStatus = RS_NET_UDP_SETUP;
|
||||||
|
#ifdef CONN_DEBUG
|
||||||
|
std::cerr << "p3ConnectMgr::netStartup() disabling stunkeepalive() cos EXT" << std::endl;
|
||||||
|
#endif
|
||||||
|
tou_stunkeepalive(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RS_NET_MODE_TRY_UDP:
|
case RS_NET_MODE_TRY_UDP:
|
||||||
@ -322,6 +334,9 @@ void p3ConnectMgr::netTick()
|
|||||||
|
|
||||||
void p3ConnectMgr::netUdpInit()
|
void p3ConnectMgr::netUdpInit()
|
||||||
{
|
{
|
||||||
|
#ifdef CONN_DEBUG
|
||||||
|
std::cerr << "p3ConnectMgr::netUdpInit()" << std::endl;
|
||||||
|
#endif
|
||||||
connMtx.lock(); /* LOCK MUTEX */
|
connMtx.lock(); /* LOCK MUTEX */
|
||||||
|
|
||||||
struct sockaddr_in iaddr = ownState.localaddr;
|
struct sockaddr_in iaddr = ownState.localaddr;
|
||||||
@ -335,6 +350,9 @@ void p3ConnectMgr::netUdpInit()
|
|||||||
|
|
||||||
void p3ConnectMgr::netDhtInit()
|
void p3ConnectMgr::netDhtInit()
|
||||||
{
|
{
|
||||||
|
#ifdef CONN_DEBUG
|
||||||
|
std::cerr << "p3ConnectMgr::netDhtInit()" << std::endl;
|
||||||
|
#endif
|
||||||
connMtx.lock(); /* LOCK MUTEX */
|
connMtx.lock(); /* LOCK MUTEX */
|
||||||
|
|
||||||
uint32_t vs = ownState.visState;
|
uint32_t vs = ownState.visState;
|
||||||
@ -347,6 +365,9 @@ void p3ConnectMgr::netDhtInit()
|
|||||||
|
|
||||||
void p3ConnectMgr::netUpnpInit()
|
void p3ConnectMgr::netUpnpInit()
|
||||||
{
|
{
|
||||||
|
#ifdef CONN_DEBUG
|
||||||
|
std::cerr << "p3ConnectMgr::netUpnpInit()" << std::endl;
|
||||||
|
#endif
|
||||||
uint16_t eport, iport;
|
uint16_t eport, iport;
|
||||||
|
|
||||||
connMtx.lock(); /* LOCK MUTEX */
|
connMtx.lock(); /* LOCK MUTEX */
|
||||||
@ -390,6 +411,10 @@ void p3ConnectMgr::netUpnpCheck()
|
|||||||
/* UPnP Failed us! */
|
/* UPnP Failed us! */
|
||||||
mUpnpAddrValid = false;
|
mUpnpAddrValid = false;
|
||||||
mNetStatus = RS_NET_UDP_SETUP;
|
mNetStatus = RS_NET_UDP_SETUP;
|
||||||
|
#ifdef CONN_DEBUG
|
||||||
|
std::cerr << "p3ConnectMgr::netUpnpCheck() ensabling stunkeepalive() cos UDP" << std::endl;
|
||||||
|
#endif
|
||||||
|
tou_stunkeepalive(1);
|
||||||
|
|
||||||
connMtx.unlock(); /* UNLOCK MUTEX */
|
connMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
}
|
}
|
||||||
@ -404,6 +429,10 @@ void p3ConnectMgr::netUpnpCheck()
|
|||||||
mNetStatus = RS_NET_UDP_SETUP;
|
mNetStatus = RS_NET_UDP_SETUP;
|
||||||
/* Fix netMode & Clear others! */
|
/* Fix netMode & Clear others! */
|
||||||
ownState.netMode = RS_NET_MODE_TRY_UPNP | RS_NET_MODE_UPNP;
|
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);
|
||||||
|
|
||||||
connMtx.unlock(); /* UNLOCK MUTEX */
|
connMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
}
|
}
|
||||||
@ -964,6 +993,7 @@ bool p3ConnectMgr::connectAttempt(std::string id, struct sockaddr_in &addr,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it->second.lastattempt = time(NULL); /* time of last connect attempt */
|
||||||
it->second.inConnAttempt = true;
|
it->second.inConnAttempt = true;
|
||||||
it->second.currentConnAddr = it->second.connAddrs.front();
|
it->second.currentConnAddr = it->second.connAddrs.front();
|
||||||
it->second.connAddrs.pop_front();
|
it->second.connAddrs.pop_front();
|
||||||
|
@ -138,7 +138,7 @@ class peerConnectState
|
|||||||
|
|
||||||
/* a list of connect attempts to make (in order) */
|
/* a list of connect attempts to make (in order) */
|
||||||
bool inConnAttempt;
|
bool inConnAttempt;
|
||||||
time_t connAttemptTS;
|
time_t lastattempt;
|
||||||
peerConnectAddress currentConnAddr;
|
peerConnectAddress currentConnAddr;
|
||||||
std::list<peerConnectAddress> connAddrs;
|
std::list<peerConnectAddress> connAddrs;
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
* #define P3DHTMGR_USE_LOCAL_UDP_CONN 1 // For Testing only
|
* #define P3DHTMGR_USE_LOCAL_UDP_CONN 1 // For Testing only
|
||||||
****/
|
****/
|
||||||
|
|
||||||
|
#define P3DHTMGR_USE_LOCAL_UDP_CONN 1 // For Testing only
|
||||||
|
|
||||||
/**** DHT State Variables ****
|
/**** DHT State Variables ****
|
||||||
* TODO:
|
* TODO:
|
||||||
* (1) notify call in.
|
* (1) notify call in.
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "rsserver/p3face.h"
|
#include "rsserver/p3face.h"
|
||||||
|
#include "tcponudp/tou.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -176,6 +177,9 @@ void RsServer::run()
|
|||||||
{
|
{
|
||||||
lastSec = (int) ts;
|
lastSec = (int) ts;
|
||||||
|
|
||||||
|
// Every second! (UDP keepalive).
|
||||||
|
tou_tick_stunkeepalive();
|
||||||
|
|
||||||
// every five loops (> 5 secs)
|
// every five loops (> 5 secs)
|
||||||
if (loop % 5 == 0)
|
if (loop % 5 == 0)
|
||||||
{
|
{
|
||||||
|
@ -89,6 +89,24 @@ int tou_stunpeer(const struct sockaddr *my_addr, socklen_t addrlen,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tou_stunkeepalive(int required)
|
||||||
|
{
|
||||||
|
if (!tou_inited)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
udps->setStunKeepAlive(required);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tou_tick_stunkeepalive()
|
||||||
|
{
|
||||||
|
if (!tou_inited)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
udps->tick();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen)
|
int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen)
|
||||||
{
|
{
|
||||||
if (!tou_inited)
|
if (!tou_inited)
|
||||||
|
@ -66,12 +66,18 @@ extern "C" {
|
|||||||
* (3) offer more stunpeers, for external address determination.
|
* (3) offer more stunpeers, for external address determination.
|
||||||
* int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char *id);
|
* int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char *id);
|
||||||
* (4) repeat (2)+(3) until a valid extaddr is returned.
|
* (4) repeat (2)+(3) until a valid extaddr is returned.
|
||||||
|
* (5) if stunkeepalive is required, then periodically send out
|
||||||
|
* stun packets to maintain external firewall port.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int tou_init(const struct sockaddr *my_addr, socklen_t addrlen);
|
int tou_init(const struct sockaddr *my_addr, socklen_t addrlen);
|
||||||
int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen);
|
int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen);
|
||||||
int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char *id);
|
int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char *id);
|
||||||
|
int tou_stunkeepalive(int required);
|
||||||
|
int tou_tick_stunkeepalive();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Connections are as similar to UNIX as possible
|
/* Connections are as similar to UNIX as possible
|
||||||
* (1) create a socket: tou_socket() this reserves a socket id.
|
* (1) create a socket: tou_socket() this reserves a socket id.
|
||||||
|
@ -39,7 +39,10 @@ static const int STUN_TTL = 64;
|
|||||||
#define DEBUG_UDP_SORTER 1
|
#define DEBUG_UDP_SORTER 1
|
||||||
|
|
||||||
UdpSorter::UdpSorter(struct sockaddr_in &local)
|
UdpSorter::UdpSorter(struct sockaddr_in &local)
|
||||||
:udpLayer(NULL), laddr(local), eaddrKnown(false)
|
:udpLayer(NULL), laddr(local), eaddrKnown(false),
|
||||||
|
mStunKeepAlive(false), mStunLastRecv(0), mStunLastSend(0)
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
sockaddr_clear(&eaddr);
|
sockaddr_clear(&eaddr);
|
||||||
|
|
||||||
@ -58,6 +61,7 @@ void UdpSorter::recvPkt(void *data, int size, struct sockaddr_in &from)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
sortMtx.lock(); /********** LOCK MUTEX *********/
|
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||||
|
mStunLastRecv = time(NULL);
|
||||||
|
|
||||||
/* look for a peer */
|
/* look for a peer */
|
||||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||||
@ -70,7 +74,7 @@ void UdpSorter::recvPkt(void *data, int size, struct sockaddr_in &from)
|
|||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
||||||
/* respond */
|
/* respond */
|
||||||
handleStunPkt(data, size, from);
|
locked_handleStunPkt(data, size, from);
|
||||||
}
|
}
|
||||||
else if (it == streams.end())
|
else if (it == streams.end())
|
||||||
{
|
{
|
||||||
@ -146,6 +150,8 @@ int UdpSorter::tick()
|
|||||||
#ifdef DEBUG_UDP_SORTER
|
#ifdef DEBUG_UDP_SORTER
|
||||||
std::cerr << "UdpSorter::tick()" << std::endl;
|
std::cerr << "UdpSorter::tick()" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
checkStunKeepAlive();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +193,7 @@ int UdpSorter::addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr)
|
|||||||
/******************************* STUN Handling ********************************/
|
/******************************* STUN Handling ********************************/
|
||||||
|
|
||||||
/* respond */
|
/* respond */
|
||||||
bool UdpSorter::handleStunPkt(void *data, int size, struct sockaddr_in &from)
|
bool UdpSorter::locked_handleStunPkt(void *data, int size, struct sockaddr_in &from)
|
||||||
{
|
{
|
||||||
if (size == 20) /* request */
|
if (size == 20) /* request */
|
||||||
{
|
{
|
||||||
@ -230,6 +236,9 @@ bool UdpSorter::handleStunPkt(void *data, int size, struct sockaddr_in &from)
|
|||||||
#endif
|
#endif
|
||||||
eaddrKnown = true;
|
eaddrKnown = true;
|
||||||
eaddr = eAddr;
|
eaddr = eAddr;
|
||||||
|
|
||||||
|
locked_recvdStun(from);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,21 +251,6 @@ bool UdpSorter::handleStunPkt(void *data, int size, struct sockaddr_in &from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool UdpSorter::addStunPeer(const struct sockaddr_in &remote, const char *peerid)
|
|
||||||
{
|
|
||||||
/* add to the list */
|
|
||||||
#ifdef DEBUG_UDP_SORTER
|
|
||||||
std::cerr << "UdpSorter::addStunPeer()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
|
|
||||||
std::cerr << "UdpSorter::addStunPeer() - just stun it!";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
doStun(remote);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSorter::externalAddr(struct sockaddr_in &external)
|
bool UdpSorter::externalAddr(struct sockaddr_in &external)
|
||||||
{
|
{
|
||||||
if (eaddrKnown)
|
if (eaddrKnown)
|
||||||
@ -301,6 +295,10 @@ int UdpSorter::doStun(struct sockaddr_in stun_addr)
|
|||||||
/* send it off */
|
/* send it off */
|
||||||
int sentlen = sendPkt(stundata, tmplen, stun_addr, STUN_TTL);
|
int sentlen = sendPkt(stundata, tmplen, stun_addr, STUN_TTL);
|
||||||
|
|
||||||
|
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||||
|
mStunLastSend = time(NULL);
|
||||||
|
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||||
|
|
||||||
#ifdef DEBUG_UDP_SORTER
|
#ifdef DEBUG_UDP_SORTER
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "UdpSorter::doStun() Sent Stun Packet(" << sentlen << ") from:";
|
out << "UdpSorter::doStun() Sent Stun Packet(" << sentlen << ") from:";
|
||||||
@ -444,3 +442,223 @@ bool UdpSorter::isStunPacket(void *data, int size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************* STUN Handling ********************************
|
||||||
|
* The KeepAlive part - slightly more complicated
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int32_t TOU_STUN_MAX_FAIL_COUNT = 10; /* 10 tries (could be higher?) */
|
||||||
|
const int32_t TOU_STUN_MAX_SEND_RATE = 5; /* every 5 seconds */
|
||||||
|
const int32_t TOU_STUN_MAX_RECV_RATE = 25; /* every 25 seconds */
|
||||||
|
|
||||||
|
/******************************* STUN Handling ********************************/
|
||||||
|
|
||||||
|
bool UdpSorter::setStunKeepAlive(uint32_t required)
|
||||||
|
{
|
||||||
|
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||||
|
|
||||||
|
mStunKeepAlive = (required != 0);
|
||||||
|
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::setStunKeepAlive() to: " << mStunKeepAlive;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UdpSorter::addStunPeer(const struct sockaddr_in &remote, const char *peerid)
|
||||||
|
{
|
||||||
|
/* add to the list */
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::addStunPeer()";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
storeStunPeer(remote, peerid);
|
||||||
|
|
||||||
|
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||||
|
bool needStun = (!eaddrKnown);
|
||||||
|
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||||
|
|
||||||
|
if (needStun)
|
||||||
|
{
|
||||||
|
doStun(remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UdpSorter::storeStunPeer(const struct sockaddr_in &remote, const char *peerid)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::storeStunPeer()";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||||
|
|
||||||
|
std::list<TouStunPeer>::iterator it;
|
||||||
|
for(it = mStunList.begin(); it != mStunList.end(); it++)
|
||||||
|
{
|
||||||
|
if ((remote.sin_addr.s_addr == it->remote.sin_addr.s_addr) &&
|
||||||
|
(remote.sin_port == it->remote.sin_port))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::storeStunPeer() Peer Already There!";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
/* already there */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TouStunPeer peer(std::string(peerid), remote);
|
||||||
|
mStunList.push_back(peer);
|
||||||
|
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::storeStunPeer() Added Peer";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UdpSorter::checkStunKeepAlive()
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::checkStunKeepAlive()";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TouStunPeer peer;
|
||||||
|
time_t now;
|
||||||
|
{
|
||||||
|
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||||
|
|
||||||
|
if (!mStunKeepAlive)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::checkStunKeepAlive() FALSE";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
return false; /* all good */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if we need to send one now */
|
||||||
|
now = time(NULL);
|
||||||
|
|
||||||
|
if ((now - mStunLastSend < TOU_STUN_MAX_SEND_RATE) ||
|
||||||
|
(now - mStunLastRecv < TOU_STUN_MAX_RECV_RATE))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::checkStunKeepAlive() To Fast ... delaying";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
/* too fast */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mStunList.size() < 1)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::checkStunKeepAlive() No Peers in List!";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* extract entry */
|
||||||
|
peer = mStunList.front();
|
||||||
|
mStunList.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
doStun(peer.remote);
|
||||||
|
|
||||||
|
{
|
||||||
|
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||||
|
if (peer.failCount < TOU_STUN_MAX_FAIL_COUNT)
|
||||||
|
{
|
||||||
|
peer.failCount++;
|
||||||
|
peer.lastsend = now;
|
||||||
|
mStunList.push_back(peer);
|
||||||
|
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::checkStunKeepAlive() pushing Stun peer to back of list";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::checkStunKeepAlive() Discarding bad stun peer";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
locked_printStunList();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UdpSorter::locked_recvdStun(const struct sockaddr_in &remote)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_UDP_SORTER
|
||||||
|
std::cerr << "UdpSorter::recvdStun()";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
locked_printStunList();
|
||||||
|
|
||||||
|
std::list<TouStunPeer>::iterator it;
|
||||||
|
for(it = mStunList.begin(); it != mStunList.end(); it++)
|
||||||
|
{
|
||||||
|
if ((remote.sin_addr.s_addr == it->remote.sin_addr.s_addr) &&
|
||||||
|
(remote.sin_port == it->remote.sin_port))
|
||||||
|
{
|
||||||
|
it->failCount = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UdpSorter::locked_printStunList()
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
out << "locked_printStunList()" << std::endl;
|
||||||
|
out << "\tLastSend: " << now - mStunLastSend << std::endl;
|
||||||
|
out << "\tLastRecv: " << now - mStunLastRecv << std::endl;
|
||||||
|
|
||||||
|
std::list<TouStunPeer>::iterator it;
|
||||||
|
for(it = mStunList.begin(); it != mStunList.end(); it++)
|
||||||
|
{
|
||||||
|
out << "id:" << it->id << " addr: " << inet_ntoa(it->remote.sin_addr);
|
||||||
|
out << ":" << htons(it->remote.sin_port);
|
||||||
|
out << " failCount: " << it->failCount;
|
||||||
|
out << " lastSend: " << now - it->lastsend;
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << out.str();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +43,24 @@ class UdpPeer
|
|||||||
virtual void recvPkt(void *data, int size) = 0;
|
virtual void recvPkt(void *data, int size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TouStunPeer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TouStunPeer()
|
||||||
|
:lastsend(0), failCount(0) { return; }
|
||||||
|
|
||||||
|
TouStunPeer(std::string id_in, const struct sockaddr_in &addr)
|
||||||
|
:id(id_in), remote(addr), lastsend(0), failCount(0) { return; }
|
||||||
|
|
||||||
|
std::string id;
|
||||||
|
struct sockaddr_in remote;
|
||||||
|
time_t lastsend;
|
||||||
|
uint32_t failCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class UdpSorter: public UdpReceiver
|
class UdpSorter: public UdpReceiver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -52,7 +70,11 @@ virtual ~UdpSorter() { return; }
|
|||||||
|
|
||||||
/* add a TCPonUDP stream */
|
/* add a TCPonUDP stream */
|
||||||
int addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr);
|
int addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr);
|
||||||
|
|
||||||
|
bool setStunKeepAlive(uint32_t required);
|
||||||
bool addStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
bool addStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
||||||
|
bool checkStunKeepAlive();
|
||||||
|
|
||||||
bool externalAddr(struct sockaddr_in &remote);
|
bool externalAddr(struct sockaddr_in &remote);
|
||||||
|
|
||||||
/* Packet IO */
|
/* Packet IO */
|
||||||
@ -76,7 +98,7 @@ int status(std::ostream &out);
|
|||||||
|
|
||||||
/* STUN handling */
|
/* STUN handling */
|
||||||
bool isStunPacket(void *data, int size);
|
bool isStunPacket(void *data, int size);
|
||||||
bool handleStunPkt(void *data, int size, struct sockaddr_in &from);
|
bool locked_handleStunPkt(void *data, int size, struct sockaddr_in &from);
|
||||||
|
|
||||||
int doStun(struct sockaddr_in stun_addr);
|
int doStun(struct sockaddr_in stun_addr);
|
||||||
bool response(void *stun_pkt, int size, struct sockaddr_in &addr);
|
bool response(void *stun_pkt, int size, struct sockaddr_in &addr);
|
||||||
@ -84,7 +106,10 @@ bool response(void *stun_pkt, int size, struct sockaddr_in &addr);
|
|||||||
void *generate_stun_reply(struct sockaddr_in *stun_addr, int *len);
|
void *generate_stun_reply(struct sockaddr_in *stun_addr, int *len);
|
||||||
bool generate_stun_pkt(void *stun_pkt, int *len);
|
bool generate_stun_pkt(void *stun_pkt, int *len);
|
||||||
|
|
||||||
|
/* stun keepAlive */
|
||||||
|
bool locked_printStunList();
|
||||||
|
bool locked_recvdStun(const struct sockaddr_in &remote);
|
||||||
|
bool storeStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
||||||
|
|
||||||
UdpLayer *udpLayer;
|
UdpLayer *udpLayer;
|
||||||
|
|
||||||
@ -94,9 +119,16 @@ bool generate_stun_pkt(void *stun_pkt, int *len);
|
|||||||
struct sockaddr_in eaddr; /* external addr */
|
struct sockaddr_in eaddr; /* external addr */
|
||||||
bool eaddrKnown;
|
bool eaddrKnown;
|
||||||
|
|
||||||
std::list<struct sockaddr_in> stunPeers; /* potentials */
|
bool mStunKeepAlive;
|
||||||
|
time_t mStunLastRecv;
|
||||||
|
time_t mStunLastSend;
|
||||||
|
|
||||||
|
std::list<TouStunPeer> mStunList; /* potentials */
|
||||||
|
|
||||||
std::map<struct sockaddr_in, UdpPeer *> streams;
|
std::map<struct sockaddr_in, UdpPeer *> streams;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -115,7 +115,7 @@ bool SetRedirectAndTest(struct UPNPUrls * urls,
|
|||||||
char externalIPAddress[16];
|
char externalIPAddress[16];
|
||||||
char intClient[16];
|
char intClient[16];
|
||||||
char intPort[6];
|
char intPort[6];
|
||||||
char leaseDuration[] = "600";
|
char leaseDuration[] = "600"; /* 10 mins */
|
||||||
int r;
|
int r;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user