diff --git a/libretroshare/src/pqi/p3connmgr.cc b/libretroshare/src/pqi/p3connmgr.cc index 5f5cfa419..0ed4610a4 100644 --- a/libretroshare/src/pqi/p3connmgr.cc +++ b/libretroshare/src/pqi/p3connmgr.cc @@ -791,7 +791,13 @@ void p3ConnectMgr::networkConsistencyCheck() 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 (getExtFinderExtAddress(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; @@ -2359,7 +2365,7 @@ bool p3ConnectMgr::retryConnectTCP(std::string id) peerConnectAddress pca; pca.addr = ipListIt->ipAddr; pca.type = RS_NET_CONN_TCP_UNKNOW_TOPOLOGY; - //fir the delay, we add a random time and some more time when the friend list is big + //for the delay, we add a random time and some more time when the friend list is big pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY + rand() % 3 + (mFriendList.size() / 5); pca.ts = time(NULL); pca.period = 0; @@ -2367,6 +2373,43 @@ bool p3ConnectMgr::retryConnectTCP(std::string id) } } + if (!it->second.dyndns.empty()) { + struct in_addr addr; + u_short port = it->second.currentserveraddr.sin_port ? it->second.currentserveraddr.sin_port : it->second.currentlocaladdr.sin_port; + if (port) { + if (getIPAddressFromString (it->second.dyndns.c_str (), &addr)) { + bool found = false; + for (std::list::iterator cit = it->second.connAddrs.begin(); cit != it->second.connAddrs.end(); cit++) { + if (cit->addr.sin_addr.s_addr == addr.s_addr && + cit->addr.sin_port == port && + cit->type == RS_NET_CONN_TCP_UNKNOW_TOPOLOGY) { +#ifdef CONN_DEBUG + std::cerr << "p3ConnectMgr::retryConnectTCP() tcp attempt already in list." << std::endl; +#endif + found = true; + break; + } + } + + if (!found) { +#ifdef CONN_DEBUG + std::cerr << "Adding tcp connection attempt list." << std::endl; +#endif + peerConnectAddress pca; + pca.addr.sin_family = AF_INET; + pca.addr.sin_addr.s_addr = addr.s_addr; + pca.addr.sin_port = port; + pca.type = RS_NET_CONN_TCP_UNKNOW_TOPOLOGY; + //for the delay, we add a random time and some more time when the friend list is big + pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY + rand() % 3 + (mFriendList.size() / 5); + pca.ts = time(NULL); + pca.period = 0; + it->second.connAddrs.push_back(pca); + } + } + } + } + //add the supposed external address UDP IpAddressTimed extractedAddress; if (peerConnectState::extractExtAddress(it->second.getIpAddressList(), extractedAddress)) { @@ -2632,6 +2675,36 @@ bool p3ConnectMgr::setExtAddress(std::string id, struct sockaddr_in addr) return true; } +bool p3ConnectMgr::setDynDNS(std::string id, std::string dyndns) +{ + if (id == AuthSSL::getAuthSSL()->OwnId()) + { + ownState.dyndns = dyndns; + return true; + } + + RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ + /* check if it is a friend */ + 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 + return false; + } + } + + /* "it" points to peer */ + it->second.dyndns = dyndns; + + IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ + + return true; +} + bool p3ConnectMgr::setAddressList(std::string id, std::list IpAddressTimedList) { #ifdef CONN_DEBUG @@ -2912,6 +2985,7 @@ std::list p3ConnectMgr::saveList(bool &cleanup) item->currentlocaladdr = ownState.currentlocaladdr; item->currentremoteaddr = ownState.currentserveraddr; + item->dyndns = ownState.dyndns; item->ipAddressList = ownState.getIpAddressList(); #ifdef CONN_DEBUG @@ -2937,7 +3011,8 @@ std::list p3ConnectMgr::saveList(bool &cleanup) item->lastContact = (it->second).lastcontact; item->currentlocaladdr = (it->second).currentlocaladdr; item->currentremoteaddr = (it->second).currentserveraddr; - item->ipAddressList = (it->second).getIpAddressList(); + item->dyndns = (it->second).dyndns; + item->ipAddressList = (it->second).getIpAddressList(); saveData.push_back(item); #ifdef CONN_DEBUG @@ -3043,6 +3118,7 @@ bool p3ConnectMgr::loadList(std::list load) } setLocalAddress(pitem->pid, pitem->currentlocaladdr); setExtAddress(pitem->pid, pitem->currentremoteaddr); + setDynDNS (pitem->pid, pitem->dyndns); setAddressList(pitem->pid, pitem->ipAddressList); } else if (sitem) diff --git a/libretroshare/src/pqi/p3connmgr.h b/libretroshare/src/pqi/p3connmgr.h index 8eeda9621..a68b24706 100644 --- a/libretroshare/src/pqi/p3connmgr.h +++ b/libretroshare/src/pqi/p3connmgr.h @@ -158,6 +158,7 @@ class peerConnectState //used to store current ip (for config and connection management) struct sockaddr_in currentlocaladdr; /* Mandatory */ struct sockaddr_in currentserveraddr; /* Mandatory */ + std::string dyndns; time_t lastcontact; @@ -228,6 +229,7 @@ bool getNetStatusExtraAddressCheckOk(); 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 setNetworkMode(std::string id, uint32_t netMode); diff --git a/libretroshare/src/rsiface/rspeers.h b/libretroshare/src/rsiface/rspeers.h index 669070b1f..857347248 100644 --- a/libretroshare/src/rsiface/rspeers.h +++ b/libretroshare/src/rsiface/rspeers.h @@ -106,6 +106,7 @@ class RsPeerDetails uint16_t localPort; std::string extAddr; uint16_t extPort; + std::string dyndns; std::list ipAddressList; uint32_t netMode; @@ -166,6 +167,7 @@ virtual bool connectAttempt(std::string ssl_id) = 0; virtual bool setLocation(std::string ssl_id, std::string location) = 0;//location is shown in the gui to differentiate ssl certs virtual bool setLocalAddress(std::string ssl_id, std::string addr, uint16_t port) = 0; virtual bool setExtAddress( std::string ssl_id, std::string addr, uint16_t port) = 0; +virtual bool setDynDNS(std::string id, std::string addr) = 0; virtual bool setNetworkMode(std::string ssl_id, uint32_t netMode) = 0; virtual bool setVisState(std::string ssl_id, uint32_t vis) = 0; diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index c2a03e885..8fbcb0b20 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -42,6 +42,7 @@ const std::string CERT_SSL_ID = "--SSLID--"; const std::string CERT_LOCATION = "--LOCATION--"; const std::string CERT_LOCAL_IP = "--LOCAL--"; const std::string CERT_EXT_IP = "--EXT--"; +const std::string CERT_DYNDNS = "--DYNDNS--"; @@ -308,6 +309,7 @@ bool p3Peers::getPeerDetails(std::string id, RsPeerDetails &d) d.localPort = ntohs(best_local_addr.sin_port); d.extAddr = inet_ntoa(best_servr_addr.sin_addr); d.extPort = ntohs(best_servr_addr.sin_port); + d.dyndns = pcs.dyndns; d.lastConnect = pcs.lastcontact; d.connectPeriod = 0; std::list ipAddressList; @@ -729,6 +731,10 @@ bool p3Peers::setExtAddress(std::string id, std::string addr_str, uint16_t port return false; } +bool p3Peers::setDynDNS(std::string id, std::string dyndns) +{ + return mConnMgr->setDynDNS(id, dyndns); +} bool p3Peers::setNetworkMode(std::string id, uint32_t extNetMode) { @@ -800,6 +806,9 @@ p3Peers::GetRetroshareInvite() std::ostringstream out2; out2 << ownDetail.extPort; invite += out2.str() + ";"; + if (!ownDetail.dyndns.empty()) { + invite += "\n" + CERT_DYNDNS + ownDetail.dyndns + ";"; + } } #ifdef P3PEERS_DEBUG @@ -976,6 +985,19 @@ bool p3Peers::loadDetailsFromStringCert(std::string certstr, RsPeerDetails &pd) } } + //let's parse DynDNS + parsePosition = certstr.find(CERT_DYNDNS); + std::cerr << "location DynDNS : " << parsePosition << std::endl; + if (parsePosition != std::string::npos) { + parsePosition += CERT_DYNDNS.length(); + std::string subCert = certstr.substr(parsePosition); + parsePosition = subCert.find(";"); + if (parsePosition != std::string::npos) { + std::string DynDNS = subCert.substr(0, parsePosition); + std::cerr << "DynDNS : " << DynDNS << std::endl; + pd.dyndns = DynDNS; + } + } } catch (...) { std::cerr << "ConnectFriendWizard : Parse ip address error." << std::endl; diff --git a/libretroshare/src/rsserver/p3peers.h b/libretroshare/src/rsserver/p3peers.h index 2ce462cbc..9f0110d3f 100644 --- a/libretroshare/src/rsserver/p3peers.h +++ b/libretroshare/src/rsserver/p3peers.h @@ -75,6 +75,7 @@ virtual bool connectAttempt(std::string id); virtual bool setLocation(std::string ssl_id, std::string location);//location is shown in the gui to differentiate ssl certs virtual bool setLocalAddress(std::string id, std::string addr, uint16_t port); virtual bool setExtAddress(std::string id, std::string addr, uint16_t port); +virtual bool setDynDNS(std::string id, std::string dyndns); virtual bool setNetworkMode(std::string id, uint32_t netMode); virtual bool setVisState(std::string id, uint32_t mode); diff --git a/libretroshare/src/serialiser/rsconfigitems.cc b/libretroshare/src/serialiser/rsconfigitems.cc index f0aa97f68..7606884b3 100644 --- a/libretroshare/src/serialiser/rsconfigitems.cc +++ b/libretroshare/src/serialiser/rsconfigitems.cc @@ -740,6 +740,7 @@ void RsPeerNetItem::clear() sockaddr_clear(¤tlocaladdr); sockaddr_clear(¤tremoteaddr); + dyndns.clear(); } std::ostream &RsPeerNetItem::print(std::ostream &out, uint16_t indent) @@ -773,6 +774,9 @@ std::ostream &RsPeerNetItem::print(std::ostream &out, uint16_t indent) out << "currentremoteaddr: " << inet_ntoa(currentremoteaddr.sin_addr); out << ":" << htons(currentremoteaddr.sin_port) << std::endl; + printIndent(out, int_Indent); + out << "DynDNS: " << dyndns << std::endl; + printIndent(out, int_Indent); out << "ipAdressList: size : " << ipAddressList.size() << ", adresses : " << std::endl; for (std::list::iterator ipListIt = ipAddressList.begin(); ipListIt!=(ipAddressList.end()); ipListIt++) { @@ -797,6 +801,7 @@ uint32_t RsPeerConfigSerialiser::sizeNet(RsPeerNetItem *i) s += 4; /* lastContact */ s += GetTlvIpAddrPortV4Size(); /* localaddr */ s += GetTlvIpAddrPortV4Size(); /* remoteaddr */ + s += GetTlvStringSize(i->dyndns); //add the size of the ip list int ipListSize = i->ipAddressList.size(); @@ -840,6 +845,7 @@ bool RsPeerConfigSerialiser::serialiseNet(RsPeerNetItem *item, void *data, uint3 ok &= setRawUInt32(data, tlvsize, &offset, item->lastContact); /* Mandatory */ ok &= SetTlvIpAddrPortV4(data, tlvsize, &offset, TLV_TYPE_IPV4_LOCAL, &(item->currentlocaladdr)); ok &= SetTlvIpAddrPortV4(data, tlvsize, &offset, TLV_TYPE_IPV4_REMOTE, &(item->currentremoteaddr)); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_DYNDNS, item->dyndns); //store the ip list std::list::iterator ipListIt; @@ -900,6 +906,7 @@ RsPeerNetItem *RsPeerConfigSerialiser::deserialiseNet(void *data, uint32_t *size ok &= getRawUInt32(data, rssize, &offset, &(item->lastContact)); /* Mandatory */ ok &= GetTlvIpAddrPortV4(data, rssize, &offset, TLV_TYPE_IPV4_LOCAL, &(item->currentlocaladdr)); ok &= GetTlvIpAddrPortV4(data, rssize, &offset, TLV_TYPE_IPV4_REMOTE, &(item->currentremoteaddr)); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_DYNDNS, item->dyndns); //get the ip adress list std::list ipTimedList; diff --git a/libretroshare/src/serialiser/rsconfigitems.h b/libretroshare/src/serialiser/rsconfigitems.h index a9a10b17d..210dcb0a4 100644 --- a/libretroshare/src/serialiser/rsconfigitems.h +++ b/libretroshare/src/serialiser/rsconfigitems.h @@ -79,6 +79,7 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0); struct sockaddr_in currentlocaladdr; /* Mandatory */ struct sockaddr_in currentremoteaddr; /* Mandatory */ + std::string dyndns; std::list ipAddressList; }; diff --git a/libretroshare/src/serialiser/rstlvbase.h b/libretroshare/src/serialiser/rstlvbase.h index 82038308a..e388d3b14 100644 --- a/libretroshare/src/serialiser/rstlvbase.h +++ b/libretroshare/src/serialiser/rstlvbase.h @@ -155,6 +155,7 @@ const uint16_t TLV_TYPE_STR_HASH_ED2K = 0x0071; const uint16_t TLV_TYPE_IPV4_LOCAL = 0x0080; const uint16_t TLV_TYPE_IPV4_REMOTE = 0x0081; const uint16_t TLV_TYPE_IPV4_LAST = 0x0082; +const uint16_t TLV_TYPE_STR_DYNDNS = 0x0083; /*** MORE STRING IDS ****/ const uint16_t TLV_TYPE_STR_GROUPID = 0x00a0; diff --git a/libretroshare/src/services/p3disc.cc b/libretroshare/src/services/p3disc.cc index dd2513ff6..28fcd0b04 100644 --- a/libretroshare/src/services/p3disc.cc +++ b/libretroshare/src/services/p3disc.cc @@ -349,6 +349,7 @@ void p3disc::sendPeerDetails(std::string to, std::string about) { rsPeerNetItem->lastContact = detail.lastcontact; rsPeerNetItem->currentlocaladdr = detail.currentlocaladdr; rsPeerNetItem->currentremoteaddr = detail.currentserveraddr; + rsPeerNetItem->dyndns = detail.dyndns; rsPeerNetItem->ipAddressList = detail.getIpAddressList(); di->rsPeerList.push_back(*rsPeerNetItem); @@ -369,6 +370,7 @@ void p3disc::sendPeerDetails(std::string to, std::string about) { rsPeerNetItem->lastContact = time(NULL); rsPeerNetItem->currentlocaladdr = detail.currentlocaladdr; rsPeerNetItem->currentremoteaddr = detail.currentserveraddr; + rsPeerNetItem->dyndns = detail.dyndns; rsPeerNetItem->ipAddressList = detail.getIpAddressList(); di->rsPeerList.push_back(*rsPeerNetItem); @@ -550,6 +552,7 @@ void p3disc::recvPeerDetails(RsDiscReply *item) //their info is fresher than ours (there is a 10000 seconds margin), update ours mConnMgr->setLocalAddress(pitem->pid, pitem->currentlocaladdr); mConnMgr->setExtAddress(pitem->pid, pitem->currentremoteaddr); + mConnMgr->setDynDNS(pitem->pid, pitem->dyndns); mConnMgr->setNetworkMode(pitem->pid, pitem->netMode); if (item->PeerId() == pitem->pid) { mConnMgr->setVisState(pitem->pid, pitem->visState); //update vistate only if it's from the peer itself diff --git a/libretroshare/src/util/rsnet.cc b/libretroshare/src/util/rsnet.cc index 938f15c98..1bd0497aa 100644 --- a/libretroshare/src/util/rsnet.cc +++ b/libretroshare/src/util/rsnet.cc @@ -123,5 +123,15 @@ bool isExternalNet(struct in_addr *addr) return true; } +bool getIPAddressFromString (const char *addr_str, struct in_addr *addr) +{ + if (addr_str && addr) { + hostent *pHost = gethostbyname (addr_str); + if (pHost) { + addr->s_addr = *(unsigned long*) (pHost->h_addr); + return true; + } + } - + return false; +} diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h index cb2da1063..52a0da77d 100644 --- a/libretroshare/src/util/rsnet.h +++ b/libretroshare/src/util/rsnet.h @@ -68,5 +68,7 @@ bool isLoopbackNet(struct in_addr *addr); bool isPrivateNet(struct in_addr *addr); bool isExternalNet(struct in_addr *addr); +/* convert addresses */ +bool getIPAddressFromString (const char *addr_str, struct in_addr *addr); #endif /* RS_UNIVERSAL_NETWORK_HEADER */ diff --git a/retroshare-gui/src/gui/QuickStartWizard.ui b/retroshare-gui/src/gui/QuickStartWizard.ui index 4cb1eda13..27bce97e2 100644 --- a/retroshare-gui/src/gui/QuickStartWizard.ui +++ b/retroshare-gui/src/gui/QuickStartWizard.ui @@ -450,6 +450,16 @@ p, li { white-space: pre-wrap; } + + + + Dynamic DNS: + + + + + + @@ -636,6 +646,15 @@ p, li { white-space: pre-wrap; } 22 + + false + + + 22 + + + true + Directory diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.ui b/retroshare-gui/src/gui/connect/ConfCertDialog.ui index 59082adc7..4e3eefe77 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.ui +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.ui @@ -141,6 +141,13 @@ + + + + Dynamic DNS + + + @@ -151,6 +158,9 @@ + + + @@ -169,6 +179,22 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 27 + + + + @@ -199,6 +225,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index 0267f1f91..dc24ce0a1 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -160,6 +160,8 @@ void ServerPage::load() /* set the server address */ ui.extAddress->setText(QString::fromStdString(detail.extAddr)); ui.extPort -> setValue(detail.extPort); + /* set DynDNS */ + ui.dynDNS -> setText(QString::fromStdString(detail.dyndns)); } /** Loads the settings for this page */ @@ -262,7 +264,9 @@ void ServerPage::saveAddresses() rsPeers->setExtAddress(rsPeers->getOwnId(), ui.extAddress->text().toStdString(), ui.extPort->value()); } - rsicontrol->ConfigSetDataRates( ui.totalDownloadRate->value(), ui.totalUploadRate->value() ); + rsPeers->setDynDNS(rsPeers->getOwnId(), ui.dynDNS->text().toStdString()); + + rsicontrol->ConfigSetDataRates( ui.totalDownloadRate->value(), ui.totalUploadRate->value() ); load(); } diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index c346622a3..80bb02f4e 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -691,6 +691,13 @@ + + + + Dynamic DNS + + + @@ -744,6 +751,9 @@ + + +