From 757aa7a95dd2bb82b96951c59d8db3e7c0a6d8e1 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 23 May 2010 22:27:10 +0000 Subject: [PATCH] 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 --- libretroshare/src/pqi/p3connmgr.cc | 616 +++++++++++--------- libretroshare/src/pqi/p3connmgr.h | 13 +- libretroshare/src/tcponudp/extaddrfinder.cc | 10 +- libretroshare/src/tcponudp/extaddrfinder.h | 4 +- libretroshare/src/util/rsnet.cc | 8 +- libretroshare/src/util/rsnet.h | 8 +- 6 files changed, 346 insertions(+), 313 deletions(-) diff --git a/libretroshare/src/pqi/p3connmgr.cc b/libretroshare/src/pqi/p3connmgr.cc index 2b8aeff9a..360bd5082 100644 --- a/libretroshare/src/pqi/p3connmgr.cc +++ b/libretroshare/src/pqi/p3connmgr.cc @@ -749,120 +749,143 @@ void p3ConnectMgr::netUpnpCheck() void p3ConnectMgr::networkConsistencyCheck() { time_t delta; - #ifdef CONN_DEBUG_TICK +#ifdef CONN_DEBUG_TICK delta = time(NULL) - mNetInitTS; - std::cerr << "p3ConnectMgr::networkConsistencyCheck() time since last reset : " << delta << std::endl; - #endif + std::cerr << "p3ConnectMgr::networkConsistencyCheck() time since last reset : " << delta << std::endl; +#endif - bool doNetReset = false; + bool doNetReset = false; //if one of the flag is degrated from true to false during last tick, let's do a reset - #ifdef CONN_DEBUG_TICK - std::cerr << "p3ConnectMgr::networkConsistencyCheck() net flags : " << std::endl; - std::cerr << " oldnetFlagLocalOk : " << oldnetFlagLocalOk << ". netFlagLocalOk : " << netFlagLocalOk << "." << std::endl; - std::cerr << " oldnetFlagUpnpOk : " << oldnetFlagUpnpOk << ". netFlagUpnpOk : " << netFlagUpnpOk << "." << std::endl; - std::cerr << " oldnetFlagDhtOk : " << oldnetFlagDhtOk << ". netFlagDhtOk : " << netFlagDhtOk << "." << std::endl; - std::cerr << " oldnetFlagStunOk : " << oldnetFlagStunOk << ". netFlagStunOk : " << netFlagStunOk << "." << std::endl; - std::cerr << " oldnetFlagExtraAddressCheckOk : " << oldnetFlagExtraAddressCheckOk << ". netFlagExtraAddressCheckOk : " << netFlagExtraAddressCheckOk << "." << std::endl; - #endif - if ( !netFlagLocalOk - || (!netFlagUpnpOk && oldnetFlagUpnpOk) - || (!netFlagDhtOk && oldnetFlagDhtOk) - || (!netFlagStunOk && oldnetFlagStunOk) - || (!netFlagExtraAddressCheckOk && oldnetFlagExtraAddressCheckOk) - ) { - #ifdef CONN_DEBUG_TICK - std::cerr << "p3ConnectMgr::networkConsistencyCheck() A net flag went down." << std::endl; - #endif +#ifdef CONN_DEBUG_TICK + std::cerr << "p3ConnectMgr::networkConsistencyCheck() net flags : " << std::endl; + std::cerr << " oldnetFlagLocalOk : " << oldnetFlagLocalOk << ". netFlagLocalOk : " << netFlagLocalOk << "." << std::endl; + std::cerr << " oldnetFlagUpnpOk : " << oldnetFlagUpnpOk << ". netFlagUpnpOk : " << netFlagUpnpOk << "." << std::endl; + std::cerr << " oldnetFlagDhtOk : " << oldnetFlagDhtOk << ". netFlagDhtOk : " << netFlagDhtOk << "." << std::endl; + std::cerr << " oldnetFlagStunOk : " << oldnetFlagStunOk << ". netFlagStunOk : " << netFlagStunOk << "." << std::endl; + std::cerr << " oldnetFlagExtraAddressCheckOk : " << oldnetFlagExtraAddressCheckOk << ". netFlagExtraAddressCheckOk : " << netFlagExtraAddressCheckOk << "." << std::endl; +#endif + if ( !netFlagLocalOk + || (!netFlagUpnpOk && oldnetFlagUpnpOk) + || (!netFlagDhtOk && oldnetFlagDhtOk) + || (!netFlagStunOk && oldnetFlagStunOk) + || (!netFlagExtraAddressCheckOk && oldnetFlagExtraAddressCheckOk) + ) { +#ifdef CONN_DEBUG_TICK + std::cerr << "p3ConnectMgr::networkConsistencyCheck() A net flag went down." << std::endl; +#endif - //don't do a normal shutdown for upnp as it might hang up. - //With a 0 port it will just dereference and not attemps to communicate for shutting down upnp session. - netAssistFirewallPorts(0, 0); + //don't do a normal shutdown for upnp as it might hang up. + //With a 0 port it will just dereference and not attemps to communicate for shutting down upnp session. + netAssistFirewallPorts(0, 0); - doNetReset = true; + doNetReset = true; } - connMtx.lock(); /* LOCK MUTEX */ - //storing old flags - oldnetFlagLocalOk = netFlagLocalOk; - oldnetFlagUpnpOk = netFlagUpnpOk; - oldnetFlagDhtOk = netFlagDhtOk; - oldnetFlagStunOk = netFlagStunOk; - oldnetFlagExtraAddressCheckOk = netFlagExtraAddressCheckOk; + bool haveReliableIP = false ; - 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; - if (!ownState.dyndns.empty () && getIPAddressFromString (ownState.dyndns.c_str (), &extAddr.sin_addr)) { - #ifdef CONN_DEBUG_TICK - std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getIPAddressFromString for ownState.serveraddr." << std::endl; - #endif - extAddr.sin_port = ownState.currentserveraddr.sin_port; - ownState.currentserveraddr = extAddr; - } if (getExtFinderExtAddress(extAddr)) { - netExtFinderAddressCheck(); //so we put the extra address flag ok. - #ifdef CONN_DEBUG_TICK - std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getExtFinderExtAddress for ownState.serveraddr." << std::endl; - #endif - ownState.currentserveraddr = extAddr; - } else if (getUpnpExtAddress(extAddr)) { - #ifdef CONN_DEBUG_TICK - std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getUpnpExtAddress for ownState.serveraddr." << std::endl; - #endif - ownState.currentserveraddr = extAddr; - } else { - //try to extract ext address from our own ip address list - IpAddressTimed extractedAddress; - if (peerConnectState::extractExtAddress(ownState.getIpAddressList(), extractedAddress)) { - ownState.currentserveraddr = extractedAddress.ipAddr; - } + { + RsStackMutex stck(connMtx) ; - //check if a peer is connected, if yes don't do a net reset - bool is_connected = false; - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end() && !is_connected; it++) - { - /* get last contact detail */ - is_connected = it->second.state & RS_PEER_S_CONNECTED; - } - #ifdef CONN_DEBUG_TICK - if (is_connected) { - std::cerr << "p3ConnectMgr::networkConsistencyCheck() not doing a net reset because a peer is connected." << std::endl; - } else { - std::cerr << "p3ConnectMgr::networkConsistencyCheck() no peer is connected." << std::endl; - } - #endif - doNetReset = !is_connected; - } - } - connMtx.unlock(); /* UNLOCK MUTEX */ + //storing old flags + oldnetFlagLocalOk = netFlagLocalOk; + oldnetFlagUpnpOk = netFlagUpnpOk; + oldnetFlagDhtOk = netFlagDhtOk; + oldnetFlagStunOk = netFlagStunOk; + oldnetFlagExtraAddressCheckOk = netFlagExtraAddressCheckOk; - if (!doNetReset) { - //extAddr found,update ip address list - IpAddressTimed ipAddressTimed; - ipAddressTimed.ipAddr = ownState.currentserveraddr; - ipAddressTimed.seenTime = time(NULL); - ownState.updateIpAddressList(ipAddressTimed); - } + 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; - //let's do a net reset - if (doNetReset) { + if (!ownState.dyndns.empty () && getIPAddressFromString (ownState.dyndns.c_str (), &extAddr.sin_addr)) + { +#ifdef CONN_DEBUG_TICK + std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getIPAddressFromString for ownState.serveraddr." << std::endl; +#endif + extAddr.sin_port = ownState.currentserveraddr.sin_port; + ownState.currentserveraddr = extAddr; + haveReliableIP = true ; + } + else if (getExtFinderExtAddress(extAddr)) + { + netExtFinderAddressCheck(); //so we put the extra address flag ok. +#ifdef CONN_DEBUG_TICK + std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getExtFinderExtAddress for ownState.serveraddr." << std::endl; +#endif + ownState.currentserveraddr = extAddr; + haveReliableIP = true ; + } + else if (getUpnpExtAddress(extAddr)) + { +#ifdef CONN_DEBUG_TICK + std::cerr << "p3ConnectMgr::networkConsistencyCheck() using getUpnpExtAddress for ownState.serveraddr." << std::endl; +#endif + ownState.currentserveraddr = extAddr; + haveReliableIP = true ; + } + else + { + //try to extract ext address from our own ip address list + IpAddressTimed extractedAddress; + + if (peerConnectState::extractExtAddress(ownState.getIpAddressList(), extractedAddress)) + ownState.currentserveraddr = extractedAddress.ipAddr; + + //check if a peer is connected, if yes don't do a net reset + bool is_connected = false; + std::map::iterator it; + for(it = mFriendList.begin(); it != mFriendList.end() && !is_connected; it++) + { + /* get last contact detail */ + is_connected = it->second.state & RS_PEER_S_CONNECTED; + } +#ifdef CONN_DEBUG_TICK + if (is_connected) + std::cerr << "p3ConnectMgr::networkConsistencyCheck() not doing a net reset because a peer is connected." << std::endl; + else + std::cerr << "p3ConnectMgr::networkConsistencyCheck() no peer is connected." << std::endl; +#endif + doNetReset = !is_connected; + } + } + } /* UNLOCK MUTEX */ + + if (haveReliableIP) + { + //extAddr found,update ip address list + IpAddressTimed ipAddressTimed; + ipAddressTimed.ipAddr = ownState.currentserveraddr; + ipAddressTimed.seenTime = time(NULL); + + ownState.updateIpAddressList(ipAddressTimed); + } + + //let's do a net reset + if (doNetReset) + { //don't do a reset it if the network init is not finished delta = time(NULL) - mNetInitTS; if (delta > MAX_NETWORK_INIT) { - #ifdef CONN_DEBUG_TICK - std::cerr << "p3ConnectMgr::networkConsistencyCheck() doing a net reset." << std::endl; - #endif - netReset(); - } else { - #ifdef CONN_DEBUG_TICK +#ifdef CONN_DEBUG_TICK + std::cerr << "p3ConnectMgr::networkConsistencyCheck() doing a net reset." << std::endl; +#endif + netReset(); + } + else + { +#ifdef CONN_DEBUG_TICK std::cerr << "p3ConnectMgr::networkConsistencyCheck() reset delayed : p3ConnectMgr time since last reset : " << delta; std::cerr << ". Cannot reset before : " << MAX_NETWORK_INIT << " sec" << std::endl; - #endif +#endif } - } + } } void p3ConnectMgr::netExtFinderAddressCheck() -{ struct sockaddr_in tmpip; +{ + struct sockaddr_in tmpip; if (getExtFinderExtAddress(tmpip)) { #ifdef CONN_DEBUG_TICK 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 == ownState.currentlocaladdr.sin_addr.s_addr) && (!isLoopbackNet(&remote_peer_address.sin_addr)) - ) { + ) + { IpAddressTimed ipLocalAddressTimed; ipLocalAddressTimed.ipAddr = remote_peer_address; ipLocalAddressTimed.seenTime = time(NULL); it->second.updateIpAddressList(ipLocalAddressTimed); - it->second.purgeIpAddressList(); #ifdef CONN_DEBUG std::cerr << "p3ConnectMgr::connectResult() adding current peer adress in list." << std::endl; it->second.printIpAddressList(); @@ -2671,38 +2694,40 @@ bool p3ConnectMgr::setLocalAddress(std::string id, struct sockaddr_in addr) 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 || - ownState.currentserveraddr.sin_port != addr.sin_port) { - RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ - ownState.currentserveraddr = addr; - //check port and address - if (ownState.currentserveraddr.sin_addr.s_addr == 0 || ownState.currentserveraddr.sin_port == 0 || - ownState.currentserveraddr.sin_addr.s_addr == 1|| ownState.currentserveraddr.sin_port == 1 || - std::string(inet_ntoa(ownState.currentserveraddr.sin_addr)) == "1.1.1.1") { - //try to extract ext address from the ip address list - IpAddressTimed extractedAddress; - if (peerConnectState::extractExtAddress(ownState.getIpAddressList(), extractedAddress)) { - ownState.currentserveraddr = extractedAddress.ipAddr; - } else { - ownState.currentserveraddr = ownState.currentlocaladdr; - } - } - } - return true; - } + if (ownState.currentserveraddr.sin_addr.s_addr != addr.sin_addr.s_addr || ownState.currentserveraddr.sin_port != addr.sin_port) + { + RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ + ownState.currentserveraddr = addr; - RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ +// //check port and address +// if (ownState.currentserveraddr.sin_addr.s_addr == 0 || ownState.currentserveraddr.sin_port == 0 || +// ownState.currentserveraddr.sin_addr.s_addr == 1|| ownState.currentserveraddr.sin_port == 1 || +// std::string(inet_ntoa(ownState.currentserveraddr.sin_addr)) == "1.1.1.1") +// { +// //try to extract ext address from the ip address list +// IpAddressTimed extractedAddress; +// if (peerConnectState::extractExtAddress(ownState.getIpAddressList(), extractedAddress)) { +// ownState.currentserveraddr = extractedAddress.ipAddr; +// } else { +// ownState.currentserveraddr = ownState.currentlocaladdr; +// } +// } + } + return true; + } + + RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ /* check if it is a friend */ - std::map::iterator it; + std::map::iterator it; if (mFriendList.end() == (it = mFriendList.find(id))) { if (mOthersList.end() == (it = mOthersList.find(id))) { - #ifdef CONN_DEBUG - std::cerr << "p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list id: " << id << std::endl; - #endif +#ifdef CONN_DEBUG + std::cerr << "p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list id: " << id << std::endl; +#endif return false; } } @@ -2750,45 +2775,48 @@ bool p3ConnectMgr::setDynDNS(std::string id, std::string dyndns) return true; } -bool p3ConnectMgr::setAddressList(std::string id, std::list IpAddressTimedList) +bool p3ConnectMgr::setAddressList(const std::string& id, const std::list& IpAddressTimedList) { - #ifdef CONN_DEBUG - std::cerr << "p3ConnectMgr::setAddressList() called for id : " << id << std::endl; - #endif +#ifdef CONN_DEBUG + std::cerr << "p3ConnectMgr::setAddressList() called for id : " << id << std::endl; +#endif - RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ + RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ - /* check if it is our own ip */ - if (id == getOwnId()) { - ownState.updateIpAddressList(IpAddressTimedList); - //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 -// sockaddr_in extAddr; -// if (!getExtFinderExtAddress(extAddr) && !getUpnpExtAddress(extAddr)) { //TODO fix it -// IpAddressTimed extractedAddress; -// if (peerConnectState::extractExtAddress(IpAddressTimedList, extractedAddress)) { -// #ifdef CONN_DEBUG -// std::cerr << "p3ConnectMgr::setAddressList() using ip address list to set external addres." << std::endl; -// #endif -// ownState.currentserveraddr.sin_addr = extractedAddress.ipAddr.sin_addr; -// IndicateConfigChanged(); -// } else { -// #ifdef CONN_DEBUG -// std::cerr << "p3ConnectMgr::setAddressList() no valuable ext adress found." << std::endl; -// #endif -// } -// } - return true; - } + /* check if it is our own ip */ + if (id == getOwnId()) + { + ownState.updateIpAddressList(IpAddressTimedList); - /* check if it is a friend */ + //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 + // sockaddr_in extAddr; + // if (!getExtFinderExtAddress(extAddr) && !getUpnpExtAddress(extAddr)) { //TODO fix it + // IpAddressTimed extractedAddress; + // if (peerConnectState::extractExtAddress(IpAddressTimedList, extractedAddress)) { + // #ifdef CONN_DEBUG + // std::cerr << "p3ConnectMgr::setAddressList() using ip address list to set external addres." << std::endl; + // #endif + // ownState.currentserveraddr.sin_addr = extractedAddress.ipAddr.sin_addr; + // IndicateConfigChanged(); + // } else { + // #ifdef CONN_DEBUG + // std::cerr << "p3ConnectMgr::setAddressList() no valuable ext adress found." << std::endl; + // #endif + // } + // } + + return true; + } + + /* check if it is a friend */ std::map::iterator it; if (mFriendList.end() == (it = mFriendList.find(id))) { - #ifdef CONN_DEBUG - std::cerr << "p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list. id: " << id << std::endl; - #endif - return false; +#ifdef CONN_DEBUG + std::cerr << "p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list. id: " << id << std::endl; +#endif + return false; } /* "it" points to peer */ @@ -2916,7 +2944,7 @@ bool p3ConnectMgr::checkNetAddress() // ownState.currentlocaladdr.sin_addr = getPreferredInterface() ; - if(ownState.currentlocaladdr.sin_addr.s_addr != 0 && !isLoopbackNet(&(ownState.currentlocaladdr.sin_addr))) + if(ownState.currentlocaladdr.sin_addr.s_addr != 0 && !isLoopbackNet(&(ownState.currentlocaladdr.sin_addr))) { if (netFlagLocalOk != true) { @@ -2926,20 +2954,19 @@ bool p3ConnectMgr::checkNetAddress() netFlagLocalOk = true; IndicateConfigChanged(); } - } else { - if (netFlagLocalOk != false) - { + } + else if (netFlagLocalOk != false) + { #ifdef CONN_DEBUG - std::cerr << "p3ConnectMgr::checkNetAddress() changing netFlagOk to false." << std::endl; + std::cerr << "p3ConnectMgr::checkNetAddress() changing netFlagOk to false." << std::endl; #endif - netFlagLocalOk = false; - netFlagExtraAddressCheckOk = false; - netFlagUpnpOk = false; - netFlagDhtOk = false; - netFlagStunOk = false; - IndicateConfigChanged(); - } - } + netFlagLocalOk = false; + netFlagExtraAddressCheckOk = false; + netFlagUpnpOk = false; + netFlagDhtOk = false; + netFlagStunOk = false; + IndicateConfigChanged(); + } if(isLoopbackNet(&(ownState.currentlocaladdr.sin_addr))) mNetStatus = RS_NET_LOOPBACK; @@ -2961,12 +2988,12 @@ bool p3ConnectMgr::checkNetAddress() ownState.currentserveraddr.sin_family = AF_INET; //update ip address list + // IpAddressTimed ipAddressTimed; ipAddressTimed.ipAddr = ownState.currentlocaladdr; ipAddressTimed.seenTime = time(NULL); ownState.updateIpAddressList(ipAddressTimed); - #ifdef CONN_DEBUG_TICK std::cerr << "p3ConnectMgr::checkNetAddress() Final Local Address: " << inet_ntoa(ownState.currentlocaladdr.sin_addr); std::cerr << ":" << ntohs(ownState.currentlocaladdr.sin_port) << std::endl; @@ -3190,17 +3217,16 @@ bool p3ConnectMgr::loadList(std::list load) vitem->print(std::cerr, 10); std::cerr << std::endl; #endif - std::list::iterator kit; - for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); kit++) { - if(kit->key == "USE_EXTR_IP_FINDER") { - use_extr_addr_finder = (kit->value == "TRUE"); - std::cerr << "setting use_extr_addr_finder to " << use_extr_addr_finder << std::endl ; - } else if (kit->key == "ALLOW_TUNNEL_CONNECTION") { - allow_tunnel_connection = (kit->value == "TRUE"); - std::cerr << "setting allow_tunnel_connection to " << allow_tunnel_connection << std::endl ; - } - } - + std::list::iterator kit; + for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); kit++) { + if(kit->key == "USE_EXTR_IP_FINDER") { + use_extr_addr_finder = (kit->value == "TRUE"); + std::cerr << "setting use_extr_addr_finder to " << use_extr_addr_finder << std::endl ; + } else if (kit->key == "ALLOW_TUNNEL_CONNECTION") { + allow_tunnel_connection = (kit->value == "TRUE"); + std::cerr << "setting allow_tunnel_connection to " << allow_tunnel_connection << std::endl ; + } + } } delete (*it); @@ -3519,148 +3545,158 @@ bool p3ConnectMgr::getStunExtAddress(struct sockaddr_in &addr) { } -bool p3ConnectMgr::getExtFinderExtAddress(struct sockaddr_in &addr) { - if ((use_extr_addr_finder && mExtAddrFinder->hasValidIP(&addr))) { - addr.sin_port = ownState.currentlocaladdr.sin_port; - return true; - } else { - return false; - } +bool p3ConnectMgr::getExtFinderExtAddress(struct sockaddr_in &addr) +{ + struct in_addr ad ; + + if ((use_extr_addr_finder && mExtAddrFinder->hasValidIP(&ad))) + { + addr.sin_port = ownState.currentlocaladdr.sin_port; + addr.sin_addr = ad ; + return true; + } + else + return false; } -bool peerConnectState::compare_seen_time (IpAddressTimed first, IpAddressTimed second) { //Sort the ip list ordering by seen time - return (first.seenTime < second.seenTime); -} - -bool peerConnectState::is_same_address(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.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 - sortIpAddressListBySeenTime(this->ipAddressList); -} - -void peerConnectState::sortIpAddressListBySeenTime(std::list &ipTimedListInput) { //Sort the ip list ordering by seen time - ipTimedListInput.sort(peerConnectState::compare_seen_time); - ipTimedListInput.reverse(); -} - - -std::list peerConnectState::getIpAddressList() { - purgeIpAddressList(); +std::list peerConnectState::getIpAddressList() +{ return ipAddressList; } -void peerConnectState::purgeIpAddressList() {//purge old and useless addresses to keep a small list - std::list::iterator ipListIt; - for (ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end());) { - 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; - } - } +void peerConnectState::updateIpAddressList(const std::list& ipTimedList) //purge old addresses to keep a small list +{ + std::list::const_iterator ipListIt; - //purge duplicates - for (ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()); ipListIt++) { - std::list::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 ipTimedList) { //purge old addresses to keep a small list - std::list::iterator ipListIt; - for (ipListIt = ipTimedList.begin(); ipListIt!=(ipTimedList.end()); ipListIt++) { + for (ipListIt = ipTimedList.begin(); ipListIt!=(ipTimedList.end()); ++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 - std::cerr << "peerConnectState::updateIpAdressList() ip " << inet_ntoa(ipTimed.ipAddr.sin_addr); - std::cerr << ":" << ntohs(ipTimed.ipAddr.sin_port); - std::cerr << std::endl; + std::cerr << "peerConnectState::updateIpAdressList() ip " << inet_ntoa(ipTimed.ipAddr.sin_addr); + std::cerr << ":" << ntohs(ipTimed.ipAddr.sin_port); + std::cerr << std::endl; #endif - if (ipTimed.ipAddr.sin_addr.s_addr == 0 || ipTimed.ipAddr.sin_port == 0 || - 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)) { + // 1 - check for dummy/unusable values. + // + if(isLoopbackNet(&(ipTimed.ipAddr.sin_addr))) + { #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 - return; - } + return ; + } - //check if the ip list contains the current remote address of the connected peer - bool found = false; - std::list::iterator ipListIt; - for (ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()) && !found; ipListIt++) { - if (is_same_address(*ipListIt, ipTimed)) { + 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; + for (std::list::iterator ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()) && !found; ++ipListIt) + if((*ipListIt).ipAddr.sin_addr.s_addr == ipTimed.ipAddr.sin_addr.s_addr) + { #ifdef CONN_DEBUG std::cerr << "peerConnectState::updateIpAdressList() ip found in the list." << std::endl; #endif found = true; //update the seen time - if (ipListIt->seenTime < ipTimed.seenTime) { - ipListIt->seenTime = ipTimed.seenTime; - #ifdef CONN_DEBUG - std::cerr << "peerConnectState::updateIpAdressList() Update seen time to : " << ipTimed.seenTime << std::endl; - #endif - } - } - } - - if (!found) { - //add the current addresses to the ip list + // + 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 - 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 << std::endl; + std::cerr << "peerConnectState::updateIpAdressList() Update seen time to : " << ipTimed.seenTime << std::endl; #endif - ipAddressList.push_back(ipTimed); + } } -} + // if not found, insert the address at sorted position into the list + // + if (!found) + { +#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 << ":" << ntohs(ipTimed.ipAddr.sin_port); + std::cerr << std::endl; +#endif + bool placed = false ; -void peerConnectState::printIpAddressList() { - std::cerr << "peerConnectState::printIpAdressList() current ip list for the peer : " << id << ", size : " << ipAddressList.size() << ", adresses : " << std::endl; - for (std::list::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::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); + } + + // 5 - cut to the fixed number of retained addresses. + + std::list::iterator it ; + int cnt = 0 ; + for(it = ipAddressList.begin(); it!=(ipAddressList.end()) ;) + if(cnt >= PEER_IP_CONNECT_STATE_MAX_LIST_SIZE) + { + std::list::iterator tmp=it ; + ++tmp ; + ipAddressList.erase(it) ; + it=tmp ; } + else + ++it,++cnt ; + + std::cerr << "Adress list updated:" << std::endl ; + printIpAddressList(); } -bool peerConnectState::extractExtAddress(std::list IpAddressTimedList, IpAddressTimed &resultAddress) {//extract first address that is not the same as local address - sortIpAddressListBySeenTime(IpAddressTimedList); - //check if the ip list contains the current remote address of the connected peer - std::list::iterator ipListIt; - for (ipListIt = IpAddressTimedList.begin(); ipListIt!=(IpAddressTimedList.end()); ++ipListIt) { - //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 && 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" && - (!isLoopbackNet(&ipListIt->ipAddr.sin_addr)) && - (!isPrivateNet(&ipListIt->ipAddr.sin_addr)) - ) { - resultAddress = *ipListIt; - return true; - } - } - return false; +void peerConnectState::printIpAddressList() +{ + std::cerr << "peerConnectState::printIpAdressList() current ip list for the peer : " << id << ", size : " << ipAddressList.size() << ", adresses : " << std::endl; + + for (std::list::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; + +} + +// Extract first address that is not the same as local address +// +bool peerConnectState::extractExtAddress(const std::list& IpAddressTimedList, IpAddressTimed &resultAddress) +{ + //check if the ip list contains the current remote address of the connected peer + // + std::list::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 + //if ((ipListIt->ipAddr.sin_addr.s_addr != 0) + // + if(!isPrivateNet(&ipListIt->ipAddr.sin_addr)) + { + resultAddress = *ipListIt; + return true; + } + } + return false; } diff --git a/libretroshare/src/pqi/p3connmgr.h b/libretroshare/src/pqi/p3connmgr.h index bdd4d3683..3471a4c2b 100644 --- a/libretroshare/src/pqi/p3connmgr.h +++ b/libretroshare/src/pqi/p3connmgr.h @@ -143,17 +143,14 @@ class peerConnectState //used to store friends ip lists void sortIpAddressListBySeenTime(); //Sort the ip list ordering by seen time - void purgeIpAddressList(); //purge old addresses to keep a small list std::list getIpAddressList(); //return the sorted ant purged list. - void updateIpAddressList(IpAddressTimed ipTimed); - void updateIpAddressList(std::list ipTimedList); + void updateIpAddressList(const IpAddressTimed& ipTimed); + void updateIpAddressList(const std::list& ipTimedList); void printIpAddressList(); - static void sortIpAddressListBySeenTime(std::list &ipTimedList); //Sort the ip list ordering by seen time - static bool compare_seen_time (IpAddressTimed first, IpAddressTimed second); - static bool is_same_address (IpAddressTimed first, IpAddressTimed second); + static bool is_same_address (const IpAddressTimed& first, const IpAddressTimed& second); static void printIpAddressList(std::list ipTimedList); - static bool extractExtAddress(std::list ipAddressList, IpAddressTimed &resultAddress); //extract the last seen external address from the list + static bool extractExtAddress(const std::list& ipAddressList, IpAddressTimed &resultAddress); //extract the last seen external address from the list //used to store current ip (for config and connection management) 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 setExtAddress(std::string id, struct sockaddr_in addr); bool setDynDNS(std::string id, std::string dyndns); -bool setAddressList(std::string id, std::list IpAddressTimedList); +bool setAddressList(const std::string& id, const std::list& IpAddressTimedList); bool setNetworkMode(std::string id, uint32_t netMode); bool setVisState(std::string id, uint32_t visState); diff --git a/libretroshare/src/tcponudp/extaddrfinder.cc b/libretroshare/src/tcponudp/extaddrfinder.cc index 10d43ffb0..50fb1ce6c 100644 --- a/libretroshare/src/tcponudp/extaddrfinder.cc +++ b/libretroshare/src/tcponudp/extaddrfinder.cc @@ -161,7 +161,7 @@ void* doExtAddrSearch(void *p) 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 ; { @@ -194,7 +194,7 @@ void ExtAddrFinder::start_request() 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 std::cerr << "ExtAddrFinder: Getting ip." << std::endl ; @@ -284,10 +284,10 @@ ExtAddrFinder::ExtAddrFinder() _searching = new bool ; *_searching = false ; - mFoundTS = new time_t; - *mFoundTS = time(NULL) - MAX_IP_STORE; + mFoundTS = new time_t; + *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( "www.showmyip.com" )) ; diff --git a/libretroshare/src/tcponudp/extaddrfinder.h b/libretroshare/src/tcponudp/extaddrfinder.h index 55b0cd8d6..ec8782c7c 100644 --- a/libretroshare/src/tcponudp/extaddrfinder.h +++ b/libretroshare/src/tcponudp/extaddrfinder.h @@ -12,7 +12,7 @@ class ExtAddrFinder ExtAddrFinder() ; ~ExtAddrFinder() ; - bool hasValidIP(struct sockaddr_in *addr) ; + bool hasValidIP(struct in_addr *addr) ; void getIPServersList(std::list& ip_servers) { ip_servers = _ip_servers ; } void start_request() ; @@ -24,7 +24,7 @@ class ExtAddrFinder time_t *mFoundTS; RsMutex _addrMtx ; - struct sockaddr_in *_addr ; + struct in_addr *_addr ; bool *_found ; bool *_searching ; std::list _ip_servers ; diff --git a/libretroshare/src/util/rsnet.cc b/libretroshare/src/util/rsnet.cc index a29432d28..3e8e3d995 100644 --- a/libretroshare/src/util/rsnet.cc +++ b/libretroshare/src/util/rsnet.cc @@ -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. 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); 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); @@ -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)) { diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h index d7cf2ff0f..02018f083 100644 --- a/libretroshare/src/util/rsnet.h +++ b/libretroshare/src/util/rsnet.h @@ -65,10 +65,10 @@ uint64_t htonll(uint64_t x); void sockaddr_clear(struct sockaddr_in *addr); /* determine network type (moved from pqi/pqinetwork.cc) */ -bool isValidNet(struct in_addr *addr); -bool isLoopbackNet(struct in_addr *addr); -bool isPrivateNet(struct in_addr *addr); -bool isExternalNet(struct in_addr *addr); +bool isValidNet(const struct in_addr *addr); +bool isLoopbackNet(const struct in_addr *addr); +bool isPrivateNet(const struct in_addr *addr); +bool isExternalNet(const struct in_addr *addr); /* convert addresses */ bool getIPAddressFromString (const char *addr_str, struct in_addr *addr);