Ported branch commits 2980/1: cleaned the code in IP address lists management. Removed some bugs. Changed the strategy a bit: only keep the most recent port for identical ips. Changed the interface of extAddrFinder to make it mroe secure.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2983 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-05-23 22:27:10 +00:00
parent 591a141a18
commit 757aa7a95d
6 changed files with 346 additions and 313 deletions

View File

@ -781,7 +781,11 @@ void p3ConnectMgr::networkConsistencyCheck()
doNetReset = true; doNetReset = true;
} }
connMtx.lock(); /* LOCK MUTEX */ bool haveReliableIP = false ;
{
RsStackMutex stck(connMtx) ;
//storing old flags //storing old flags
oldnetFlagLocalOk = netFlagLocalOk; oldnetFlagLocalOk = netFlagLocalOk;
oldnetFlagUpnpOk = netFlagUpnpOk; oldnetFlagUpnpOk = netFlagUpnpOk;
@ -789,31 +793,45 @@ void p3ConnectMgr::networkConsistencyCheck()
oldnetFlagStunOk = netFlagStunOk; oldnetFlagStunOk = netFlagStunOk;
oldnetFlagExtraAddressCheckOk = netFlagExtraAddressCheckOk; oldnetFlagExtraAddressCheckOk = netFlagExtraAddressCheckOk;
if (!doNetReset) {//set an external address. if ip adresses are different, let's use the stun address, then the extaddrfinder and then the upnp address. if (!doNetReset)
{ // Set an external address. if ip adresses are different, let's use the stun address, then
// the extaddrfinder and then the upnp address.
//
struct sockaddr_in extAddr; struct sockaddr_in extAddr;
if (!ownState.dyndns.empty () && getIPAddressFromString (ownState.dyndns.c_str (), &extAddr.sin_addr)) {
if (!ownState.dyndns.empty () && getIPAddressFromString (ownState.dyndns.c_str (), &extAddr.sin_addr))
{
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getIPAddressFromString for ownState.serveraddr." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getIPAddressFromString for ownState.serveraddr." << std::endl;
#endif #endif
extAddr.sin_port = ownState.currentserveraddr.sin_port; extAddr.sin_port = ownState.currentserveraddr.sin_port;
ownState.currentserveraddr = extAddr; ownState.currentserveraddr = extAddr;
} if (getExtFinderExtAddress(extAddr)) { haveReliableIP = true ;
}
else if (getExtFinderExtAddress(extAddr))
{
netExtFinderAddressCheck(); //so we put the extra address flag ok. netExtFinderAddressCheck(); //so we put the extra address flag ok.
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getExtFinderExtAddress for ownState.serveraddr." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getExtFinderExtAddress for ownState.serveraddr." << std::endl;
#endif #endif
ownState.currentserveraddr = extAddr; ownState.currentserveraddr = extAddr;
} else if (getUpnpExtAddress(extAddr)) { haveReliableIP = true ;
}
else if (getUpnpExtAddress(extAddr))
{
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getUpnpExtAddress for ownState.serveraddr." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getUpnpExtAddress for ownState.serveraddr." << std::endl;
#endif #endif
ownState.currentserveraddr = extAddr; ownState.currentserveraddr = extAddr;
} else { haveReliableIP = true ;
}
else
{
//try to extract ext address from our own ip address list //try to extract ext address from our own ip address list
IpAddressTimed extractedAddress; IpAddressTimed extractedAddress;
if (peerConnectState::extractExtAddress(ownState.getIpAddressList(), extractedAddress)) {
if (peerConnectState::extractExtAddress(ownState.getIpAddressList(), extractedAddress))
ownState.currentserveraddr = extractedAddress.ipAddr; ownState.currentserveraddr = extractedAddress.ipAddr;
}
//check if a peer is connected, if yes don't do a net reset //check if a peer is connected, if yes don't do a net reset
bool is_connected = false; bool is_connected = false;
@ -824,27 +842,29 @@ void p3ConnectMgr::networkConsistencyCheck()
is_connected = it->second.state & RS_PEER_S_CONNECTED; is_connected = it->second.state & RS_PEER_S_CONNECTED;
} }
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
if (is_connected) { if (is_connected)
std::cerr << "p3ConnectMgr::networkConsistencyCheck() not doing a net reset because a peer is connected." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() not doing a net reset because a peer is connected." << std::endl;
} else { else
std::cerr << "p3ConnectMgr::networkConsistencyCheck() no peer is connected." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() no peer is connected." << std::endl;
}
#endif #endif
doNetReset = !is_connected; doNetReset = !is_connected;
} }
} }
connMtx.unlock(); /* UNLOCK MUTEX */ } /* UNLOCK MUTEX */
if (!doNetReset) { if (haveReliableIP)
{
//extAddr found,update ip address list //extAddr found,update ip address list
IpAddressTimed ipAddressTimed; IpAddressTimed ipAddressTimed;
ipAddressTimed.ipAddr = ownState.currentserveraddr; ipAddressTimed.ipAddr = ownState.currentserveraddr;
ipAddressTimed.seenTime = time(NULL); ipAddressTimed.seenTime = time(NULL);
ownState.updateIpAddressList(ipAddressTimed); ownState.updateIpAddressList(ipAddressTimed);
} }
//let's do a net reset //let's do a net reset
if (doNetReset) { if (doNetReset)
{
//don't do a reset it if the network init is not finished //don't do a reset it if the network init is not finished
delta = time(NULL) - mNetInitTS; delta = time(NULL) - mNetInitTS;
if (delta > MAX_NETWORK_INIT) { if (delta > MAX_NETWORK_INIT) {
@ -852,7 +872,9 @@ void p3ConnectMgr::networkConsistencyCheck()
std::cerr << "p3ConnectMgr::networkConsistencyCheck() doing a net reset." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() doing a net reset." << std::endl;
#endif #endif
netReset(); netReset();
} else { }
else
{
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
std::cerr << "p3ConnectMgr::networkConsistencyCheck() reset delayed : p3ConnectMgr time since last reset : " << delta; std::cerr << "p3ConnectMgr::networkConsistencyCheck() reset delayed : p3ConnectMgr time since last reset : " << delta;
std::cerr << ". Cannot reset before : " << MAX_NETWORK_INIT << " sec" << std::endl; std::cerr << ". Cannot reset before : " << MAX_NETWORK_INIT << " sec" << std::endl;
@ -862,7 +884,8 @@ void p3ConnectMgr::networkConsistencyCheck()
} }
void p3ConnectMgr::netExtFinderAddressCheck() void p3ConnectMgr::netExtFinderAddressCheck()
{ struct sockaddr_in tmpip; {
struct sockaddr_in tmpip;
if (getExtFinderExtAddress(tmpip)) { if (getExtFinderExtAddress(tmpip)) {
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
std::cerr << "p3ConnectMgr::netExtraAddressCheck() return true" << std::endl; std::cerr << "p3ConnectMgr::netExtraAddressCheck() return true" << std::endl;
@ -1674,13 +1697,13 @@ bool p3ConnectMgr::connectResult(std::string id, bool success, uint32_t flags, s
remote_peer_address.sin_addr.s_addr != 0 && remote_peer_address.sin_addr.s_addr != 0 &&
!(remote_peer_address.sin_addr.s_addr == ownState.currentlocaladdr.sin_addr.s_addr) && !(remote_peer_address.sin_addr.s_addr == ownState.currentlocaladdr.sin_addr.s_addr) &&
(!isLoopbackNet(&remote_peer_address.sin_addr)) (!isLoopbackNet(&remote_peer_address.sin_addr))
) { )
{
IpAddressTimed ipLocalAddressTimed; IpAddressTimed ipLocalAddressTimed;
ipLocalAddressTimed.ipAddr = remote_peer_address; ipLocalAddressTimed.ipAddr = remote_peer_address;
ipLocalAddressTimed.seenTime = time(NULL); ipLocalAddressTimed.seenTime = time(NULL);
it->second.updateIpAddressList(ipLocalAddressTimed); it->second.updateIpAddressList(ipLocalAddressTimed);
it->second.purgeIpAddressList();
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::connectResult() adding current peer adress in list." << std::endl; std::cerr << "p3ConnectMgr::connectResult() adding current peer adress in list." << std::endl;
it->second.printIpAddressList(); it->second.printIpAddressList();
@ -2673,22 +2696,24 @@ bool p3ConnectMgr::setExtAddress(std::string id, struct sockaddr_in addr)
{ {
if (id == AuthSSL::getAuthSSL()->OwnId()) if (id == AuthSSL::getAuthSSL()->OwnId())
{ {
if (ownState.currentserveraddr.sin_addr.s_addr != addr.sin_addr.s_addr || if (ownState.currentserveraddr.sin_addr.s_addr != addr.sin_addr.s_addr || ownState.currentserveraddr.sin_port != addr.sin_port)
ownState.currentserveraddr.sin_port != addr.sin_port) { {
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
ownState.currentserveraddr = addr; ownState.currentserveraddr = addr;
//check port and address
if (ownState.currentserveraddr.sin_addr.s_addr == 0 || ownState.currentserveraddr.sin_port == 0 || // //check port and address
ownState.currentserveraddr.sin_addr.s_addr == 1|| ownState.currentserveraddr.sin_port == 1 || // if (ownState.currentserveraddr.sin_addr.s_addr == 0 || ownState.currentserveraddr.sin_port == 0 ||
std::string(inet_ntoa(ownState.currentserveraddr.sin_addr)) == "1.1.1.1") { // ownState.currentserveraddr.sin_addr.s_addr == 1|| ownState.currentserveraddr.sin_port == 1 ||
//try to extract ext address from the ip address list // std::string(inet_ntoa(ownState.currentserveraddr.sin_addr)) == "1.1.1.1")
IpAddressTimed extractedAddress; // {
if (peerConnectState::extractExtAddress(ownState.getIpAddressList(), extractedAddress)) { // //try to extract ext address from the ip address list
ownState.currentserveraddr = extractedAddress.ipAddr; // IpAddressTimed extractedAddress;
} else { // if (peerConnectState::extractExtAddress(ownState.getIpAddressList(), extractedAddress)) {
ownState.currentserveraddr = ownState.currentlocaladdr; // ownState.currentserveraddr = extractedAddress.ipAddr;
} // } else {
} // ownState.currentserveraddr = ownState.currentlocaladdr;
// }
// }
} }
return true; return true;
} }
@ -2750,7 +2775,7 @@ bool p3ConnectMgr::setDynDNS(std::string id, std::string dyndns)
return true; return true;
} }
bool p3ConnectMgr::setAddressList(std::string id, std::list<IpAddressTimed> IpAddressTimedList) bool p3ConnectMgr::setAddressList(const std::string& id, const std::list<IpAddressTimed>& IpAddressTimedList)
{ {
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::setAddressList() called for id : " << id << std::endl; std::cerr << "p3ConnectMgr::setAddressList() called for id : " << id << std::endl;
@ -2759,8 +2784,10 @@ bool p3ConnectMgr::setAddressList(std::string id, std::list<IpAddressTimed> I
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
/* check if it is our own ip */ /* check if it is our own ip */
if (id == getOwnId()) { if (id == getOwnId())
{
ownState.updateIpAddressList(IpAddressTimedList); ownState.updateIpAddressList(IpAddressTimedList);
//if we have no ext address from upnp or extAdrFinder, we will use this list for ext ip detection //if we have no ext address from upnp or extAdrFinder, we will use this list for ext ip detection
//useless, already done in network consistency check //useless, already done in network consistency check
// sockaddr_in extAddr; // sockaddr_in extAddr;
@ -2778,6 +2805,7 @@ bool p3ConnectMgr::setAddressList(std::string id, std::list<IpAddressTimed> I
// #endif // #endif
// } // }
// } // }
return true; return true;
} }
@ -2926,8 +2954,8 @@ bool p3ConnectMgr::checkNetAddress()
netFlagLocalOk = true; netFlagLocalOk = true;
IndicateConfigChanged(); IndicateConfigChanged();
} }
} else { }
if (netFlagLocalOk != false) else if (netFlagLocalOk != false)
{ {
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::checkNetAddress() changing netFlagOk to false." << std::endl; std::cerr << "p3ConnectMgr::checkNetAddress() changing netFlagOk to false." << std::endl;
@ -2939,7 +2967,6 @@ bool p3ConnectMgr::checkNetAddress()
netFlagStunOk = false; netFlagStunOk = false;
IndicateConfigChanged(); IndicateConfigChanged();
} }
}
if(isLoopbackNet(&(ownState.currentlocaladdr.sin_addr))) if(isLoopbackNet(&(ownState.currentlocaladdr.sin_addr)))
mNetStatus = RS_NET_LOOPBACK; mNetStatus = RS_NET_LOOPBACK;
@ -2961,12 +2988,12 @@ bool p3ConnectMgr::checkNetAddress()
ownState.currentserveraddr.sin_family = AF_INET; ownState.currentserveraddr.sin_family = AF_INET;
//update ip address list //update ip address list
//
IpAddressTimed ipAddressTimed; IpAddressTimed ipAddressTimed;
ipAddressTimed.ipAddr = ownState.currentlocaladdr; ipAddressTimed.ipAddr = ownState.currentlocaladdr;
ipAddressTimed.seenTime = time(NULL); ipAddressTimed.seenTime = time(NULL);
ownState.updateIpAddressList(ipAddressTimed); ownState.updateIpAddressList(ipAddressTimed);
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
std::cerr << "p3ConnectMgr::checkNetAddress() Final Local Address: " << inet_ntoa(ownState.currentlocaladdr.sin_addr); std::cerr << "p3ConnectMgr::checkNetAddress() Final Local Address: " << inet_ntoa(ownState.currentlocaladdr.sin_addr);
std::cerr << ":" << ntohs(ownState.currentlocaladdr.sin_port) << std::endl; std::cerr << ":" << ntohs(ownState.currentlocaladdr.sin_port) << std::endl;
@ -3200,7 +3227,6 @@ bool p3ConnectMgr::loadList(std::list<RsItem *> load)
std::cerr << "setting allow_tunnel_connection to " << allow_tunnel_connection << std::endl ; std::cerr << "setting allow_tunnel_connection to " << allow_tunnel_connection << std::endl ;
} }
} }
} }
delete (*it); delete (*it);
@ -3519,143 +3545,153 @@ bool p3ConnectMgr::getStunExtAddress(struct sockaddr_in &addr) {
} }
bool p3ConnectMgr::getExtFinderExtAddress(struct sockaddr_in &addr) { bool p3ConnectMgr::getExtFinderExtAddress(struct sockaddr_in &addr)
if ((use_extr_addr_finder && mExtAddrFinder->hasValidIP(&addr))) { {
struct in_addr ad ;
if ((use_extr_addr_finder && mExtAddrFinder->hasValidIP(&ad)))
{
addr.sin_port = ownState.currentlocaladdr.sin_port; addr.sin_port = ownState.currentlocaladdr.sin_port;
addr.sin_addr = ad ;
return true; return true;
} else { }
else
return false; return false;
} }
}
bool peerConnectState::compare_seen_time (IpAddressTimed first, IpAddressTimed second) { //Sort the ip list ordering by seen time bool peerConnectState::is_same_address(const IpAddressTimed& first, const IpAddressTimed& second)
return (first.seenTime < second.seenTime); {
}
bool peerConnectState::is_same_address(IpAddressTimed first, IpAddressTimed second) { //Sort the ip list ordering by seen time
return (first.ipAddr.sin_addr.s_addr == second.ipAddr.sin_addr.s_addr && first.ipAddr.sin_port == second.ipAddr.sin_port); return (first.ipAddr.sin_addr.s_addr == second.ipAddr.sin_addr.s_addr && first.ipAddr.sin_port == second.ipAddr.sin_port);
} }
void peerConnectState::sortIpAddressListBySeenTime() { //Sort the ip list ordering by seen time std::list<IpAddressTimed> peerConnectState::getIpAddressList()
sortIpAddressListBySeenTime(this->ipAddressList); {
}
void peerConnectState::sortIpAddressListBySeenTime(std::list<IpAddressTimed> &ipTimedListInput) { //Sort the ip list ordering by seen time
ipTimedListInput.sort(peerConnectState::compare_seen_time);
ipTimedListInput.reverse();
}
std::list<IpAddressTimed> peerConnectState::getIpAddressList() {
purgeIpAddressList();
return ipAddressList; return ipAddressList;
} }
void peerConnectState::purgeIpAddressList() {//purge old and useless addresses to keep a small list void peerConnectState::updateIpAddressList(const std::list<IpAddressTimed>& ipTimedList) //purge old addresses to keep a small list
std::list<IpAddressTimed>::iterator ipListIt; {
for (ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end());) { std::list<IpAddressTimed>::const_iterator ipListIt;
if (ipListIt->ipAddr.sin_addr.s_addr == 0 || ipListIt->ipAddr.sin_port == 0 ||
ipListIt->ipAddr.sin_addr.s_addr == 1|| ipListIt->ipAddr.sin_port == 1 ||
std::string(inet_ntoa(ipListIt->ipAddr.sin_addr)) == "1.1.1.1") {
ipAddressList.erase(ipListIt++);
} else {
++ipListIt;
}
}
//purge duplicates for (ipListIt = ipTimedList.begin(); ipListIt!=(ipTimedList.end()); ++ipListIt)
for (ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()); ipListIt++) {
std::list<IpAddressTimed>::iterator ipListIt2 = ipListIt;
++ipListIt2;
while (ipListIt2!=(ipAddressList.end())) {
if (is_same_address(*ipListIt2, *ipListIt)) {
ipAddressList.erase(ipListIt2++);
} else {
++ipListIt2;
}
}
}
sortIpAddressListBySeenTime();
//keep only a limited number of addresses
if (ipAddressList.size() > PEER_IP_CONNECT_STATE_MAX_LIST_SIZE) {
ipAddressList.resize(PEER_IP_CONNECT_STATE_MAX_LIST_SIZE);
}
}
void peerConnectState::updateIpAddressList(std::list<IpAddressTimed> ipTimedList) { //purge old addresses to keep a small list
std::list<IpAddressTimed>::iterator ipListIt;
for (ipListIt = ipTimedList.begin(); ipListIt!=(ipTimedList.end()); ipListIt++) {
updateIpAddressList(*ipListIt); updateIpAddressList(*ipListIt);
} }
}
void peerConnectState::updateIpAddressList(IpAddressTimed ipTimed) { //purge old addresses to keep a small list void peerConnectState::updateIpAddressList(const IpAddressTimed& ipTimed)
{
//purge old addresses to keep a small list
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "peerConnectState::updateIpAdressList() ip " << inet_ntoa(ipTimed.ipAddr.sin_addr); std::cerr << "peerConnectState::updateIpAdressList() ip " << inet_ntoa(ipTimed.ipAddr.sin_addr);
std::cerr << ":" << ntohs(ipTimed.ipAddr.sin_port); std::cerr << ":" << ntohs(ipTimed.ipAddr.sin_port);
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
if (ipTimed.ipAddr.sin_addr.s_addr == 0 || ipTimed.ipAddr.sin_port == 0 || // 1 - check for dummy/unusable values.
ipTimed.ipAddr.sin_addr.s_addr == 1|| ipTimed.ipAddr.sin_port == 1 || //
std::string(inet_ntoa(ipTimed.ipAddr.sin_addr)) == "1.1.1.1" || isLoopbackNet(&ipTimed.ipAddr.sin_addr)) { if(isLoopbackNet(&(ipTimed.ipAddr.sin_addr)))
{
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "peerConnectState::updateIpAdressList() ip parameter is 0.0.0.0, 1.1.1.1, or loopback, or port is 0, ignoring." << std::endl; std::cerr << "peerConnectState::updateIpAdressList() ip parameter is loopback: disgarding." << std::endl ;
#endif #endif
return ; return ;
} }
//check if the ip list contains the current remote address of the connected peer if(ipTimed.ipAddr.sin_addr.s_addr == 0 || ipTimed.ipAddr.sin_port == 0)
{
#ifdef CONN_DEBUG
std::cerr << "peerConnectState::updateIpAdressList() ip parameter is 0.0.0.0, or port is 0, ignoring." << std::endl;
#endif
return;
}
// 2 - check if the ip list already contains the current remote address of the connected peer. In such a case,
// we update the time stamp.
//
bool found = false; bool found = false;
std::list<IpAddressTimed>::iterator ipListIt; for (std::list<IpAddressTimed>::iterator ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()) && !found; ++ipListIt)
for (ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()) && !found; ipListIt++) { if((*ipListIt).ipAddr.sin_addr.s_addr == ipTimed.ipAddr.sin_addr.s_addr)
if (is_same_address(*ipListIt, ipTimed)) { {
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "peerConnectState::updateIpAdressList() ip found in the list." << std::endl; std::cerr << "peerConnectState::updateIpAdressList() ip found in the list." << std::endl;
#endif #endif
found = true; found = true;
//update the seen time //update the seen time
if (ipListIt->seenTime < ipTimed.seenTime) { //
ipListIt->seenTime = ipTimed.seenTime; if (ipListIt->seenTime < ipTimed.seenTime)
{
(*ipListIt).seenTime = ipTimed.seenTime;
(*ipListIt).ipAddr.sin_port = ipTimed.ipAddr.sin_port ; // keep the port of the most recent address.
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "peerConnectState::updateIpAdressList() Update seen time to : " << ipTimed.seenTime << std::endl; std::cerr << "peerConnectState::updateIpAdressList() Update seen time to : " << ipTimed.seenTime << std::endl;
#endif #endif
} }
} }
}
if (!found) { // if not found, insert the address at sorted position into the list
//add the current addresses to the ip list //
if (!found)
{
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "peerConnectState::updateIpAdressList() adding to the ip list the current remote addr : " << id << " address : " << inet_ntoa(ipTimed.ipAddr.sin_addr); std::cerr << "peerConnectState::updateIpAdressList() adding to the ip list the current remote addr : " << id << " address : " << inet_ntoa(ipTimed.ipAddr.sin_addr);
std::cerr << ":" << ntohs(ipTimed.ipAddr.sin_port); std::cerr << ":" << ntohs(ipTimed.ipAddr.sin_port);
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
bool placed = false ;
for(std::list<IpAddressTimed>::iterator ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()); ++ipListIt)
if(ipTimed.seenTime > (*ipListIt).seenTime)
{
ipAddressList.insert(ipListIt,ipTimed);
placed=true ;
break;
}
if(!placed)
ipAddressList.push_back(ipTimed); ipAddressList.push_back(ipTimed);
} }
// 5 - cut to the fixed number of retained addresses.
std::list<IpAddressTimed>::iterator it ;
int cnt = 0 ;
for(it = ipAddressList.begin(); it!=(ipAddressList.end()) ;)
if(cnt >= PEER_IP_CONNECT_STATE_MAX_LIST_SIZE)
{
std::list<IpAddressTimed>::iterator tmp=it ;
++tmp ;
ipAddressList.erase(it) ;
it=tmp ;
}
else
++it,++cnt ;
std::cerr << "Adress list updated:" << std::endl ;
printIpAddressList();
} }
void peerConnectState::printIpAddressList() { void peerConnectState::printIpAddressList()
{
std::cerr << "peerConnectState::printIpAdressList() current ip list for the peer : " << id << ", size : " << ipAddressList.size() << ", adresses : " << std::endl; std::cerr << "peerConnectState::printIpAdressList() current ip list for the peer : " << id << ", size : " << ipAddressList.size() << ", adresses : " << std::endl;
for (std::list<IpAddressTimed>::iterator ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()); ipListIt++) {
std::cerr << inet_ntoa(ipListIt->ipAddr.sin_addr) << ":" << ntohs(ipListIt->ipAddr.sin_port) << " seenTime : " << ipListIt->seenTime << std::endl; for (std::list<IpAddressTimed>::iterator ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()); ipListIt++)
} std::cerr << inet_ntoa(ipListIt->ipAddr.sin_addr) << ":"
<< ntohs(ipListIt->ipAddr.sin_port) << " seenTime : "
<< ipListIt->seenTime << std::endl;
} }
bool peerConnectState::extractExtAddress(std::list<IpAddressTimed> IpAddressTimedList, IpAddressTimed &resultAddress) {//extract first address that is not the same as local address // Extract first address that is not the same as local address
sortIpAddressListBySeenTime(IpAddressTimedList); //
bool peerConnectState::extractExtAddress(const std::list<IpAddressTimed>& IpAddressTimedList, IpAddressTimed &resultAddress)
{
//check if the ip list contains the current remote address of the connected peer //check if the ip list contains the current remote address of the connected peer
std::list<IpAddressTimed>::iterator ipListIt; //
for (ipListIt = IpAddressTimedList.begin(); ipListIt!=(IpAddressTimedList.end()); ++ipListIt) { std::list<IpAddressTimed>::const_iterator ipListIt;
for (ipListIt = IpAddressTimedList.begin(); ipListIt!=(IpAddressTimedList.end()); ++ipListIt)
{
//assume address is valid if not private, is not 0 and is not loopback //assume address is valid if not private, is not 0 and is not loopback
//if ((ipListIt->ipAddr.sin_addr.s_addr != 0) //if ((ipListIt->ipAddr.sin_addr.s_addr != 0)
if (ipListIt->ipAddr.sin_addr.s_addr != 0 && ipListIt->ipAddr.sin_port != 0 && //
ipListIt->ipAddr.sin_addr.s_addr != 1 && ipListIt->ipAddr.sin_port != 1 && if(!isPrivateNet(&ipListIt->ipAddr.sin_addr))
std::string(inet_ntoa(ipListIt->ipAddr.sin_addr)) != "1.1.1.1" && {
(!isLoopbackNet(&ipListIt->ipAddr.sin_addr)) &&
(!isPrivateNet(&ipListIt->ipAddr.sin_addr))
) {
resultAddress = *ipListIt; resultAddress = *ipListIt;
return true; return true;
} }

View File

@ -143,17 +143,14 @@ class peerConnectState
//used to store friends ip lists //used to store friends ip lists
void sortIpAddressListBySeenTime(); //Sort the ip list ordering by seen time void sortIpAddressListBySeenTime(); //Sort the ip list ordering by seen time
void purgeIpAddressList(); //purge old addresses to keep a small list
std::list<IpAddressTimed> getIpAddressList(); //return the sorted ant purged list. std::list<IpAddressTimed> getIpAddressList(); //return the sorted ant purged list.
void updateIpAddressList(IpAddressTimed ipTimed); void updateIpAddressList(const IpAddressTimed& ipTimed);
void updateIpAddressList(std::list<IpAddressTimed> ipTimedList); void updateIpAddressList(const std::list<IpAddressTimed>& ipTimedList);
void printIpAddressList(); void printIpAddressList();
static void sortIpAddressListBySeenTime(std::list<IpAddressTimed> &ipTimedList); //Sort the ip list ordering by seen time static bool is_same_address (const IpAddressTimed& first, const IpAddressTimed& second);
static bool compare_seen_time (IpAddressTimed first, IpAddressTimed second);
static bool is_same_address (IpAddressTimed first, IpAddressTimed second);
static void printIpAddressList(std::list<IpAddressTimed> ipTimedList); static void printIpAddressList(std::list<IpAddressTimed> ipTimedList);
static bool extractExtAddress(std::list<IpAddressTimed> ipAddressList, IpAddressTimed &resultAddress); //extract the last seen external address from the list static bool extractExtAddress(const std::list<IpAddressTimed>& ipAddressList, IpAddressTimed &resultAddress); //extract the last seen external address from the list
//used to store current ip (for config and connection management) //used to store current ip (for config and connection management)
struct sockaddr_in currentlocaladdr; /* Mandatory */ struct sockaddr_in currentlocaladdr; /* Mandatory */
@ -230,7 +227,7 @@ void setOwnNetConfig(uint32_t netMode, uint32_t visState);
bool setLocalAddress(std::string id, struct sockaddr_in addr); bool setLocalAddress(std::string id, struct sockaddr_in addr);
bool setExtAddress(std::string id, struct sockaddr_in addr); bool setExtAddress(std::string id, struct sockaddr_in addr);
bool setDynDNS(std::string id, std::string dyndns); bool setDynDNS(std::string id, std::string dyndns);
bool setAddressList(std::string id, std::list<IpAddressTimed> IpAddressTimedList); bool setAddressList(const std::string& id, const std::list<IpAddressTimed>& IpAddressTimedList);
bool setNetworkMode(std::string id, uint32_t netMode); bool setNetworkMode(std::string id, uint32_t netMode);
bool setVisState(std::string id, uint32_t visState); bool setVisState(std::string id, uint32_t visState);

View File

@ -161,7 +161,7 @@ void* doExtAddrSearch(void *p)
sort(res.begin(),res.end()) ; // eliminates outliers. sort(res.begin(),res.end()) ; // eliminates outliers.
if(!inet_aton(res[res.size()/2].c_str(),&(af->_addr->sin_addr))) if(!inet_aton(res[res.size()/2].c_str(),af->_addr))
{ {
std::cerr << "ExtAddrFinder: Could not convert " << res[res.size()/2] << " into an address." << std::endl ; std::cerr << "ExtAddrFinder: Could not convert " << res[res.size()/2] << " into an address." << std::endl ;
{ {
@ -194,7 +194,7 @@ void ExtAddrFinder::start_request()
pthread_detach(tid); /* so memory is reclaimed in linux */ pthread_detach(tid); /* so memory is reclaimed in linux */
} }
bool ExtAddrFinder::hasValidIP(struct sockaddr_in *addr) bool ExtAddrFinder::hasValidIP(struct in_addr *addr)
{ {
#ifdef EXTADDRSEARCH_DEBUG #ifdef EXTADDRSEARCH_DEBUG
std::cerr << "ExtAddrFinder: Getting ip." << std::endl ; std::cerr << "ExtAddrFinder: Getting ip." << std::endl ;
@ -287,7 +287,7 @@ ExtAddrFinder::ExtAddrFinder()
mFoundTS = new time_t; mFoundTS = new time_t;
*mFoundTS = time(NULL) - MAX_IP_STORE; *mFoundTS = time(NULL) - MAX_IP_STORE;
_addr = (sockaddr_in*)malloc(sizeof(sockaddr_in)) ; _addr = (in_addr*)malloc(sizeof(in_addr)) ;
_ip_servers.push_back(std::string( "checkip.dyndns.org" )) ; _ip_servers.push_back(std::string( "checkip.dyndns.org" )) ;
_ip_servers.push_back(std::string( "www.showmyip.com" )) ; _ip_servers.push_back(std::string( "www.showmyip.com" )) ;

View File

@ -12,7 +12,7 @@ class ExtAddrFinder
ExtAddrFinder() ; ExtAddrFinder() ;
~ExtAddrFinder() ; ~ExtAddrFinder() ;
bool hasValidIP(struct sockaddr_in *addr) ; bool hasValidIP(struct in_addr *addr) ;
void getIPServersList(std::list<std::string>& ip_servers) { ip_servers = _ip_servers ; } void getIPServersList(std::list<std::string>& ip_servers) { ip_servers = _ip_servers ; }
void start_request() ; void start_request() ;
@ -24,7 +24,7 @@ class ExtAddrFinder
time_t *mFoundTS; time_t *mFoundTS;
RsMutex _addrMtx ; RsMutex _addrMtx ;
struct sockaddr_in *_addr ; struct in_addr *_addr ;
bool *_found ; bool *_found ;
bool *_searching ; bool *_searching ;
std::list<std::string> _ip_servers ; std::list<std::string> _ip_servers ;

View File

@ -72,7 +72,7 @@ void sockaddr_clear(struct sockaddr_in *addr)
} }
bool isValidNet(struct in_addr *addr) bool isValidNet(const struct in_addr *addr)
{ {
// invalid address. // invalid address.
if((*addr).s_addr == INADDR_NONE) if((*addr).s_addr == INADDR_NONE)
@ -84,13 +84,13 @@ bool isValidNet(struct in_addr *addr)
} }
bool isLoopbackNet(struct in_addr *addr) bool isLoopbackNet(const struct in_addr *addr)
{ {
in_addr_t taddr = ntohl(addr->s_addr); in_addr_t taddr = ntohl(addr->s_addr);
return (taddr == (127 << 24 | 1)); return (taddr == (127 << 24 | 1));
} }
bool isPrivateNet(struct in_addr *addr) bool isPrivateNet(const struct in_addr *addr)
{ {
in_addr_t taddr = ntohl(addr->s_addr); in_addr_t taddr = ntohl(addr->s_addr);
@ -111,7 +111,7 @@ bool isPrivateNet(struct in_addr *addr)
} }
} }
bool isExternalNet(struct in_addr *addr) bool isExternalNet(const struct in_addr *addr)
{ {
if (!isValidNet(addr)) if (!isValidNet(addr))
{ {

View File

@ -65,10 +65,10 @@ uint64_t htonll(uint64_t x);
void sockaddr_clear(struct sockaddr_in *addr); void sockaddr_clear(struct sockaddr_in *addr);
/* determine network type (moved from pqi/pqinetwork.cc) */ /* determine network type (moved from pqi/pqinetwork.cc) */
bool isValidNet(struct in_addr *addr); bool isValidNet(const struct in_addr *addr);
bool isLoopbackNet(struct in_addr *addr); bool isLoopbackNet(const struct in_addr *addr);
bool isPrivateNet(struct in_addr *addr); bool isPrivateNet(const struct in_addr *addr);
bool isExternalNet(struct in_addr *addr); bool isExternalNet(const struct in_addr *addr);
/* convert addresses */ /* convert addresses */
bool getIPAddressFromString (const char *addr_str, struct in_addr *addr); bool getIPAddressFromString (const char *addr_str, struct in_addr *addr);