diff --git a/libretroshare/src/pqi/p3peermgr.cc b/libretroshare/src/pqi/p3peermgr.cc index b29e4fcd5..f6a509501 100644 --- a/libretroshare/src/pqi/p3peermgr.cc +++ b/libretroshare/src/pqi/p3peermgr.cc @@ -2000,9 +2000,6 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list& saveData) item->domain_addr = (it->second).hiddenDomain; item->domain_port = (it->second).hiddenPort; - item->maxUploadRate = it->second.maxUpRate ; - item->maxDownloadRate = it->second.maxDnRate ; - saveData.push_back(item); saveCleanupList.push_back(item); #ifdef PEER_DEBUG @@ -2012,6 +2009,10 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list& saveData) #endif } + RsPeerBandwidthLimitsItem *pblitem = new RsPeerBandwidthLimitsItem ; + pblitem->peers = mPeerBandwidthLimits ; + saveData.push_back(pblitem) ; + RsPeerServicePermissionItem *sitem = new RsPeerServicePermissionItem ; for(std::map::const_iterator it(mFriendsPermissionFlags.begin());it!=mFriendsPermissionFlags.end();++it) @@ -2077,18 +2078,28 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list& saveData) bool p3PeerMgrIMPL::getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn) { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ + RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - /* check if it is a friend */ - std::map::iterator it = mFriendList.find(pid) ; - - if(mFriendList.end() == it) - return false ; - - maxUp = it->second.maxUpRate ; - maxDn = it->second.maxDnRate ; - - return true ; + /* check if it is a friend */ + std::map::iterator it = mFriendList.find(pid) ; + + if(mFriendList.end() == it) + return false ; + + std::map::const_iterator it2 = mPeerBandwidthLimits.find(it->second.gpg_id) ; + + if(it2 != mPeerBandwidthLimits.end()) + { + maxUp = it2->second.max_up_rate_kbs ; + maxDn = it2->second.max_dl_rate_kbs ; + return true ; + } + else + { + maxUp = 0; + maxDn = 0; + return false ; + } } bool p3PeerMgrIMPL::setMaxRates(const RsPeerId& pid,uint32_t maxUp,uint32_t maxDn) { @@ -2186,9 +2197,6 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setLocation(pitem->peerId, pitem->location); } - // this is the external interface, but the - setMaxRates(pitem->peerId,pitem->maxUploadRate,pitem->maxDownloadRate) ; - if (pitem->netMode == RS_NET_MODE_HIDDEN) { /* set only the hidden stuff & localAddress */ @@ -2300,6 +2308,18 @@ bool p3PeerMgrIMPL::loadList(std::list& load) continue; } + + RsPeerBandwidthLimitsItem *pblitem = dynamic_cast(*it) ; + + if(pblitem) + { + RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ + +#ifdef PEER_DEBUG + std::cerr << "Loaded service permission item: " << std::endl; +#endif + mPeerBandwidthLimits = pblitem->peers ; + } RsPeerServicePermissionItem *sitem = dynamic_cast(*it) ; if(sitem) diff --git a/libretroshare/src/pqi/p3peermgr.h b/libretroshare/src/pqi/p3peermgr.h index 383514826..81496aa99 100644 --- a/libretroshare/src/pqi/p3peermgr.h +++ b/libretroshare/src/pqi/p3peermgr.h @@ -398,6 +398,7 @@ private: std::list saveCleanupList; /* TEMPORARY LIST WHEN SAVING */ std::map mFriendsPermissionFlags ; // permission flags for each gpg key + std::map mPeerBandwidthLimits ; // bandwidth limits for each gpg key struct sockaddr_storage mProxyServerAddressTor; struct sockaddr_storage mProxyServerAddressI2P; diff --git a/libretroshare/src/retroshare/rstypes.h b/libretroshare/src/retroshare/rstypes.h index 0ebd066ca..37975d605 100644 --- a/libretroshare/src/retroshare/rstypes.h +++ b/libretroshare/src/retroshare/rstypes.h @@ -118,6 +118,15 @@ class Condition std::string name; }; +class PeerBandwidthLimits +{ +public: + PeerBandwidthLimits() : max_up_rate_kbs(0), max_dl_rate_kbs(0) {} + + uint32_t max_up_rate_kbs ; + uint32_t max_dl_rate_kbs ; +}; + //class SearchRequest // unused stuff. //{ // public: diff --git a/libretroshare/src/serialiser/rsconfigitems.cc b/libretroshare/src/serialiser/rsconfigitems.cc index 2692774d5..1acebc4c7 100644 --- a/libretroshare/src/serialiser/rsconfigitems.cc +++ b/libretroshare/src/serialiser/rsconfigitems.cc @@ -879,11 +879,7 @@ uint32_t RsPeerConfigSerialiser::sizeNet(RsPeerNetItem *i) s += GetTlvStringSize(i->domain_addr); s += 2; /* domain_port */ - s += 4 ; // max upload rate - s += 4 ; // max dl rate - return s; - } bool RsPeerConfigSerialiser::serialiseNet(RsPeerNetItem *item, void *data, uint32_t *size) @@ -941,9 +937,6 @@ bool RsPeerConfigSerialiser::serialiseNet(RsPeerNetItem *item, void *data, uint3 ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_DOMADDR, item->domain_addr); ok &= setRawUInt16(data, tlvsize, &offset, item->domain_port); /* Mandatory */ - ok &= setRawUInt32(data, tlvsize, &offset, item->maxUploadRate); /* Mandatory */ - ok &= setRawUInt32(data, tlvsize, &offset, item->maxDownloadRate); /* Mandatory */ - if(offset != tlvsize) { #ifdef RSSERIAL_ERROR_DEBUG @@ -1021,12 +1014,6 @@ RsPeerNetItem *RsPeerConfigSerialiser::deserialiseNet(void *data, uint32_t *size ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_DOMADDR, item->domain_addr); ok &= getRawUInt16(data, rssize, &offset, &(item->domain_port)); /* Mandatory */ - if(offset == rssize) // this allows to load the peer list when max bandwidth rates are missing. - return item ; - - ok &= getRawUInt32(data, rssize, &offset, &(item->maxUploadRate)); /* Mandatory */ - ok &= getRawUInt32(data, rssize, &offset, &(item->maxDownloadRate)); /* Mandatory */ - if (offset != rssize) { #ifdef RSSERIAL_ERROR_DEBUG @@ -1040,6 +1027,160 @@ RsPeerNetItem *RsPeerConfigSerialiser::deserialiseNet(void *data, uint32_t *size return item; } +/****************************************************************************/ + +uint32_t RsPeerConfigSerialiser::sizePeerBandwidthLimits(RsPeerBandwidthLimitsItem *i) +{ + uint32_t s = 8; /* header */ + s += 4; // number of elements + s += i->peers.size() * (4 + 4 + RsPgpId::SIZE_IN_BYTES) ; + + return s; +} + +bool RsPeerConfigSerialiser::serialisePeerBandwidthLimits(RsPeerBandwidthLimitsItem *item, void *data, uint32_t *size) +{ + uint32_t tlvsize = RsPeerConfigSerialiser::sizePeerBandwidthLimits(item); + uint32_t offset = 0; + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsPeerConfigSerialiser::serialiseNet() tlvsize: " << tlvsize << std::endl; +#endif + + if(*size < tlvsize) + { +#ifdef RSSERIAL_ERROR_DEBUG + std::cerr << "RsPeerConfigSerialiser::serialiseNet() ERROR not enough space" << std::endl; +#endif + return false; /* not enough space */ + } + + *size = tlvsize; + + bool ok = true; + + // serialise header + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsPeerConfigSerialiser::serialiseNet() Header: " << ok << std::endl; + std::cerr << "RsPeerConfigSerialiser::serialiseNet() Header test: " << tlvsize << std::endl; +#endif + + /* skip the header */ + offset += 8; + + ok &= setRawUInt32(data, tlvsize, &offset, item->peers.size()); /* Mandatory */ + + for(std::map::const_iterator it(item->peers.begin());it!=item->peers.end();++it) + { + ok &= it->first.serialise(data,tlvsize,offset); + + ok &= setRawUInt32(data, tlvsize, &offset, it->second.max_up_rate_kbs); /* Mandatory */ + ok &= setRawUInt32(data, tlvsize, &offset, it->second.max_dl_rate_kbs); /* Mandatory */ + } + + if(offset != tlvsize) + { +#ifdef RSSERIAL_ERROR_DEBUG + std::cerr << "RsPeerConfigSerialiser::serialiseNet() Size Error! " << std::endl; +#endif + ok = false; + } + + return ok; + +} + +RsPeerBandwidthLimitsItem *RsPeerConfigSerialiser::deserialisePeerBandwidthLimits(void *data, uint32_t *size) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsPeerConfigSerialiser::deserialiseNet() rssize: " << rssize << std::endl; +#endif + + if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) || + (RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) || + (RS_PKT_TYPE_PEER_CONFIG != getRsItemType(rstype)) || + (RS_PKT_SUBTYPE_PEER_BANDLIMITS != getRsItemSubType(rstype))) + { +#ifdef RSSERIAL_ERROR_DEBUG + std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR Type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef RSSERIAL_ERROR_DEBUG + std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR not enough data" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsPeerBandwidthLimitsItem *item = new RsPeerBandwidthLimitsItem(); + + /* skip the header */ + offset += 8; + + /* get mandatory parts first */ + uint32_t n ; + ok &= getRawUInt32(data, rssize, &offset, &n) ; + + for(uint32_t i=0;ipeers[pgpid] = p ; + } + + if (offset != rssize) + { +#ifdef RSSERIAL_ERROR_DEBUG + std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + return item; +} + +std::ostream &RsPeerBandwidthLimitsItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsPeerBandwidthLimitsItem", indent); + uint16_t int_Indent = indent + 2; + + for(std::map::const_iterator it(peers.begin());it!=peers.end();++it) + { + printIndent(out, int_Indent); + out << it->first << " : " << it->second.max_up_rate_kbs << " (up) " << it->second.max_dl_rate_kbs << " (dn)" << std::endl; + } + + printRsItemEnd(out, "RsPeerStunItem", indent); + return out; +} + + + /****************************************************************************/ RsPeerStunItem::~RsPeerStunItem() diff --git a/libretroshare/src/serialiser/rsconfigitems.h b/libretroshare/src/serialiser/rsconfigitems.h index 6771ea4f2..0ad555274 100644 --- a/libretroshare/src/serialiser/rsconfigitems.h +++ b/libretroshare/src/serialiser/rsconfigitems.h @@ -54,6 +54,7 @@ const uint8_t RS_PKT_SUBTYPE_PEER_STUN = 0x02; const uint8_t RS_PKT_SUBTYPE_PEER_NET = 0x03; const uint8_t RS_PKT_SUBTYPE_PEER_GROUP = 0x04; const uint8_t RS_PKT_SUBTYPE_PEER_PERMISSIONS = 0x05; +const uint8_t RS_PKT_SUBTYPE_PEER_BANDLIMITS = 0x06; /* FILE CONFIG SUBTYPES */ const uint8_t RS_PKT_SUBTYPE_FILE_TRANSFER = 0x01; @@ -61,6 +62,8 @@ const uint8_t RS_PKT_SUBTYPE_FILE_ITEM = 0x02; /**************************************************************************/ +#warning should make these items use a clean serialise code, and all derive from the same item type. + class RsPeerNetItem: public RsItem { public: @@ -95,11 +98,9 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0); // for proxy connection. std::string domain_addr; uint16_t domain_port; - - uint32_t maxUploadRate ; - uint32_t maxDownloadRate ; }; +// This item should be merged with the next item, but that is not backward compatible. class RsPeerServicePermissionItem : public RsItem { public: @@ -117,7 +118,21 @@ class RsPeerServicePermissionItem : public RsItem std::vector pgp_ids ; std::vector service_flags ; }; +class RsPeerBandwidthLimitsItem : public RsItem +{ + public: + RsPeerBandwidthLimitsItem() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_PEER_BANDLIMITS) {} + virtual ~RsPeerBandwidthLimitsItem() {} + virtual void clear() + { + peers.clear() ; + } + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + /* Mandatory */ + std::map peers ; +}; class RsPeerGroupItem : public RsItem { @@ -186,6 +201,10 @@ virtual uint32_t sizeGroup(RsPeerGroupItem *); virtual bool serialiseGroup (RsPeerGroupItem *item, void *data, uint32_t *size); virtual RsPeerGroupItem * deserialiseGroup(void *data, uint32_t *size); +virtual uint32_t sizePeerBandwidthLimits(RsPeerBandwidthLimitsItem *); +virtual bool serialisePeerBandwidthLimits (RsPeerBandwidthLimitsItem *item, void *data, uint32_t *size); +virtual RsPeerBandwidthLimitsItem *deserialisePeerBandwidthLimits(void *data, uint32_t *size); + virtual uint32_t sizePermissions(RsPeerServicePermissionItem *); virtual bool serialisePermissions (RsPeerServicePermissionItem *item, void *data, uint32_t *size); virtual RsPeerServicePermissionItem * deserialisePermissions(void *data, uint32_t *size);