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/branches/v0.5.0@2981 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-05-23 22:14:13 +00:00
parent f78e25521b
commit cb535dd73d
6 changed files with 337 additions and 306 deletions

View File

@ -749,114 +749,134 @@ void p3ConnectMgr::netUpnpCheck()
void p3ConnectMgr::networkConsistencyCheck() void p3ConnectMgr::networkConsistencyCheck()
{ {
time_t delta; time_t delta;
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
delta = time(NULL) - mNetInitTS; delta = time(NULL) - mNetInitTS;
std::cerr << "p3ConnectMgr::networkConsistencyCheck() time since last reset : " << delta << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() time since last reset : " << delta << std::endl;
#endif #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 //if one of the flag is degrated from true to false during last tick, let's do a reset
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
std::cerr << "p3ConnectMgr::networkConsistencyCheck() net flags : " << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() net flags : " << std::endl;
std::cerr << " oldnetFlagLocalOk : " << oldnetFlagLocalOk << ". netFlagLocalOk : " << netFlagLocalOk << "." << std::endl; std::cerr << " oldnetFlagLocalOk : " << oldnetFlagLocalOk << ". netFlagLocalOk : " << netFlagLocalOk << "." << std::endl;
std::cerr << " oldnetFlagUpnpOk : " << oldnetFlagUpnpOk << ". netFlagUpnpOk : " << netFlagUpnpOk << "." << std::endl; std::cerr << " oldnetFlagUpnpOk : " << oldnetFlagUpnpOk << ". netFlagUpnpOk : " << netFlagUpnpOk << "." << std::endl;
std::cerr << " oldnetFlagDhtOk : " << oldnetFlagDhtOk << ". netFlagDhtOk : " << netFlagDhtOk << "." << std::endl; std::cerr << " oldnetFlagDhtOk : " << oldnetFlagDhtOk << ". netFlagDhtOk : " << netFlagDhtOk << "." << std::endl;
std::cerr << " oldnetFlagStunOk : " << oldnetFlagStunOk << ". netFlagStunOk : " << netFlagStunOk << "." << std::endl; std::cerr << " oldnetFlagStunOk : " << oldnetFlagStunOk << ". netFlagStunOk : " << netFlagStunOk << "." << std::endl;
std::cerr << " oldnetFlagExtraAddressCheckOk : " << oldnetFlagExtraAddressCheckOk << ". netFlagExtraAddressCheckOk : " << netFlagExtraAddressCheckOk << "." << std::endl; std::cerr << " oldnetFlagExtraAddressCheckOk : " << oldnetFlagExtraAddressCheckOk << ". netFlagExtraAddressCheckOk : " << netFlagExtraAddressCheckOk << "." << std::endl;
#endif #endif
if ( !netFlagLocalOk if ( !netFlagLocalOk
|| (!netFlagUpnpOk && oldnetFlagUpnpOk) || (!netFlagUpnpOk && oldnetFlagUpnpOk)
|| (!netFlagDhtOk && oldnetFlagDhtOk) || (!netFlagDhtOk && oldnetFlagDhtOk)
|| (!netFlagStunOk && oldnetFlagStunOk) || (!netFlagStunOk && oldnetFlagStunOk)
|| (!netFlagExtraAddressCheckOk && oldnetFlagExtraAddressCheckOk) || (!netFlagExtraAddressCheckOk && oldnetFlagExtraAddressCheckOk)
) { ) {
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
std::cerr << "p3ConnectMgr::networkConsistencyCheck() A net flag went down." << std::endl; std::cerr << "p3ConnectMgr::networkConsistencyCheck() A net flag went down." << std::endl;
#endif #endif
//don't do a normal shutdown for upnp as it might hang up. //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. //With a 0 port it will just dereference and not attemps to communicate for shutting down upnp session.
netAssistFirewallPorts(0, 0); netAssistFirewallPorts(0, 0);
doNetReset = true; doNetReset = true;
} }
connMtx.lock(); /* LOCK MUTEX */ bool haveReliableIP = false ;
//storing old flags
oldnetFlagLocalOk = netFlagLocalOk;
oldnetFlagUpnpOk = netFlagUpnpOk;
oldnetFlagDhtOk = netFlagDhtOk;
oldnetFlagStunOk = netFlagStunOk;
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. {
struct sockaddr_in extAddr; RsStackMutex stck(connMtx) ;
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;
}
//check if a peer is connected, if yes don't do a net reset //storing old flags
bool is_connected = false; oldnetFlagLocalOk = netFlagLocalOk;
std::map<std::string, peerConnectState>::iterator it; oldnetFlagUpnpOk = netFlagUpnpOk;
for(it = mFriendList.begin(); it != mFriendList.end() && !is_connected; it++) oldnetFlagDhtOk = netFlagDhtOk;
{ oldnetFlagStunOk = netFlagStunOk;
/* get last contact detail */ oldnetFlagExtraAddressCheckOk = netFlagExtraAddressCheckOk;
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 */
if (!doNetReset) { if (!doNetReset)
//extAddr found,update ip address list { // Set an external address. if ip adresses are different, let's use the stun address, then
IpAddressTimed ipAddressTimed; // the extaddrfinder and then the upnp address.
ipAddressTimed.ipAddr = ownState.currentserveraddr; //
ipAddressTimed.seenTime = time(NULL); struct sockaddr_in extAddr;
ownState.updateIpAddressList(ipAddressTimed);
}
//let's do a net reset if (getExtFinderExtAddress(extAddr))
if (doNetReset) { {
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<std::string, peerConnectState>::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 //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) {
#ifdef CONN_DEBUG_TICK #ifdef CONN_DEBUG_TICK
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 { }
#ifdef CONN_DEBUG_TICK else
{
#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;
#endif #endif
} }
} }
} }
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;
@ -1657,7 +1677,6 @@ bool p3ConnectMgr::connectResult(std::string id, bool success, uint32_t flags, s
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();
@ -2586,38 +2605,40 @@ bool p3ConnectMgr::setLocalAddress(std::string id, struct sockaddr_in addr)
bool p3ConnectMgr::setExtAddress(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 || 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 ||
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 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 */ /* check if it is a friend */
std::map<std::string, peerConnectState>::iterator it; std::map<std::string, peerConnectState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id))) if (mFriendList.end() == (it = mFriendList.find(id)))
{ {
if (mOthersList.end() == (it = mOthersList.find(id))) if (mOthersList.end() == (it = mOthersList.find(id)))
{ {
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list id: " << id << std::endl; std::cerr << "p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list id: " << id << std::endl;
#endif #endif
return false; return false;
} }
} }
@ -2635,45 +2656,48 @@ bool p3ConnectMgr::setExtAddress(std::string id, struct sockaddr_in addr)
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;
#endif #endif
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); {
//if we have no ext address from upnp or extAdrFinder, we will use this list for ext ip detection ownState.updateIpAddressList(IpAddressTimedList);
//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 */ //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<std::string, peerConnectState>::iterator it; std::map<std::string, peerConnectState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id))) if (mFriendList.end() == (it = mFriendList.find(id)))
{ {
#ifdef CONN_DEBUG #ifdef CONN_DEBUG
std::cerr << "p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list. id: " << id << std::endl; std::cerr << "p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list. id: " << id << std::endl;
#endif #endif
return false; return false;
} }
/* "it" points to peer */ /* "it" points to peer */
@ -2801,7 +2825,7 @@ bool p3ConnectMgr::checkNetAddress()
// //
ownState.currentlocaladdr.sin_addr = getPreferredInterface() ; 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) if (netFlagLocalOk != true)
{ {
@ -2811,20 +2835,19 @@ 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;
#endif #endif
netFlagLocalOk = false; netFlagLocalOk = false;
netFlagExtraAddressCheckOk = false; netFlagExtraAddressCheckOk = false;
netFlagUpnpOk = false; netFlagUpnpOk = false;
netFlagDhtOk = false; netFlagDhtOk = false;
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;
@ -2846,12 +2869,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;
@ -3072,17 +3095,16 @@ bool p3ConnectMgr::loadList(std::list<RsItem *> load)
vitem->print(std::cerr, 10); vitem->print(std::cerr, 10);
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
std::list<RsTlvKeyValue>::iterator kit; std::list<RsTlvKeyValue>::iterator kit;
for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); kit++) { for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); kit++) {
if(kit->key == "USE_EXTR_IP_FINDER") { if(kit->key == "USE_EXTR_IP_FINDER") {
use_extr_addr_finder = (kit->value == "TRUE"); use_extr_addr_finder = (kit->value == "TRUE");
std::cerr << "setting use_extr_addr_finder to " << use_extr_addr_finder << std::endl ; std::cerr << "setting use_extr_addr_finder to " << use_extr_addr_finder << std::endl ;
} else if (kit->key == "ALLOW_TUNNEL_CONNECTION") { } else if (kit->key == "ALLOW_TUNNEL_CONNECTION") {
allow_tunnel_connection = (kit->value == "TRUE"); allow_tunnel_connection = (kit->value == "TRUE");
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);
@ -3401,148 +3423,160 @@ bool p3ConnectMgr::getStunExtAddress(struct sockaddr_in &addr) {
} }
bool p3ConnectMgr::getExtFinderExtAddress(struct sockaddr_in &addr) { #define CONN_DEBUG 1
if ((use_extr_addr_finder && mExtAddrFinder->hasValidIP(&addr))) {
addr.sin_port = ownState.currentlocaladdr.sin_port; bool p3ConnectMgr::getExtFinderExtAddress(struct sockaddr_in &addr)
return true; {
} else { struct in_addr ad ;
return false;
} 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 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") { 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 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)
bool found = false; {
std::list<IpAddressTimed>::iterator ipListIt; #ifdef CONN_DEBUG
for (ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()) && !found; ipListIt++) { std::cerr << "peerConnectState::updateIpAdressList() ip parameter is 0.0.0.0, or port is 0, ignoring." << std::endl;
if (is_same_address(*ipListIt, ipTimed)) { #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<IpAddressTimed>::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 #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)
#ifdef CONN_DEBUG {
std::cerr << "peerConnectState::updateIpAdressList() Update seen time to : " << ipTimed.seenTime << std::endl; (*ipListIt).seenTime = ipTimed.seenTime;
#endif (*ipListIt).ipAddr.sin_port = ipTimed.ipAddr.sin_port ; // keep the port of the most recent address.
}
}
}
if (!found) {
//add the current addresses to the ip list
#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() Update seen time to : " << ipTimed.seenTime << std::endl;
std::cerr << ":" << ntohs(ipTimed.ipAddr.sin_port);
std::cerr << std::endl;
#endif #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 ;
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);
}
// 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()
{
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;
} }
void peerConnectState::printIpAddressList() { // Extract first address that is not the same as local address
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++) { bool peerConnectState::extractExtAddress(const std::list<IpAddressTimed>& IpAddressTimedList, IpAddressTimed &resultAddress)
std::cerr << inet_ntoa(ipListIt->ipAddr.sin_addr) << ":" << ntohs(ipListIt->ipAddr.sin_port) << " seenTime : " << ipListIt->seenTime << std::endl; {
//check if the ip list contains the current remote address of the connected peer
//
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
//if ((ipListIt->ipAddr.sin_addr.s_addr != 0)
//
if(!isPrivateNet(&ipListIt->ipAddr.sin_addr))
{
resultAddress = *ipListIt;
return true;
} }
} }
return false;
bool peerConnectState::extractExtAddress(std::list<IpAddressTimed> 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<IpAddressTimed>::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;
} }

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 */
@ -228,7 +225,7 @@ bool getNetStatusExtraAddressCheckOk();
void setOwnNetConfig(uint32_t netMode, uint32_t visState); 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 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

@ -160,7 +160,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 ;
{ {
@ -193,7 +193,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 ;
@ -283,10 +283,10 @@ ExtAddrFinder::ExtAddrFinder()
_searching = new bool ; _searching = new bool ;
*_searching = false ; *_searching = false ;
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

@ -67,7 +67,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)
@ -79,13 +79,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);
@ -106,7 +106,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

@ -63,10 +63,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);
#endif /* RS_UNIVERSAL_NETWORK_HEADER */ #endif /* RS_UNIVERSAL_NETWORK_HEADER */