From 3575f12240a9bdf7fb93ea96ea35247a49434673 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 4 Jul 2010 10:15:56 +0000 Subject: [PATCH] Network REWORK * Added separate classes to handle IpAddress History. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3245 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/pqi/pqiipset.cc | 268 ++++++++++++++++++++++++++++++ libretroshare/src/pqi/pqiipset.h | 74 +++++++++ 2 files changed, 342 insertions(+) create mode 100644 libretroshare/src/pqi/pqiipset.cc create mode 100644 libretroshare/src/pqi/pqiipset.h diff --git a/libretroshare/src/pqi/pqiipset.cc b/libretroshare/src/pqi/pqiipset.cc new file mode 100644 index 000000000..3118601c9 --- /dev/null +++ b/libretroshare/src/pqi/pqiipset.cc @@ -0,0 +1,268 @@ +/* + * libretroshare/src/pqi: pqiipset.cc + * + * 3P/PQI network interface for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "pqi/pqiipset.h" + +bool pqiIpAddress::sameAddress(const pqiIpAddress &a) const +{ + return ((mAddr.sin_addr.s_addr == a.mAddr.sin_addr.s_addr) && + (mAddr.sin_port == a.mAddr.sin_port)); +} + + +bool pqiIpAddress::validAddress() const +{ + /* filter for unlikely addresses */ + if(isLoopbackNet(&(mAddr.sin_addr))) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddress::validAddress() ip parameter is loopback: disgarding." << std::endl ; +#endif + return false; + } + + if(mAddr.sin_addr.s_addr == 0 || mAddr.sin_addr.s_addr == 1 || mAddr.sin_port == 0) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddress::validAddress() ip parameter is 0.0.0.0/1, or port is 0, ignoring." << std::endl; +#endif + return false; + } + + return true; + +} + + +bool pqiIpAddrList::updateIpAddressList(const pqiIpAddress &addr) +{ + std::list::iterator it; + bool add = false; + bool newAddr = true; + +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList()"; + std::cerr << std::endl; +#endif + + if (mAddrs.size() < MAX_ADDRESS_LIST_SIZE) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() small list: Add"; + std::cerr << std::endl; +#endif + add = true; + } + else if (mAddrs.begin()->mSeenTime < addr.mSeenTime) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() oldAddr: Add"; + std::cerr << std::endl; +#endif + add = true; + } + + if ((!add) || (!addr.validAddress())) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() not Add or !valid.. fail"; + std::cerr << std::endl; +#endif + return false; + } + + for(it = mAddrs.begin(); it != mAddrs.end(); it++) + { + if (it->sameAddress(addr)) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() found duplicate"; + std::cerr << std::endl; +#endif + if (it->mSeenTime > addr.mSeenTime) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() orig better, returning"; + std::cerr << std::endl; +#endif + /* already better -> quit */ + return false; + } + +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() deleting orig"; + std::cerr << std::endl; +#endif + it = mAddrs.erase(it); + newAddr = false; + break; + } + } + + // ordered by increasing time. (oldest at front) + bool added = false; + for(it = mAddrs.begin(); it != mAddrs.end(); it++) + { + if (it->mSeenTime > addr.mSeenTime) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() added orig SeenTime: " << it->mSeenTime << " new SeenTime: " << addr.mSeenTime; + std::cerr << std::endl; +#endif + + added = true; + mAddrs.insert(it, addr); + break; + } + } + if (!added) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() pushing to back"; + std::cerr << std::endl; +#endif + mAddrs.push_back(addr); + } + + /* pop if necessary */ + if (mAddrs.size() > MAX_ADDRESS_LIST_SIZE) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrList::updateIpAddressList() popping front"; + std::cerr << std::endl; +#endif + mAddrs.pop_front(); + } + + return newAddr; +} + +void pqiIpAddrList::extractFromTlv(const RsTlvIpAddrSet &tlvAddrs) +{ + std::list::const_iterator it; + + for(it = tlvAddrs.addrs.begin(); it != tlvAddrs.addrs.end() ; ++it) + { + pqiIpAddress addr; + addr.mAddr = it->addr; + addr.mSeenTime = it->seenTime; + addr.mSrc = it->source; + + mAddrs.push_back(addr); + } +} + +void pqiIpAddrList::loadTlv(RsTlvIpAddrSet &tlvAddrs) +{ + std::list::iterator it; + + for(it = mAddrs.begin(); it != mAddrs.end() ; ++it) + { + RsTlvIpAddressInfo addr; + addr.addr = it->mAddr; + addr.seenTime = it->mSeenTime; + addr.source = it->mSrc; + + tlvAddrs.addrs.push_back(addr); + } +} + + + +void pqiIpAddrList::printIpAddressList(std::ostream &out) const +{ + std::list::const_iterator it; + time_t now = time(NULL); + for(it = mAddrs.begin(); it != mAddrs.end(); it++) + { + out << inet_ntoa(it->mAddr.sin_addr) << ":" + << ntohs(it->mAddr.sin_port) << " ( " + << now - it->mSeenTime << " old) " << std::endl; + + } + return; +} + + +bool pqiIpAddrSet::updateLocalAddrs(const pqiIpAddress &addr) +{ + return mLocal.updateIpAddressList(addr); +} + +bool pqiIpAddrSet::updateExtAddrs(const pqiIpAddress &addr) +{ + return mLocal.updateIpAddressList(addr); +} + +bool pqiIpAddrSet::updateAddrs(const pqiIpAddrSet &addrs) +{ +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrSet::updateAddrs()"; + std::cerr << std::endl; +#endif + + bool newAddrs = false; + std::list::const_iterator it; + for(it = addrs.mLocal.mAddrs.begin(); it != addrs.mLocal.mAddrs.end(); it++) + { + if (mLocal.updateIpAddressList(*it)) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrSet::updateAddrs() Updated Local Addr"; + std::cerr << std::endl; +#endif + newAddrs = true; + } + } + + for(it = addrs.mExt.mAddrs.begin(); it != addrs.mExt.mAddrs.end(); it++) + { + if (mExt.updateIpAddressList(*it)) + { +#ifdef IPADDR_DEBUG + std::cerr << "pqiIpAddrSet::updateAddrs() Updated Ext Addr"; + std::cerr << std::endl; +#endif + newAddrs = true; + } + } + return newAddrs; +} + + + +void pqiIpAddrSet::printAddrs(std::ostream &out) const +{ + out << "Local Addresses: "; + mLocal.printIpAddressList(out); + out << std::endl; + out << "Ext Addresses: "; + mExt.printIpAddressList(out); + out << std::endl; +} + + + + diff --git a/libretroshare/src/pqi/pqiipset.h b/libretroshare/src/pqi/pqiipset.h new file mode 100644 index 000000000..54a50ea1f --- /dev/null +++ b/libretroshare/src/pqi/pqiipset.h @@ -0,0 +1,74 @@ +#ifndef PQI_IP_SET_H +#define PQI_IP_SET_H + +/* + * libretroshare/src/pqi: pqiipset.h + * + * 3P/PQI network interface for RetroShare. + * + * Copyright 2009-2010 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "util/rsnet.h" +#include "serialiser/rstlvaddrs.h" + +#define MAX_ADDRESS_LIST_SIZE 4 + +class pqiIpAddress +{ + public: + bool sameAddress(const pqiIpAddress &a) const; + bool validAddress() const; + + struct sockaddr_in mAddr; + time_t mSeenTime; + uint32_t mSrc; +}; + + +class pqiIpAddrList +{ + public: + + // returns true if new address added. + bool updateIpAddressList(const pqiIpAddress &addr); + void printIpAddressList(std::ostream &out) const; + void extractFromTlv(const RsTlvIpAddrSet &tlvAddrs); + void loadTlv(RsTlvIpAddrSet &tlvAddrs); + + // sorted list... based on seen time. + std::list mAddrs; +}; + + +class pqiIpAddrSet +{ + public: + + bool updateLocalAddrs(const pqiIpAddress &addr); + bool updateExtAddrs(const pqiIpAddress &addr); + bool updateAddrs(const pqiIpAddrSet &addrs); + void printAddrs(std::ostream &out) const; + pqiIpAddrList mLocal; + pqiIpAddrList mExt; +}; + + +#endif