From 90d6ac66975c33af36be2a6aa6c20088d3ca41e5 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 28 Apr 2015 21:46:10 +0000 Subject: [PATCH] fixed memory leak and potential crash due to not copying items passed to config saving in messages. Added save/load for map between GRouter and Msg ids which fixes the never removed outgoing messages git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8184 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsmsgitems.cc | 143 ++++++++++++++++++++- libretroshare/src/serialiser/rsmsgitems.h | 26 +++- libretroshare/src/services/p3msgservice.cc | 28 ++-- 3 files changed, 185 insertions(+), 12 deletions(-) diff --git a/libretroshare/src/serialiser/rsmsgitems.cc b/libretroshare/src/serialiser/rsmsgitems.cc index 2cca75dd0..42635fb11 100644 --- a/libretroshare/src/serialiser/rsmsgitems.cc +++ b/libretroshare/src/serialiser/rsmsgitems.cc @@ -762,6 +762,144 @@ RsMsgSrcId* RsMsgSerialiser::deserialiseMsgSrcIdItem(void* data, uint32_t* pktsi /************************* end of definition of msgSrcId serialisation functions ************************/ +std::ostream& RsMsgGRouterMap::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsMsgGRouterMap", indent); + uint16_t int_Indent = indent + 2; + + for(std::map::const_iterator it(ongoing_msgs.begin());it!=ongoing_msgs.end();++it) + { + printIndent(out, int_Indent); + out << " " << std::hex << it->first << std::dec << " : " << it->second << std::endl; + } + + printRsItemEnd(out, "RsMsgGRouterMap", indent); + + return out; +} + +void RsMsgGRouterMap::clear() +{ + ongoing_msgs.clear() ; + + return; +} + +uint32_t RsMsgGRouterMap::serial_size(bool) +{ + uint32_t s = 8; /* header */ + + s += 4; // number of entries + s += (8+4)*ongoing_msgs.size(); // entries + + return s; +} + +bool RsMsgGRouterMap::serialise(void *data, uint32_t& pktsize,bool config) +{ + uint32_t tlvsize = serial_size( config) ; + uint32_t offset = 0; + + if (pktsize < tlvsize) + return false; /* not enough space */ + + pktsize = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsMsgSerialiser::serialiseMsgParentIdItem() Header: " << ok << std::endl; + std::cerr << "RsMsgSerialiser::serialiseMsgParentIdItem() Size: " << tlvsize << std::endl; +#endif + + /* skip the header */ + offset += 8; + + ok &= setRawUInt32(data, tlvsize, &offset, ongoing_msgs.size()); + + for(std::map::const_iterator it=ongoing_msgs.begin();ok && it!=ongoing_msgs.end();++it) + { + ok &= setRawUInt64(data, tlvsize, &offset, it->first); + ok &= setRawUInt32(data, tlvsize, &offset, it->second); + } + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsMsgSerialiser::serialiseMsgGRouterMap() Size Error! " << std::endl; + } + + return ok; +} + +RsMsgGRouterMap* RsMsgSerialiser::deserialiseMsgGRouterMap(void* data, uint32_t* pktsize) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_MSG != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_MSG_GROUTER_MAP != getRsItemSubType(rstype))) + { + return NULL; /* wrong type */ + } + + if (*pktsize < rssize) /* check size */ + return NULL; /* not enough data */ + + /* set the packet length */ + *pktsize = rssize; + + bool ok = true; + + /* ready to load */ + RsMsgGRouterMap *item = new RsMsgGRouterMap(); + item->clear(); + + /* skip the header */ + offset += 8; + + uint32_t s=0 ; + + /* get mandatory parts first */ + ok &= getRawUInt32(data, rssize, &offset, &s); + + for(uint32_t i=0;iongoing_msgs.insert(std::make_pair(routing_id,mid)) ; + } + + if (offset != rssize) + { + /* error */ + delete item; + return NULL; + } + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + +/************************* end of definition of msgGRouterMap serialisation functions ************************/ + + /************************************** Message ParentId **********************/ std::ostream& RsMsgParentId::print(std::ostream& out, uint16_t indent) @@ -922,7 +1060,10 @@ RsItem* RsMsgSerialiser::deserialise(void *data, uint32_t *pktsize) case RS_PKT_SUBTYPE_MSG_TAGS: return deserialiseMsgTagItem(data, pktsize); break; - default: + case RS_PKT_SUBTYPE_MSG_GROUTER_MAP: + return deserialiseMsgGRouterMap(data, pktsize); + break; + default: return NULL; break; } diff --git a/libretroshare/src/serialiser/rsmsgitems.h b/libretroshare/src/serialiser/rsmsgitems.h index 91a69050b..e32844f84 100644 --- a/libretroshare/src/serialiser/rsmsgitems.h +++ b/libretroshare/src/serialiser/rsmsgitems.h @@ -35,6 +35,7 @@ #include "serialiser/rstlvidset.h" #include "serialiser/rstlvfileitem.h" +#include "grouter/grouteritems.h" #if 0 #include "serialiser/rstlvtypes.h" @@ -45,10 +46,11 @@ // for defining tags themselves and msg tags const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03; -const uint8_t RS_PKT_SUBTYPE_MSG_TAGS = 0x04; -const uint8_t RS_PKT_SUBTYPE_MSG_SRC_TAG = 0x05; +const uint8_t RS_PKT_SUBTYPE_MSG_TAGS = 0x04; +const uint8_t RS_PKT_SUBTYPE_MSG_SRC_TAG = 0x05; const uint8_t RS_PKT_SUBTYPE_MSG_PARENT_TAG = 0x06; const uint8_t RS_PKT_SUBTYPE_MSG_INVITE = 0x07; +const uint8_t RS_PKT_SUBTYPE_MSG_GROUTER_MAP = 0x08; /**************************************************************************/ @@ -207,6 +209,23 @@ class RsPublicMsgInviteConfigItem : public RsMessageItem time_t time_stamp ; }; +class RsMsgGRouterMap : public RsMessageItem +{ + public: + RsMsgGRouterMap() : RsMessageItem(RS_PKT_SUBTYPE_MSG_GROUTER_MAP) {} + + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + virtual bool serialise(void *data,uint32_t& size,bool config) ; + virtual uint32_t serial_size(bool config) ; + + virtual ~RsMsgGRouterMap() {} + virtual void clear(); + + // ----------- Specific fields ------------- // + // + std::map ongoing_msgs ; +}; class RsMsgParentId : public RsMessageItem { @@ -234,7 +253,7 @@ class RsMsgSerialiser: public RsSerialType :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_MSG), m_bConfiguration (bConfiguration) {} RsMsgSerialiser(uint16_t type) - :RsSerialType(RS_PKT_VERSION_SERVICE, type), m_bConfiguration (false) {} + :RsSerialType(RS_PKT_VERSION_SERVICE, type), m_bConfiguration (false) {} virtual ~RsMsgSerialiser() {} @@ -256,6 +275,7 @@ class RsMsgSerialiser: public RsSerialType virtual RsMsgSrcId *deserialiseMsgSrcIdItem(void *data, uint32_t *size); virtual RsMsgParentId *deserialiseMsgParentIdItem(void *data, uint32_t *size); virtual RsPublicMsgInviteConfigItem *deserialisePublicMsgInviteConfigItem(void *data, uint32_t *size); + virtual RsMsgGRouterMap *deserialiseMsgGRouterMap(void *data, uint32_t *size); bool m_bConfiguration; // is set to true for saving configuration (enables serialising msgId) }; diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index e2c3154f7..34c922e3c 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -428,28 +428,33 @@ bool p3MsgService::saveList(bool& cleanup, std::list& itemList) MsgTagType stdTags; - cleanup = false; + cleanup = true; mMsgMtx.lock(); for(mit = imsg.begin(); mit != imsg.end(); ++mit) - itemList.push_back(mit->second); + itemList.push_back(new RsMsgItem(*mit->second)); for(lit = mSrcIds.begin(); lit != mSrcIds.end(); ++lit) - itemList.push_back(lit->second); + itemList.push_back(new RsMsgSrcId(*lit->second)); for(mit = msgOutgoing.begin(); mit != msgOutgoing.end(); ++mit) - itemList.push_back(mit->second) ; + itemList.push_back(new RsMsgItem(*mit->second)) ; for(mit2 = mTags.begin(); mit2 != mTags.end(); ++mit2) - itemList.push_back(mit2->second); + itemList.push_back(new RsMsgTagType(*mit2->second)); for(mit3 = mMsgTags.begin(); mit3 != mMsgTags.end(); ++mit3) - itemList.push_back(mit3->second); + itemList.push_back(new RsMsgTags(*mit3->second)); for(mit4 = mParentId.begin(); mit4 != mParentId.end(); ++mit4) - itemList.push_back(mit4->second); + itemList.push_back(new RsMsgParentId(*mit4->second)); + + RsMsgGRouterMap *grmap = new RsMsgGRouterMap ; + grmap->ongoing_msgs = _ongoing_messages ; + + itemList.push_back(grmap) ; RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; RsTlvKeyValue kv; @@ -526,6 +531,7 @@ bool p3MsgService::loadList(std::list& load) RsMsgTags* mti; RsMsgSrcId* msi; RsMsgParentId* msp; + RsMsgGRouterMap* grm; // RsPublicMsgInviteConfigItem* msv; std::list items; @@ -545,7 +551,13 @@ bool p3MsgService::loadList(std::list& load) mMsgUniqueId = mitem->msgId + 1; } items.push_back(mitem); - } + } + else if (NULL != (grm = dynamic_cast(*it))) + { + // merge. + for(std::map::const_iterator it(grm->ongoing_msgs.begin());it!=grm->ongoing_msgs.end();++it) + _ongoing_messages.insert(*it) ; + } else if(NULL != (mtt = dynamic_cast(*it))) { // delete standard tags as they are now save in config