diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index a3040125b..8875bfe9f 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -425,6 +425,8 @@ HEADERS += serialiser/rsbaseitems.h \ serialiser/rstlvutil.h \ serialiser/rstlvdsdv.h \ serialiser/rsdsdvitems.h \ + serialiser/rstlvbanlist.h \ + serialiser/rsbanlistitems.h \ serialiser/rstunnelitems.h HEADERS += services/p3channels.h \ @@ -438,6 +440,7 @@ HEADERS += services/p3channels.h \ services/p3service.h \ services/p3statusservice.h \ services/p3dsdv.h \ + services/p3banlist.h \ services/p3tunnel.h HEADERS += distrib/p3distrib.h \ @@ -561,6 +564,8 @@ SOURCES += serialiser/rsbaseitems.cc \ serialiser/rstlvutil.cc \ serialiser/rstlvdsdv.cc \ serialiser/rsdsdvitems.cc \ + serialiser/rstlvbanlist.cc \ + serialiser/rsbanlistitems.cc \ serialiser/rstunnelitems.cc SOURCES += services/p3channels.cc \ @@ -572,7 +577,8 @@ SOURCES += services/p3channels.cc \ services/p3photoservice.cc \ services/p3service.cc \ services/p3statusservice.cc \ - services/p3dsdv.cc + services/p3dsdv.cc \ + services/p3banlist.cc # removed because getPeer() doesn t exist services/p3tunnel.cc diff --git a/libretroshare/src/serialiser/rsbanlistitems.cc b/libretroshare/src/serialiser/rsbanlistitems.cc new file mode 100644 index 000000000..100b067f5 --- /dev/null +++ b/libretroshare/src/serialiser/rsbanlistitems.cc @@ -0,0 +1,203 @@ +/* + * libretroshare/src/serialiser: rsbanlist.cc + * + * RetroShare Serialiser. + * + * Copyright 2011 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 "serialiser/rsbaseserial.h" +#include "serialiser/rsbanlistitems.h" +#include "serialiser/rstlvbanlist.h" + +/*** +#define RSSERIAL_DEBUG 1 +***/ + +#include + +/*************************************************************************/ + +RsBanListItem::~RsBanListItem() +{ + return; +} + +void RsBanListItem::clear() +{ + peerList.TlvClear(); +} + +std::ostream &RsBanListItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsBanListItem", indent); + uint16_t int_Indent = indent + 2; + peerList.print(out, int_Indent); + + printRsItemEnd(out, "RsBanListItem", indent); + return out; +} + + +uint32_t RsBanListSerialiser::sizeList(RsBanListItem *item) +{ + uint32_t s = 8; /* header */ + s += item->peerList.TlvSize(); + + return s; +} + +/* serialise the data to the buffer */ +bool RsBanListSerialiser::serialiseList(RsBanListItem *item, void *data, uint32_t *pktsize) +{ + uint32_t tlvsize = sizeList(item); + uint32_t offset = 0; + + if (*pktsize < tlvsize) + return false; /* not enough space */ + + *pktsize = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsDsdvSerialiser::serialiseRoute() Header: " << ok << std::endl; + std::cerr << "RsDsdvSerialiser::serialiseRoute() Size: " << tlvsize << std::endl; +#endif + + /* skip the header */ + offset += 8; + + /* add mandatory parts first */ + ok &= item->peerList.SetTlv(data, tlvsize, &offset); + + if (offset != tlvsize) + { + ok = false; +#ifdef RSSERIAL_DEBUG + std::cerr << "RsDsdvSerialiser::serialiseRoute() Size Error! " << std::endl; +#endif + } + + return ok; +} + +RsBanListItem *RsBanListSerialiser::deserialiseList(void *data, uint32_t *pktsize) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t tlvsize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_BANLIST_ITEM != getRsItemSubType(rstype))) + { + return NULL; /* wrong type */ + } + + if (*pktsize < tlvsize) /* check size */ + return NULL; /* not enough data */ + + /* set the packet length */ + *pktsize = tlvsize; + + bool ok = true; + + /* ready to load */ + RsBanListItem *item = new RsBanListItem(); + item->clear(); + + /* skip the header */ + offset += 8; + + /* add mandatory parts first */ + ok &= item->peerList.GetTlv(data, tlvsize, &offset); + + if (offset != tlvsize) + { + /* error */ + delete item; + return NULL; + } + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + +/*************************************************************************/ + +uint32_t RsBanListSerialiser::size(RsItem *i) +{ + RsBanListItem *dri; + + if (NULL != (dri = dynamic_cast(i))) + { + return sizeList(dri); + } + return 0; +} + +bool RsBanListSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize) +{ + RsBanListItem *dri; + + if (NULL != (dri = dynamic_cast(i))) + { + return serialiseList(dri, data, pktsize); + } + return false; +} + +RsItem *RsBanListSerialiser::deserialise(void *data, uint32_t *pktsize) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + case RS_PKT_SUBTYPE_BANLIST_ITEM: + return deserialiseList(data, pktsize); + break; + default: + return NULL; + break; + } +} + +/*************************************************************************/ + + + diff --git a/libretroshare/src/serialiser/rsbanlistitems.h b/libretroshare/src/serialiser/rsbanlistitems.h new file mode 100644 index 000000000..b0480f5a4 --- /dev/null +++ b/libretroshare/src/serialiser/rsbanlistitems.h @@ -0,0 +1,82 @@ +#ifndef RS_BANLIST_ITEMS_H +#define RS_BANLIST_ITEMS_H + +/* + * libretroshare/src/serialiser: rsbanlistitems.h + * + * RetroShare Serialiser. + * + * Copyright 2011 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 + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" +#include "serialiser/rstlvbanlist.h" + +#define RS_PKT_SUBTYPE_BANLIST_ITEM 0x01 + +/**************************************************************************/ + +class RsBanListItem: public RsItem +{ + public: + RsBanListItem() + :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_BANLIST, + RS_PKT_SUBTYPE_BANLIST_ITEM) + { return; } +virtual ~RsBanListItem(); +virtual void clear(); +std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsTlvBanList peerList; + +}; + + +class RsBanListSerialiser: public RsSerialType +{ + public: + RsBanListSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_BANLIST) + { return; } +virtual ~RsBanListSerialiser() + { return; } + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + + private: + +virtual uint32_t sizeList(RsBanListItem *); +virtual bool serialiseList (RsBanListItem *item, void *data, uint32_t *size); +virtual RsBanListItem *deserialiseList(void *data, uint32_t *size); + + +}; + +/**************************************************************************/ + +#endif /* RS_BANLIST_ITEMS_H */ + + diff --git a/libretroshare/src/serialiser/rsserviceids.h b/libretroshare/src/serialiser/rsserviceids.h index 116f31879..5bbd10942 100644 --- a/libretroshare/src/serialiser/rsserviceids.h +++ b/libretroshare/src/serialiser/rsserviceids.h @@ -95,6 +95,9 @@ const uint16_t RS_SERVICE_TYPE_PHOTO = 0xf040; /* DSDV Testing at the moment - Service Only */ const uint16_t RS_SERVICE_TYPE_DSDV = 0xf050; +/* BanList Testing at the moment - Service Only */ +const uint16_t RS_SERVICE_TYPE_BANLIST = 0xf060; + /* Games/External Apps - Service Only */ const uint16_t RS_SERVICE_TYPE_GAME_LAUNCHER = 0xf200; const uint16_t RS_SERVICE_TYPE_PORT = 0xf201; diff --git a/libretroshare/src/serialiser/rstlvbanlist.cc b/libretroshare/src/serialiser/rstlvbanlist.cc new file mode 100644 index 000000000..95c9fd36c --- /dev/null +++ b/libretroshare/src/serialiser/rstlvbanlist.cc @@ -0,0 +1,309 @@ + +/* + * libretroshare/src/serialiser: rstlvtypes.cc + * + * RetroShare Serialiser. + * + * Copyright 2007-2008 by Robert Fernie, Chris Parker + * + * 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 "rstlvbanlist.h" + +#include "rstlvbase.h" +#include "rstlvtypes.h" +#include "rsbaseserial.h" +#include "util/rsprint.h" +#include +#include +#include +#include + + +/************************************* RsTlvBanListEntry ************************************/ + +RsTlvBanListEntry::RsTlvBanListEntry() + :RsTlvItem(), level(0), reason(0), age(0) +{ + return; +} + +void RsTlvBanListEntry::TlvClear() +{ + sockaddr_clear(&addr); + level = 0; + reason = 0; + age = 0; +} + +uint32_t RsTlvBanListEntry::TlvSize() +{ + uint32_t s = TLV_HEADER_SIZE; + + s += GetTlvIpAddrPortV4Size(); + s += 4; // level; + s += 4; // reason; + s += 4; // age; + + return s; + +} + +bool RsTlvBanListEntry::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint32_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + /* start at data[offset] */ + /* add mandatory parts first */ + + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_BAN_ENTRY, tlvsize); + + ok &= SetTlvIpAddrPortV4(data, tlvend, offset, TLV_TYPE_IPV4_REMOTE, &addr); + ok &= setRawUInt32(data, tlvend, offset, level); + ok &= setRawUInt32(data, tlvend, offset, reason); + ok &= setRawUInt32(data, tlvend, offset, age); + return ok; + +} + + +bool RsTlvBanListEntry::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + if (size < *offset + TLV_HEADER_SIZE) + return false; + + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_BAN_ENTRY) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += TLV_HEADER_SIZE; + + ok &= GetTlvIpAddrPortV4(data, tlvend, offset, TLV_TYPE_IPV4_REMOTE, &addr); + ok &= getRawUInt32(data, tlvend, offset, &(level)); + ok &= getRawUInt32(data, tlvend, offset, &(reason)); + ok &= getRawUInt32(data, tlvend, offset, &(age)); + + /*************************************************************************** + * NB: extra components could be added (for future expansion of the type). + * or be present (if this code is reading an extended version). + * + * We must chew up the extra characters to conform with TLV specifications + ***************************************************************************/ + if (*offset != tlvend) + { +#ifdef TLV_DEBUG + std::cerr << "RsTlvBanListEntry::GetTlv() Warning extra bytes at end of item"; + std::cerr << std::endl; +#endif + *offset = tlvend; + } + + return ok; + +} + + +std::ostream &RsTlvBanListEntry::print(std::ostream &out, uint16_t indent) +{ + printBase(out, "RsTlvBanListEntry", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "addr:" << rs_inet_ntoa(addr.sin_addr) << ":" << htons(addr.sin_port); + out << std::endl; + + printIndent(out, int_Indent); + out << "level:" << level; + out << std::endl; + + printIndent(out, int_Indent); + out << "reason:" << reason; + out << std::endl; + + printIndent(out, int_Indent); + out << "age:" << age; + out << std::endl; + + printEnd(out, "RsTlvBanListEntry", indent); + return out; +} + + +/************************************* RsTlvBanList ************************************/ + +void RsTlvBanList::TlvClear() +{ + entries.clear(); +} + +uint32_t RsTlvBanList::TlvSize() +{ + + uint32_t s = TLV_HEADER_SIZE; /* header */ + + std::list::iterator it; + + + if(!entries.empty()) + { + + for(it = entries.begin(); it != entries.end() ; ++it) + s += it->TlvSize(); + + } + + return s; +} + +bool RsTlvBanList::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + /* must check sizes */ + uint32_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + return false; /* not enough space */ + + bool ok = true; + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_BAN_LIST , tlvsize); + + if(!entries.empty()) + { + std::list::iterator it; + + for(it = entries.begin(); it != entries.end() ; ++it) + ok &= it->SetTlv(data, size, offset); + } + + + return ok; + +} + + +bool RsTlvBanList::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ +{ + if (size < *offset + TLV_HEADER_SIZE) + return false; + + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_BAN_LIST) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += TLV_HEADER_SIZE; + + /* while there is TLV */ + while((*offset) + 2 < tlvend) + { + /* get the next type */ + uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + + switch(tlvsubtype) + { + case TLV_TYPE_BAN_ENTRY: + { + RsTlvBanListEntry entry; + ok &= entry.GetTlv(data, size, offset); + if (ok) + { + entries.push_back(entry); + } + } + break; + default: + ok &= SkipUnknownTlv(data, tlvend, offset); + break; + + } + + if (!ok) + break; + } + + + + /*************************************************************************** + * NB: extra components could be added (for future expansion of the type). + * or be present (if this code is reading an extended version). + * + * We must chew up the extra characters to conform with TLV specifications + ***************************************************************************/ + if (*offset != tlvend) + { +#ifdef TLV_DEBUG + std::cerr << "RsTlvBanList::GetTlv() Warning extra bytes at end of item"; + std::cerr << std::endl; +#endif + *offset = tlvend; + } + + return ok; +} + +// prints out contents of RsTlvBanList +std::ostream &RsTlvBanList::print(std::ostream &out, uint16_t indent) +{ + printBase(out, "RsTlvBanList", indent); + uint16_t int_Indent = indent + 2; + + std::list::iterator it; + for(it = entries.begin(); it != entries.end() ; ++it) + it->print(out, int_Indent); + + printEnd(out, "RsTlvBanList", indent); + return out; +} + + +/************************************* RsTlvBanList ************************************/ + + diff --git a/libretroshare/src/serialiser/rstlvbanlist.h b/libretroshare/src/serialiser/rstlvbanlist.h new file mode 100644 index 000000000..51695f919 --- /dev/null +++ b/libretroshare/src/serialiser/rstlvbanlist.h @@ -0,0 +1,72 @@ +#ifndef RS_TLV_BANLIST_TYPES_H +#define RS_TLV_BANLIST_TYPES_H + +/* + * libretroshare/src/serialiser: rstlvbanlist.h + * + * RetroShare Serialiser. + * + * Copyright 2011 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". + * + */ + +/******************************************************************* + * These are the Compound TLV structures that must be (un)packed. + ******************************************************************/ + +#include +#include "serialiser/rstlvtypes.h" +#include "util/rsnet.h" + +#define RSDSDV_MAX_ROUTE_TABLE 1000 + +class RsTlvBanListEntry: public RsTlvItem +{ + public: + RsTlvBanListEntry(); +virtual ~RsTlvBanListEntry() { return; } +virtual uint32_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + struct sockaddr_in addr; + uint32_t level; + uint32_t reason; + uint32_t age; +}; + +class RsTlvBanList: public RsTlvItem +{ + public: + RsTlvBanList(); +virtual ~RsTlvBanList() { return; } +virtual uint32_t TlvSize(); +virtual void TlvClear(); +virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ +virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ +virtual std::ostream &print(std::ostream &out, uint16_t indent); + + std::list entries; +}; + + +#endif + diff --git a/libretroshare/src/serialiser/rstlvbase.h b/libretroshare/src/serialiser/rstlvbase.h index c99280911..691495956 100644 --- a/libretroshare/src/serialiser/rstlvbase.h +++ b/libretroshare/src/serialiser/rstlvbase.h @@ -216,7 +216,8 @@ const uint16_t TLV_TYPE_DSDV_ENDPOINT = 0x1080; const uint16_t TLV_TYPE_DSDV_ENTRY = 0x1081; const uint16_t TLV_TYPE_DSDV_ENTRY_SET= 0x1082; - +const uint16_t TLV_TYPE_BAN_ENTRY = 0x1090; +const uint16_t TLV_TYPE_BAN_LIST = 0x1091; const uint32_t RSTLV_IMAGE_TYPE_PNG = 0x0001; diff --git a/libretroshare/src/services/p3banlist.cc b/libretroshare/src/services/p3banlist.cc new file mode 100644 index 000000000..5ac5e5540 --- /dev/null +++ b/libretroshare/src/services/p3banlist.cc @@ -0,0 +1,382 @@ +/* + * libretroshare/src/services p3banlist.cc + * + * Ban List Service for RetroShare. + * + * Copyright 2011-2011 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/p3linkmgr.h" +#include "pqi/p3netmgr.h" + +#include "util/rsnet.h" + +#include "services/p3banlist.h" +#include "serialiser/rsbanlistitems.h" + +#include + +/**** + * #define DEBUG_BANLIST 1 + ****/ + + +/* DEFINE INTERFACE POINTER! */ +//RsBanList *rsBanList = NULL; + +#define RSBANLIST_ENTRY_MAX_AGE (60 * 60 * 1) // 1 HOURS +#define RSBANLIST_SEND_PERIOD 600 // 10 Minutes. + +#define RSBANLIST_SOURCE_SELF 0 +#define RSBANLIST_SOURCE_FRIEND 1 +#define RSBANLIST_SOURCE_FOF 2 + + +/************ IMPLEMENTATION NOTES ********************************* + * + * Get Bad Peers passed to us (from DHT mainly). + * we distribute and track the network list of bad peers. + * + */ + + +p3BanList::p3BanList(p3LinkMgr *lm, p3NetMgr *nm) + :p3Service(RS_SERVICE_TYPE_BANLIST), mBanMtx("p3BanList"), mLinkMgr(lm), mNetMgr(nm) +{ + addSerialType(new RsBanListSerialiser()); + + mSentListTime = 0; +} + + +int p3BanList::tick() +{ + processIncoming(); + sendPackets(); + + return 0; +} + +int p3BanList::status() +{ + return 1; +} + + +/***** Implementation ******/ + +bool p3BanList::processIncoming() +{ + /* for each packet - pass to specific handler */ + RsItem *item = NULL; + bool updated = false; + while(NULL != (item = recvItem())) + { + switch(item->PacketSubType()) + { + default: + break; + case RS_PKT_SUBTYPE_BANLIST_ITEM: + { + updated = (updated || recvBanItem((RsBanListItem *) item)); + } + break; + } + + /* clean up */ + delete item; + } + + if (updated) + { + { + RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + + mBanSet.clear(); + condenseBanSources_locked(); + } + + /* pass list to NetAssist */ + + } + + return true ; +} + + +bool p3BanList::recvBanItem(RsBanListItem *item) +{ + bool updated = false; + + std::list::const_iterator it; + for(it = item->peerList.entries.begin(); it != item->peerList.entries.end(); it++) + { + updated = (updated || addBanEntry(item->PeerId(), + it->addr, it->level, it->reason, it->age)); + } + return updated; +} + +bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in &addr, uint32_t level, uint32_t reason, uint32_t age) +{ + RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + + time_t now = time(NULL); + bool updated = false; + + std::map::iterator it; + it = mBanSources.find(peerId); + if (it == mBanSources.end()) + { + BanList bl; + bl.mPeerId = peerId; + bl.mLastUpdate = 0; + mBanSources[peerId] = bl; + + it = mBanSources.find(peerId); + updated = true; + } + + std::map::iterator mit; + mit = it->second.mBanPeers.find(addr.sin_addr.s_addr); + if (mit == it->second.mBanPeers.end()) + { + /* add in */ + BanListPeer blp; + blp.addr = addr; + blp.reason = reason; + blp.level = level; + blp.mTs = now - age; + updated = true; + } + else + { + /* see if it needs an update */ + if ((mit->second.reason != reason) || + (mit->second.level != level) || + (mit->second.mTs < now - age)) + { + /* update */ + mit->second.addr = addr; + mit->second.reason = reason; + mit->second.level = level; + mit->second.mTs = now - age; + updated = true; + } + } + return updated; +} + + +int p3BanList::condenseBanSources_locked() +{ + time_t now = time(NULL); + std::string ownId = mLinkMgr->getOwnId(); + + std::map::const_iterator it; + for(it = mBanSources.begin(); it != mBanSources.end(); it++) + { + if (now - it->second.mLastUpdate > RSBANLIST_ENTRY_MAX_AGE) + { + continue; + } + + std::map::const_iterator lit; + for(lit = it->second.mBanPeers.begin(); + lit != it->second.mBanPeers.end(); lit++) + { + /* check timestamp */ + if (now - lit->second.mTs > RSBANLIST_ENTRY_MAX_AGE) + { + continue; + } + + int lvl = lit->second.level; + if (it->first != ownId) + { + /* as from someone else, increment level */ + lvl++; + } + + /* check if it exists in the Set already */ + std::map::iterator sit; + sit = mBanSet.find(lit->second.addr.sin_addr.s_addr); + if ((sit == mBanSet.end()) || (lvl < sit->second.level)) + { + BanListPeer bp = lit->second; + bp.level = lvl; + bp.addr.sin_port = 0; + mBanSet[lit->second.addr.sin_addr.s_addr] = bp; + } + else + { + /* update if necessary */ + if (lvl == sit->second.level) + { + sit->second.reason |= lit->second.reason; + if (sit->second.mTs < lit->second.mTs) + { + sit->second.mTs = lit->second.mTs; + } + } + } + } + } +} + + + +int p3BanList::sendPackets() +{ + time_t now = time(NULL); + time_t pt; + { + RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + pt = mSentListTime; + } + + if (now - pt > RSBANLIST_SEND_PERIOD) + { + sendBanLists(); + printBanSources(std::cerr); + printBanSet(std::cerr); + + RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + mSentListTime = now; + } + return true ; +} + +void p3BanList::sendBanLists() +{ + + /* we ping our peers */ + /* who is online? */ + std::list idList; + + mLinkMgr->getOnlineList(idList); + +#ifdef DEBUG_BANLIST + std::cerr << "p3BanList::sendBanList()"; + std::cerr << std::endl; +#endif + + /* prepare packets */ + std::list::iterator it; + for(it = idList.begin(); it != idList.end(); it++) + { +#ifdef DEBUG_BANLIST + std::cerr << "p3VoRS::sendBanList() To: " << *it; + std::cerr << std::endl; +#endif + sendBanSet(*it); + } +} + + + +int p3BanList::sendBanSet(std::string peerid) +{ + /* */ + RsBanListItem *item = new RsBanListItem(); + item->PeerId(peerid); + + time_t now = time(NULL); + + { + RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + std::map::iterator it; + for(it = mBanSet.begin(); it != mBanSet.end(); it++) + { + if (it->second.level > RSBANLIST_SOURCE_FRIEND) + { + continue; // only share OWN and FRIENDS. + } + + RsTlvBanListEntry bi; + bi.addr = it->second.addr; + bi.reason = it->second.reason; + bi.level = it->second.level; + bi.age = now - it->second.mTs; + + item->peerList.entries.push_back(bi); + } + } + + sendItem(item); + return 1; +} + + +int p3BanList::printBanSet(std::ostream &out) +{ + RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + + out << "p3BanList::printBanSet"; + out << std::endl; + + time_t now = time(NULL); + + std::map::iterator it; + for(it = mBanSet.begin(); it != mBanSet.end(); it++) + { + out << "Ban: " << rs_inet_ntoa(it->second.addr.sin_addr); + out << " Reason: " << it->second.reason; + out << " Level: " << it->second.level; + if (it->second.level > RSBANLIST_SOURCE_FRIEND) + { + out << " (unused)"; + } + + out << " Age: " << now - it->second.mTs; + out << std::endl; + } +} + + + +int p3BanList::printBanSources(std::ostream &out) +{ + RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + + time_t now = time(NULL); + + std::map::const_iterator it; + for(it = mBanSources.begin(); it != mBanSources.end(); it++) + { + out << "BanList from: " << it->first; + out << " LastUpdate: " << now - it->second.mLastUpdate; + out << std::endl; + + std::map::const_iterator lit; + for(lit = it->second.mBanPeers.begin(); + lit != it->second.mBanPeers.end(); lit++) + { + out << "\t"; + out << "Ban: " << rs_inet_ntoa(lit->second.addr.sin_addr); + out << " Reason: " << lit->second.reason; + out << " Level: " << lit->second.level; + out << " Age: " << now - lit->second.mTs; + out << std::endl; + } + } +} + + diff --git a/libretroshare/src/services/p3banlist.h b/libretroshare/src/services/p3banlist.h new file mode 100644 index 000000000..a804a4566 --- /dev/null +++ b/libretroshare/src/services/p3banlist.h @@ -0,0 +1,129 @@ +/* + * libretroshare/src/services/p3banlist.h + * + * Exchange list of Peers for Banning / Whitelisting. + * + * Copyright 2011 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". + * + */ + + +#ifndef SERVICE_RSBANLIST_HEADER +#define SERVICE_RSBANLIST_HEADER + +#include +#include +#include + +#include "serialiser/rsbanlistitems.h" +#include "services/p3service.h" +//#include "retroshare/rsbanlist.h" + +class p3LinkMgr; +class p3NetMgr; + +class BanListPeer +{ + public: + + struct sockaddr_in addr; + uint32_t reason; // Dup Self, Dup Friend + int level; // LOCAL, FRIEND, FoF. + time_t mTs; +}; + +class BanList +{ + public: + + std::string mPeerId; /* from */ + time_t mLastUpdate; + std::map mBanPeers; +}; + + + +//!The RS BanList service. + /** + * + * Exchange list of Banned IP addresses with peers. + */ + +class p3BanList: /* public RsBanList, */ public p3Service /* , public p3Config, public pqiMonitor */ +{ + public: + p3BanList(p3LinkMgr *lm, p3NetMgr *nm); + + /***** overloaded from RsBanList *****/ + + /***** overloaded from p3Service *****/ + /*! + * This retrieves all chat msg items and also (important!) + * processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned + * (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status + * : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar + * @see NotifyBase + + */ + virtual int tick(); + virtual int status(); + + int sendPackets(); + bool processIncoming(); + + bool recvBanItem(RsBanListItem *item); + bool addBanEntry(const std::string &peerId, const struct sockaddr_in &addr, + uint32_t level, uint32_t reason, uint32_t age); + void sendBanLists(); + int sendBanSet(std::string peerid); + + int printBanSources(std::ostream &out); + int printBanSet(std::ostream &out); + + /*! + * Interface stuff. + */ + + /*************** pqiMonitor callback ***********************/ + //virtual void statusChange(const std::list &plist); + + + /************* from p3Config *******************/ + //virtual RsSerialiser *setupSerialiser() ; + //virtual bool saveList(bool& cleanup, std::list&) ; + //virtual void saveDone(); + //virtual bool loadList(std::list& load) ; + + + private: + RsMutex mBanMtx; + + int condenseBanSources_locked(); + + time_t mSentListTime; + std::map mBanSources; + std::map mBanSet; + + p3LinkMgr *mLinkMgr; + p3NetMgr *mNetMgr; + +}; + +#endif // SERVICE_RSBANLIST_HEADER +