mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 06:06:10 -04:00
Added Code to detect Symmetric NAT (BAD!) Firewalls.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@361 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
6dd3d30d8e
commit
2dc2954f40
14 changed files with 257 additions and 43 deletions
|
@ -107,12 +107,12 @@ int tou_tick_stunkeepalive()
|
|||
return 1;
|
||||
}
|
||||
|
||||
int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen)
|
||||
int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen, uint8_t *stable)
|
||||
{
|
||||
if (!tou_inited)
|
||||
return -1;
|
||||
|
||||
if (udps->externalAddr(*(struct sockaddr_in *) ext_addr))
|
||||
if (udps->externalAddr(*(struct sockaddr_in *) ext_addr, *stable))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ extern "C" {
|
|||
*/
|
||||
|
||||
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, uint8_t *stable);
|
||||
int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char *id);
|
||||
int tou_stunkeepalive(int required);
|
||||
int tou_tick_stunkeepalive();
|
||||
|
|
|
@ -39,7 +39,7 @@ static const int STUN_TTL = 64;
|
|||
#define DEBUG_UDP_SORTER 1
|
||||
|
||||
UdpSorter::UdpSorter(struct sockaddr_in &local)
|
||||
:udpLayer(NULL), laddr(local), eaddrKnown(false),
|
||||
:udpLayer(NULL), laddr(local), eaddrKnown(false), eaddrStable(false),
|
||||
mStunKeepAlive(false), mStunLastRecv(0), mStunLastSend(0)
|
||||
|
||||
|
||||
|
@ -234,10 +234,7 @@ bool UdpSorter::locked_handleStunPkt(void *data, int size, struct sockaddr_in &f
|
|||
std::cerr << inet_ntoa(eAddr.sin_addr) << ":" << ntohs(eAddr.sin_port);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
eaddrKnown = true;
|
||||
eaddr = eAddr;
|
||||
|
||||
locked_recvdStun(from);
|
||||
locked_recvdStun(from, eAddr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -251,11 +248,17 @@ bool UdpSorter::locked_handleStunPkt(void *data, int size, struct sockaddr_in &f
|
|||
}
|
||||
|
||||
|
||||
bool UdpSorter::externalAddr(struct sockaddr_in &external)
|
||||
bool UdpSorter::externalAddr(struct sockaddr_in &external, uint8_t &stable)
|
||||
{
|
||||
if (eaddrKnown)
|
||||
{
|
||||
external = eaddr;
|
||||
|
||||
if (eaddrStable)
|
||||
stable = 1;
|
||||
else
|
||||
stable = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -612,15 +615,21 @@ bool UdpSorter::checkStunKeepAlive()
|
|||
}
|
||||
|
||||
|
||||
bool UdpSorter::locked_recvdStun(const struct sockaddr_in &remote)
|
||||
bool UdpSorter::locked_recvdStun(const struct sockaddr_in &remote, const struct sockaddr_in &extaddr)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::recvdStun()";
|
||||
std::cerr << std::endl;
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::locked_recvdStun() from:";
|
||||
out << inet_ntoa(remote.sin_addr) << ":" << ntohs(remote.sin_port);
|
||||
out << " claiming ExtAddr is:";
|
||||
out << inet_ntoa(extaddr.sin_addr) << ":" << ntohs(extaddr.sin_port);
|
||||
|
||||
std::cerr << out.str() << std::endl;
|
||||
#endif
|
||||
|
||||
locked_printStunList();
|
||||
|
||||
bool found = true;
|
||||
std::list<TouStunPeer>::iterator it;
|
||||
for(it = mStunList.begin(); it != mStunList.end(); it++)
|
||||
{
|
||||
|
@ -628,13 +637,85 @@ bool UdpSorter::locked_recvdStun(const struct sockaddr_in &remote)
|
|||
(remote.sin_port == it->remote.sin_port))
|
||||
{
|
||||
it->failCount = 0;
|
||||
return true;
|
||||
it->eaddr = extaddr;
|
||||
it->response = true;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!eaddrKnown)
|
||||
{
|
||||
locked_checkExternalAddress();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool UdpSorter::locked_checkExternalAddress()
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::locked_checkExternalAddress()";
|
||||
std::cerr << out.str() << std::endl;
|
||||
#endif
|
||||
|
||||
bool found1 = false;
|
||||
bool found2 = false;
|
||||
|
||||
std::list<TouStunPeer>::iterator it;
|
||||
std::list<TouStunPeer>::iterator p1;
|
||||
std::list<TouStunPeer>::iterator p2;
|
||||
for(it = mStunList.begin(); it != mStunList.end(); it++)
|
||||
{
|
||||
if (it->response)
|
||||
{
|
||||
if (!found1)
|
||||
{
|
||||
p1 = it;
|
||||
found1 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
p2 = it;
|
||||
found2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found1 && found2)
|
||||
{
|
||||
if ((p1->eaddr.sin_addr.s_addr == p2->eaddr.sin_addr.s_addr) &&
|
||||
(p1->eaddr.sin_port == p2->eaddr.sin_port))
|
||||
{
|
||||
eaddrStable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
eaddrStable = false;
|
||||
}
|
||||
eaddrKnown = true;
|
||||
eaddr = p1->eaddr;
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::locked_checkExternalAddress() Found State:";
|
||||
if (eaddrStable)
|
||||
std::cerr << " Stable NAT translation (GOOD!) ";
|
||||
else
|
||||
std::cerr << " unStable (symmetric NAT translation (BAD!) ";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool UdpSorter::locked_printStunList()
|
||||
{
|
||||
std::ostringstream out;
|
||||
|
|
|
@ -49,13 +49,14 @@ class TouStunPeer
|
|||
{
|
||||
public:
|
||||
TouStunPeer()
|
||||
:lastsend(0), failCount(0) { return; }
|
||||
:response(false), 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; }
|
||||
:id(id_in), remote(addr), response(false), lastsend(0), failCount(0) { return; }
|
||||
|
||||
std::string id;
|
||||
struct sockaddr_in remote;
|
||||
struct sockaddr_in remote, eaddr;
|
||||
bool response;
|
||||
time_t lastsend;
|
||||
uint32_t failCount;
|
||||
};
|
||||
|
@ -75,7 +76,7 @@ bool setStunKeepAlive(uint32_t required);
|
|||
bool addStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
||||
bool checkStunKeepAlive();
|
||||
|
||||
bool externalAddr(struct sockaddr_in &remote);
|
||||
bool externalAddr(struct sockaddr_in &remote, uint8_t &stable);
|
||||
|
||||
/* Packet IO */
|
||||
/* pass-through send packets */
|
||||
|
@ -108,7 +109,9 @@ bool generate_stun_pkt(void *stun_pkt, int *len);
|
|||
|
||||
/* stun keepAlive */
|
||||
bool locked_printStunList();
|
||||
bool locked_recvdStun(const struct sockaddr_in &remote);
|
||||
bool locked_recvdStun(const struct sockaddr_in &remote, const struct sockaddr_in &extaddr);
|
||||
bool locked_checkExternalAddress();
|
||||
|
||||
bool storeStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
||||
|
||||
UdpLayer *udpLayer;
|
||||
|
@ -116,8 +119,10 @@ bool storeStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
|||
RsMutex sortMtx; /* for all class data (below) */
|
||||
|
||||
struct sockaddr_in laddr; /* local addr */
|
||||
|
||||
struct sockaddr_in eaddr; /* external addr */
|
||||
bool eaddrKnown;
|
||||
bool eaddrStable; /* if true then usable. if false -> Symmettric NAT */
|
||||
|
||||
bool mStunKeepAlive;
|
||||
time_t mStunLastRecv;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue