diff --git a/libretroshare/src/pqi/p3connmgr.cc b/libretroshare/src/pqi/p3connmgr.cc index d1d56c922..6c543e152 100644 --- a/libretroshare/src/pqi/p3connmgr.cc +++ b/libretroshare/src/pqi/p3connmgr.cc @@ -1086,7 +1086,7 @@ void p3ConnectMgr::stunStatus(std::string id, struct sockaddr_in raddr, uint3 connMtx.unlock(); /* UNLOCK MUTEX */ - /* only useful if they have an exposed TCP/UDP port */ + /* only useful if they have an exposed TCP/UDP port */ if (type & RS_NET_CONN_TCP_EXTERNAL) { if (stillStunning) @@ -1536,7 +1536,7 @@ bool p3ConnectMgr::connectAttempt(std::string id, struct sockaddr_in &addr, * */ -bool p3ConnectMgr::connectResult(std::string id, bool success, uint32_t flags) +bool p3ConnectMgr::connectResult(std::string id, bool success, uint32_t flags, struct sockaddr_in remote_peer_address) { RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ @@ -1558,16 +1558,15 @@ bool p3ConnectMgr::connectResult(std::string id, bool success, uint32_t flags) return false; } - - it->second.inConnAttempt = false; + it->second.inConnAttempt = false; if (success) { - /* remove other attempts */ - it->second.connAddrs.clear(); - netAssistFriend(id, false); + /* remove other attempts */ + it->second.inConnAttempt = false; + netAssistFriend(id, false); - /* update address (will come through from DISC) */ + /* update address (will come although through from DISC) */ #ifdef CONN_DEBUG std::cerr << "p3ConnectMgr::connectResult() Connect!: id: " << id << std::endl; @@ -1579,24 +1578,25 @@ bool p3ConnectMgr::connectResult(std::string id, bool success, uint32_t flags) /* change state */ it->second.state |= RS_PEER_S_CONNECTED; it->second.actions |= RS_PEER_CONNECTED; - mStatusChanged = true; it->second.lastcontact = time(NULL); /* time of connect */ - it->second.connecttype = flags; + it->second.connecttype = flags; - IpAddressTimed ipLocalAddressTimed; - ipLocalAddressTimed.ipAddr = it->second.currentlocaladdr; - ipLocalAddressTimed.seenTime = time(NULL); - it->second.updateIpAddressList(ipLocalAddressTimed); + if (remote_peer_address.sin_addr.s_addr != 0) { + IpAddressTimed ipLocalAddressTimed; + ipLocalAddressTimed.ipAddr = remote_peer_address; + ipLocalAddressTimed.seenTime = time(NULL); + it->second.updateIpAddressList(ipLocalAddressTimed); - IpAddressTimed ipRemoteAddressTimed; - ipRemoteAddressTimed.ipAddr = it->second.currentserveraddr; - ipRemoteAddressTimed.seenTime = time(NULL); - it->second.updateIpAddressList(ipRemoteAddressTimed); + it->second.purgeIpAddressList(); + #ifdef CONN_DEBUG + std::cerr << "p3ConnectMgr::connectResult() adding current peer adress in list." << std::endl; + it->second.printIpAddressList(); + #endif + } - it->second.purgeIpAddressList(); - it->second.printIpAddressList(); //output log - return true; - } + mStatusChanged = true; + return true; + } #ifdef CONN_DEBUG std::cerr << "p3ConnectMgr::connectResult() Disconnect/Fail: id: " << id << std::endl; @@ -2450,17 +2450,13 @@ bool p3ConnectMgr::setExtAddress(std::string id, struct sockaddr_in addr) { if (id == mAuthMgr->OwnId()) { - { - RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ - ownState.currentserveraddr = addr; - } - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - if ((ownState.netMode & RS_NET_MODE_ACTUAL) == RS_NET_MODE_EXT || - (ownState.netMode & RS_NET_MODE_ACTUAL) == RS_NET_MODE_UDP) { - netReset(); - } + 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; + } return true; - } + } RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ /* check if it is a friend */ @@ -2491,9 +2487,40 @@ bool p3ConnectMgr::setExtAddress(std::string id, struct sockaddr_in addr) bool p3ConnectMgr::setAddressList(std::string id, std::list IpAddressTimedList) { - RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/ + /* check if it is our own ip */ + if (id == getOwnId()) { + //extract first address that is not the same as local address + //check if the ip list contains the current remote address of the connected peer + bool found = false; + std::list::iterator ipListIt; + for (ipListIt = IpAddressTimedList.begin(); ipListIt!=(IpAddressTimedList.end()) && !found; ipListIt++) { + //assume address is valid if not same as local address, is not 0 and is not loopback + if (!(ipListIt->ipAddr.sin_addr.s_addr == ownState.currentlocaladdr.sin_addr.s_addr) + && (ipListIt->ipAddr.sin_addr.s_addr != 0) + && (!isLoopbackNet(&ipListIt->ipAddr.sin_addr)) + ) { + found = true; + } + } - /* check if it is a friend */ + if (found) { + //the pointer ipListIt is pointing to an external address + #ifdef CONN_DEBUG + std::cerr << "p3ConnectMgr::setAddressList() setting own ext adress from p3disc : "; + std::cerr << inet_ntoa(ipListIt->ipAddr.sin_addr) << ":" << ntohs(ipListIt->ipAddr.sin_port) << " seenTime : " << ipListIt->seenTime << std::endl; + #endif + + setExtAddress(getOwnId(), ipListIt->ipAddr); + } + + + IndicateConfigChanged(); + 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))) { diff --git a/libretroshare/src/pqi/p3connmgr.h b/libretroshare/src/pqi/p3connmgr.h index 159c09f7a..b8a4f35bf 100644 --- a/libretroshare/src/pqi/p3connmgr.h +++ b/libretroshare/src/pqi/p3connmgr.h @@ -226,7 +226,6 @@ bool setLocalAddress(std::string id, struct sockaddr_in addr); bool setExtAddress(std::string id, struct sockaddr_in addr); bool setAddressList(std::string id, std::list IpAddressTimedList); - bool setNetworkMode(std::string id, uint32_t netMode); bool setVisState(std::string id, uint32_t visState); @@ -268,7 +267,7 @@ virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t ty /****************** Connections *******************/ bool connectAttempt(std::string id, struct sockaddr_in &addr, uint32_t &delay, uint32_t &period, uint32_t &type); -bool connectResult(std::string id, bool success, uint32_t flags); +bool connectResult(std::string id, bool success, uint32_t flags, struct sockaddr_in remote_peer_address); bool doNextAttempt(std::string id); p3tunnel* getP3tunnel(); @@ -287,7 +286,7 @@ virtual bool netAssistConnectEnabled(); virtual bool netAssistConnectActive(); virtual bool netAssistConnectShutdown(); - /* Assist Firewall */ +/* Assist Firewall */ bool netAssistExtAddress(struct sockaddr_in &extAddr); bool netAssistFirewallPorts(uint16_t iport, uint16_t eport); diff --git a/libretroshare/src/pqi/pqi_base.h b/libretroshare/src/pqi/pqi_base.h index f12628fae..58944038d 100644 --- a/libretroshare/src/pqi/pqi_base.h +++ b/libretroshare/src/pqi/pqi_base.h @@ -374,6 +374,7 @@ virtual int stoplistening() = 0; virtual int disconnect() = 0; virtual int reset() = 0; virtual std::string PeerId() { return peerId; } +virtual int getConnectAddress(struct sockaddr_in &raddr) = 0; virtual bool connect_parameter(uint32_t type, uint32_t value) = 0; diff --git a/libretroshare/src/pqi/pqibin.h b/libretroshare/src/pqi/pqibin.h index e0124c99f..206edc72a 100644 --- a/libretroshare/src/pqi/pqibin.h +++ b/libretroshare/src/pqi/pqibin.h @@ -138,6 +138,7 @@ virtual int stoplistening(); virtual int disconnect(); virtual int reset(); virtual bool connect_parameter(uint32_t type, uint32_t value) { return false; } +virtual int getConnectAddress(struct sockaddr_in &raddr) {return 0;} // Bin Interface. virtual int tick(); diff --git a/libretroshare/src/pqi/pqiperson.cc b/libretroshare/src/pqi/pqiperson.cc index 3cbcee986..572845295 100644 --- a/libretroshare/src/pqi/pqiperson.cc +++ b/libretroshare/src/pqi/pqiperson.cc @@ -156,7 +156,7 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState) } /* find the pqi, */ - pqiconnect *pqi = NULL; + pqiconnect *pqi = NULL; uint32_t type = 0; std::map::iterator it; @@ -193,8 +193,11 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState) case CONNECT_SUCCESS: /* notify */ - if (pqipg) - pqipg->notifyConnect(PeerId(), type, true); + if (pqipg) { + struct sockaddr_in remote_peer_address; + pqi->getConnectAddress(remote_peer_address); + pqipg->notifyConnect(PeerId(), type, true, remote_peer_address); + } if ((active) && (activepqi != pqi)) // already connected - trouble { diff --git a/libretroshare/src/pqi/pqiperson.h b/libretroshare/src/pqi/pqiperson.h index 946c964ac..90db6a771 100644 --- a/libretroshare/src/pqi/pqiperson.h +++ b/libretroshare/src/pqi/pqiperson.h @@ -69,6 +69,7 @@ virtual int stoplistening() { return ni -> stoplistening(); } virtual int reset() { return ni -> reset(); } virtual int disconnect() { return ni -> reset(); } virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni -> connect_parameter(type, value);} +virtual int getConnectAddress(struct sockaddr_in &raddr){ return ni->getConnectAddress(raddr); } // get the contact from the net side! virtual std::string PeerId() diff --git a/libretroshare/src/pqi/pqipersongrp.cc b/libretroshare/src/pqi/pqipersongrp.cc index fe0a9407e..1000827a8 100644 --- a/libretroshare/src/pqi/pqipersongrp.cc +++ b/libretroshare/src/pqi/pqipersongrp.cc @@ -476,7 +476,13 @@ int pqipersongrp::connectPeer(std::string id) return 1; } -bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success) +bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success) { + struct sockaddr_in remote_peer_address; + sockaddr_clear(&remote_peer_address); + notifyConnect(id, ptype, success, remote_peer_address); +} + +bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success, struct sockaddr_in remote_peer_address) { uint32_t type = 0; if (ptype == PQI_CONNECT_TCP) @@ -496,7 +502,7 @@ bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success if (ptype == PQI_CONNECT_DO_NEXT_ATTEMPT) { mConnMgr->doNextAttempt(id); } else { - mConnMgr->connectResult(id, success, type); + mConnMgr->connectResult(id, success, type, remote_peer_address); } } diff --git a/libretroshare/src/pqi/pqipersongrp.h b/libretroshare/src/pqi/pqipersongrp.h index e0330b8c0..d184c6333 100644 --- a/libretroshare/src/pqi/pqipersongrp.h +++ b/libretroshare/src/pqi/pqipersongrp.h @@ -72,6 +72,7 @@ int removePeer(std::string id); int connectPeer(std::string id); /*** callback from children ****/ +bool notifyConnect(std::string id, uint32_t type, bool success, struct sockaddr_in remote_peer_address); bool notifyConnect(std::string id, uint32_t type, bool success); // tick interfaces. diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index d644d5510..97ed76d20 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -178,6 +178,11 @@ int pqissl::disconnect() return reset(); } +int pqissl::getConnectAddress(struct sockaddr_in &raddr) { + raddr = remote_addr; + return (remote_addr.sin_addr.s_addr == 0); +} + /* BinInterface version of reset() for pqistreamer */ int pqissl::close() { diff --git a/libretroshare/src/pqi/pqissl.h b/libretroshare/src/pqi/pqissl.h index 485e8b092..9e886d50c 100644 --- a/libretroshare/src/pqi/pqissl.h +++ b/libretroshare/src/pqi/pqissl.h @@ -104,6 +104,7 @@ virtual int listen(); virtual int stoplistening(); virtual int reset(); virtual int disconnect(); +virtual int getConnectAddress(struct sockaddr_in &raddr); virtual bool connect_parameter(uint32_t type, uint32_t value); diff --git a/libretroshare/src/pqi/pqissltunnel.cc b/libretroshare/src/pqi/pqissltunnel.cc index 4f110dfff..147f9c944 100644 --- a/libretroshare/src/pqi/pqissltunnel.cc +++ b/libretroshare/src/pqi/pqissltunnel.cc @@ -196,6 +196,11 @@ int pqissltunnel::reset() return 1; } +int pqissltunnel::getConnectAddress(struct sockaddr_in &raddr) { + sockaddr_clear(&raddr); + return 0; +} + bool pqissltunnel::connect_parameter(uint32_t type, uint32_t value) { { diff --git a/libretroshare/src/pqi/pqissltunnel.h b/libretroshare/src/pqi/pqissltunnel.h index 6139bae63..88efd2edd 100644 --- a/libretroshare/src/pqi/pqissltunnel.h +++ b/libretroshare/src/pqi/pqissltunnel.h @@ -85,6 +85,7 @@ virtual int listen(); virtual int stoplistening(); virtual int reset(); virtual int disconnect(); +virtual int getConnectAddress(struct sockaddr_in &raddr); virtual bool connect_parameter(uint32_t type, uint32_t value); diff --git a/libretroshare/src/services/p3disc.cc b/libretroshare/src/services/p3disc.cc index 3d968e507..a4e996b51 100644 --- a/libretroshare/src/services/p3disc.cc +++ b/libretroshare/src/services/p3disc.cc @@ -710,6 +710,13 @@ void p3disc::recvPeerFriendMsg(RsDiscReply *item) mConnMgr->stunStatus(hashid1, item->currentsaddr, type, RS_STUN_FRIEND_OF_FRIEND); } + /* send Own Ip list to connect manager. It will extract the external ip address from it */ + if (peerId == mConnMgr->getOwnId()) + { + mConnMgr->setAddressList(mConnMgr->getOwnId(), item->ipAddressList); + } + + addDiscoveryData(item->PeerId(), peerId, item->currentladdr, item->currentsaddr, item->discFlags, time(NULL)); rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_NEIGHBOURS, NOTIFY_TYPE_MOD);