From 2485f9fffd2475933ee11630c2f32b9e3395c312 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 22 Apr 2013 20:49:58 +0000 Subject: [PATCH] added saving of ongoing chat invite links. Fixed a deadlock git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-GenericTunneling@6327 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsmsgitems.cc | 106 +++++++++++++++++++- libretroshare/src/serialiser/rsmsgitems.h | 22 ++++ libretroshare/src/services/p3chatservice.cc | 49 ++++++++- libretroshare/src/services/p3chatservice.h | 1 - 4 files changed, 172 insertions(+), 6 deletions(-) diff --git a/libretroshare/src/serialiser/rsmsgitems.cc b/libretroshare/src/serialiser/rsmsgitems.cc index 0338eff9b..367dce2e2 100644 --- a/libretroshare/src/serialiser/rsmsgitems.cc +++ b/libretroshare/src/serialiser/rsmsgitems.cc @@ -188,6 +188,30 @@ std::ostream& RsPrivateChatMsgConfigItem::print(std::ostream &out, uint16_t inde printRsItemEnd(out, "RsPrivateChatMsgConfigItem", indent); return out; } +std::ostream& RsPrivateChatDistantInviteConfigItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsPrivateChatDistantInviteConfigItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "radix string: " << encrypted_radix64_string << std::endl; + + printIndent(out, int_Indent); + out << "hash: " << hash << std::endl; + + printIndent(out, int_Indent); + out << "destination pgp_id: " << destination_pgp_id << std::endl; + + printIndent(out, int_Indent); + out << "time of validity: " << time_of_validity << std::endl; + + printIndent(out, int_Indent); + out << "time of last hit: " << last_hit_time << std::endl; + + printRsItemEnd(out, "RsPrivateChatDistantInviteConfigItem", indent); + return out; +} + std::ostream& RsChatStatusItem::print(std::ostream &out, uint16_t indent) { @@ -195,7 +219,7 @@ std::ostream& RsChatStatusItem::print(std::ostream &out, uint16_t indent) uint16_t int_Indent = indent + 2; printIndent(out, int_Indent); out << "Status string: " << status_string << std::endl; - out << "Flags : " << (void*)flags << std::endl; + out << "Flags : " << std::hex << flags << std::dec << std::endl; printRsItemEnd(out, "RsChatStatusItem", indent); return out; @@ -245,6 +269,7 @@ RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize) { case RS_PKT_SUBTYPE_DEFAULT: return new RsChatMsgItem(data,*pktsize) ; case RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG: return new RsPrivateChatMsgConfigItem(data,*pktsize) ; + case RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG: return new RsPrivateChatDistantInviteConfigItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_STATUS: return new RsChatStatusItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_MSG: return new RsChatLobbyMsgItem(data,*pktsize) ; @@ -387,7 +412,18 @@ uint32_t RsPrivateChatMsgConfigItem::serial_size() return s; } +uint32_t RsPrivateChatDistantInviteConfigItem::serial_size() +{ + uint32_t s = 8; /* header */ + s += GetTlvStringSize(hash); + s += GetTlvStringSize(encrypted_radix64_string); + s += GetTlvStringSize(destination_pgp_id); + s += 16; /* aes_key */ + s += 4; /* time_of_validity */ + s += 4; /* last_hit_time */ + return s; +} uint32_t RsChatStatusItem::serial_size() { uint32_t s = 8; /* header */ @@ -780,7 +816,49 @@ bool RsPrivateChatMsgConfigItem::serialise(void *data, uint32_t& pktsize) return ok; } +bool RsPrivateChatDistantInviteConfigItem::serialise(void *data, uint32_t& pktsize) +{ + uint32_t tlvsize = serial_size() ; + uint32_t offset = 0; + if (pktsize < tlvsize) + return false; /* not enough space */ + + pktsize = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); + +#ifdef CHAT_DEBUG + std::cerr << "RsChatSerialiser::serialiseItem() Header: " << ok << std::endl; + std::cerr << "RsChatSerialiser::serialiseItem() Size: " << tlvsize << std::endl; +#endif + + /* skip the header */ + offset += 8; + + /* add mandatory parts first */ + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_KEY, hash); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, encrypted_radix64_string); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GPGID, destination_pgp_id); + + memcpy(&((unsigned char *)data)[offset],aes_key,16) ; + offset += 16 ; + + ok &= setRawUInt32(data, tlvsize, &offset, time_of_validity); + ok &= setRawUInt32(data, tlvsize, &offset, last_hit_time); + + if (offset != tlvsize) + { + ok = false; +#ifdef CHAT_DEBUG + std::cerr << "RsChatSerialiser::serialiseItem() Size Error! " << std::endl; +#endif + } + + return ok; +} bool RsChatStatusItem::serialise(void *data, uint32_t& pktsize) { uint32_t tlvsize = serial_size() ; @@ -1122,6 +1200,32 @@ RsPrivateChatMsgConfigItem::RsPrivateChatMsgConfigItem(void *data,uint32_t /*siz ok &= GetTlvWideString(data, rssize, &offset, TLV_TYPE_WSTR_MSG, message); ok &= getRawUInt32(data, rssize, &offset, &recvTime); +#ifdef CHAT_DEBUG + std::cerr << "Building new chat msg config item." << std::endl ; +#endif + if (offset != rssize) + std::cerr << "Size error while deserializing." << std::endl ; + if (!ok) + std::cerr << "Unknown error while deserializing." << std::endl ; +} +RsPrivateChatDistantInviteConfigItem::RsPrivateChatDistantInviteConfigItem(void *data,uint32_t /*size*/) + : RsChatItem(RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + /* get mandatory parts first */ + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_KEY, hash); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_LINK, encrypted_radix64_string); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_GPGID, destination_pgp_id); + + memcpy(aes_key,&((unsigned char*)data)[offset],16) ; + offset += 16 ; + + ok &= getRawUInt32(data, rssize, &offset, &time_of_validity); + ok &= getRawUInt32(data, rssize, &offset, &last_hit_time); + #ifdef CHAT_DEBUG std::cerr << "Building new chat msg config item." << std::endl ; #endif diff --git a/libretroshare/src/serialiser/rsmsgitems.h b/libretroshare/src/serialiser/rsmsgitems.h index 3b9b06c75..1e800c559 100644 --- a/libretroshare/src/serialiser/rsmsgitems.h +++ b/libretroshare/src/serialiser/rsmsgitems.h @@ -64,6 +64,7 @@ const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x0F ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT = 0x10 ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2 = 0x11 ; // to be removed (deprecated since 02 Dec. 2012) const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST = 0x12 ; +const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ; // for defining tags themselves and msg tags const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03; @@ -314,6 +315,27 @@ class RsPrivateChatMsgConfigItem: public RsChatItem std::wstring message; uint32_t recvTime; }; +class RsPrivateChatDistantInviteConfigItem: public RsChatItem +{ + public: + RsPrivateChatDistantInviteConfigItem() :RsChatItem(RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG) {} + RsPrivateChatDistantInviteConfigItem(void *data,uint32_t size) ; // deserialization + + virtual ~RsPrivateChatDistantInviteConfigItem() {} + virtual void clear() {} + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); + + virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? + virtual uint32_t serial_size() ; // deserialise is handled using a constructor + + unsigned char aes_key[16] ; + std::string hash ; + std::string encrypted_radix64_string ; + std::string destination_pgp_id ; + uint32_t time_of_validity ; + uint32_t last_hit_time ; +}; + // This class contains activity info for the sending peer: active, idle, typing, etc. // diff --git a/libretroshare/src/services/p3chatservice.cc b/libretroshare/src/services/p3chatservice.cc index 18c2c36f1..b4c0ce094 100644 --- a/libretroshare/src/services/p3chatservice.cc +++ b/libretroshare/src/services/p3chatservice.cc @@ -1736,6 +1736,24 @@ bool p3ChatService::loadList(std::list& load) continue; } + RsPrivateChatDistantInviteConfigItem *ditem = NULL ; + + if(NULL != (ditem = dynamic_cast(*it))) + { + DistantChatInvite invite ; + + memcpy(invite.aes_key,ditem->aes_key,DISTANT_CHAT_AES_KEY_SIZE) ; + invite.encrypted_radix64_string = ditem->encrypted_radix64_string ; + invite.destination_pgp_id = ditem->destination_pgp_id ; + invite.time_of_validity = ditem->time_of_validity ; + invite.last_hit_time = ditem->last_hit_time ; + + _distant_chat_invites[ditem->hash] = invite ; + + delete *it ; + continue ; + } + RsConfigKeyValueSet *vitem = NULL ; if(NULL != (vitem = dynamic_cast(*it))) @@ -1799,6 +1817,21 @@ bool p3ChatService::saveList(bool& cleanup, std::list& list) list.push_back(ci); } + /* save ongoing distant chat invites */ + + for(std::map::const_iterator it(_distant_chat_invites.begin());it!=_distant_chat_invites.end();++it) + { + RsPrivateChatDistantInviteConfigItem *ei = new RsPrivateChatDistantInviteConfigItem ; + ei->hash = it->first ; + memcpy(ei->aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ; + ei->encrypted_radix64_string = it->second.encrypted_radix64_string ; + ei->destination_pgp_id = it->second.destination_pgp_id ; + ei->time_of_validity = it->second.time_of_validity ; + ei->last_hit_time = it->second.last_hit_time ; + + list.push_back(ei) ; + } + RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; RsTlvKeyValue kv; kv.key = "DEFAULT_NICK_NAME" ; @@ -1833,10 +1866,14 @@ void p3ChatService::statusChange(const std::list &plist) for (it = plist.begin(); it != plist.end(); it++) { if (it->state & RS_PEER_S_FRIEND) { if (it->actions & RS_PEER_CONNECTED) { + /* send the saved outgoing messages */ bool changed = false; - if (privateOutgoingList.size()) { + std::vector to_send ; + + if (privateOutgoingList.size()) + { RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ std::string ownId = mLinkMgr->getOwnId(); @@ -1848,7 +1885,7 @@ void p3ChatService::statusChange(const std::list &plist) if (c->PeerId() == it->id) { mHistoryMgr->addMessage(false, c->PeerId(), ownId, c); - checkSizeAndSendMessage_deprecated(c); // delete item + to_send.push_back(c) ; changed = true; @@ -1861,6 +1898,9 @@ void p3ChatService::statusChange(const std::list &plist) } } /* UNLOCKED */ + for(uint32_t i=0;igetNotify().notifyListChange(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL); @@ -2809,6 +2849,7 @@ bool p3ChatService::handleTunnelRequest(const std::string& hash,const std::strin if(it == _distant_chat_invites.end()) return false ; + it->second.last_hit_time = time(NULL) ; return true ; } @@ -2859,6 +2900,7 @@ void p3ChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtua memcpy(info.aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ; _distant_chat_peers[hash] = info ; + it->second.last_hit_time = now ; } rsicontrol->getNotify().notifyChatStatus(hash,"tunnel is up again!",true) ; @@ -3061,7 +3103,6 @@ bool p3ChatService::createDistantChatInvite(const std::string& pgp_id,time_t tim DistantChatInvite invite ; invite.time_of_validity = now + time_of_validity ; - invite.time_of_creation = now ; invite.last_hit_time = now ; RAND_bytes( (unsigned char *)&invite.aes_key[0],DISTANT_CHAT_AES_KEY_SIZE ) ; // generate a random AES encryption key @@ -3074,7 +3115,6 @@ bool p3ChatService::createDistantChatInvite(const std::string& pgp_id,time_t tim std::string hash = SSLIdType(hash_bytes).toStdString(false) ; std::cerr << "Created new distant chat invite: " << std::endl; - std::cerr << " creation time stamp = " << invite.time_of_creation << std::endl; std::cerr << " validity time stamp = " << invite.time_of_validity << std::endl; std::cerr << " hash = " << hash << std::endl; std::cerr << " encryption key = " ; @@ -3132,6 +3172,7 @@ bool p3ChatService::createDistantChatInvite(const std::string& pgp_id,time_t tim encrypted_radix64_string = invite.encrypted_radix64_string ; std::cerr << "Encrypted radix64 string: " << invite.encrypted_radix64_string << std::endl; + IndicateConfigChanged(); return true ; } diff --git a/libretroshare/src/services/p3chatservice.h b/libretroshare/src/services/p3chatservice.h index 2a5fe2dab..666863334 100644 --- a/libretroshare/src/services/p3chatservice.h +++ b/libretroshare/src/services/p3chatservice.h @@ -322,7 +322,6 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi std::string encrypted_radix64_string ; std::string destination_pgp_id ; time_t time_of_validity ; - time_t time_of_creation ; time_t last_hit_time ; }; struct DistantChatPeerInfo