mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-28 18:42:20 -04:00
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
This commit is contained in:
parent
1e5a7a057c
commit
2485f9fffd
4 changed files with 172 additions and 6 deletions
|
@ -188,6 +188,30 @@ std::ostream& RsPrivateChatMsgConfigItem::print(std::ostream &out, uint16_t inde
|
||||||
printRsItemEnd(out, "RsPrivateChatMsgConfigItem", indent);
|
printRsItemEnd(out, "RsPrivateChatMsgConfigItem", indent);
|
||||||
return out;
|
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)
|
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;
|
uint16_t int_Indent = indent + 2;
|
||||||
printIndent(out, int_Indent);
|
printIndent(out, int_Indent);
|
||||||
out << "Status string: " << status_string << std::endl;
|
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);
|
printRsItemEnd(out, "RsChatStatusItem", indent);
|
||||||
return out;
|
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_DEFAULT: return new RsChatMsgItem(data,*pktsize) ;
|
||||||
case RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG: return new RsPrivateChatMsgConfigItem(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_STATUS: return new RsChatStatusItem(data,*pktsize) ;
|
||||||
case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(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) ;
|
case RS_PKT_SUBTYPE_CHAT_LOBBY_MSG: return new RsChatLobbyMsgItem(data,*pktsize) ;
|
||||||
|
@ -387,7 +412,18 @@ uint32_t RsPrivateChatMsgConfigItem::serial_size()
|
||||||
|
|
||||||
return s;
|
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 RsChatStatusItem::serial_size()
|
||||||
{
|
{
|
||||||
uint32_t s = 8; /* header */
|
uint32_t s = 8; /* header */
|
||||||
|
@ -780,7 +816,49 @@ bool RsPrivateChatMsgConfigItem::serialise(void *data, uint32_t& pktsize)
|
||||||
|
|
||||||
return ok;
|
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)
|
bool RsChatStatusItem::serialise(void *data, uint32_t& pktsize)
|
||||||
{
|
{
|
||||||
uint32_t tlvsize = serial_size() ;
|
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 &= GetTlvWideString(data, rssize, &offset, TLV_TYPE_WSTR_MSG, message);
|
||||||
ok &= getRawUInt32(data, rssize, &offset, &recvTime);
|
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
|
#ifdef CHAT_DEBUG
|
||||||
std::cerr << "Building new chat msg config item." << std::endl ;
|
std::cerr << "Building new chat msg config item." << std::endl ;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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_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_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_CHAT_LOBBY_LIST = 0x12 ;
|
||||||
|
const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ;
|
||||||
|
|
||||||
// for defining tags themselves and msg tags
|
// for defining tags themselves and msg tags
|
||||||
const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03;
|
const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03;
|
||||||
|
@ -314,6 +315,27 @@ class RsPrivateChatMsgConfigItem: public RsChatItem
|
||||||
std::wstring message;
|
std::wstring message;
|
||||||
uint32_t recvTime;
|
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.
|
// This class contains activity info for the sending peer: active, idle, typing, etc.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1736,6 +1736,24 @@ bool p3ChatService::loadList(std::list<RsItem*>& load)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RsPrivateChatDistantInviteConfigItem *ditem = NULL ;
|
||||||
|
|
||||||
|
if(NULL != (ditem = dynamic_cast<RsPrivateChatDistantInviteConfigItem *>(*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 ;
|
RsConfigKeyValueSet *vitem = NULL ;
|
||||||
|
|
||||||
if(NULL != (vitem = dynamic_cast<RsConfigKeyValueSet*>(*it)))
|
if(NULL != (vitem = dynamic_cast<RsConfigKeyValueSet*>(*it)))
|
||||||
|
@ -1799,6 +1817,21 @@ bool p3ChatService::saveList(bool& cleanup, std::list<RsItem*>& list)
|
||||||
list.push_back(ci);
|
list.push_back(ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* save ongoing distant chat invites */
|
||||||
|
|
||||||
|
for(std::map<TurtleFileHash,DistantChatInvite>::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 ;
|
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
|
||||||
RsTlvKeyValue kv;
|
RsTlvKeyValue kv;
|
||||||
kv.key = "DEFAULT_NICK_NAME" ;
|
kv.key = "DEFAULT_NICK_NAME" ;
|
||||||
|
@ -1833,10 +1866,14 @@ void p3ChatService::statusChange(const std::list<pqipeer> &plist)
|
||||||
for (it = plist.begin(); it != plist.end(); it++) {
|
for (it = plist.begin(); it != plist.end(); it++) {
|
||||||
if (it->state & RS_PEER_S_FRIEND) {
|
if (it->state & RS_PEER_S_FRIEND) {
|
||||||
if (it->actions & RS_PEER_CONNECTED) {
|
if (it->actions & RS_PEER_CONNECTED) {
|
||||||
|
|
||||||
/* send the saved outgoing messages */
|
/* send the saved outgoing messages */
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
if (privateOutgoingList.size()) {
|
std::vector<RsChatMsgItem*> to_send ;
|
||||||
|
|
||||||
|
if (privateOutgoingList.size())
|
||||||
|
{
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
std::string ownId = mLinkMgr->getOwnId();
|
std::string ownId = mLinkMgr->getOwnId();
|
||||||
|
@ -1848,7 +1885,7 @@ void p3ChatService::statusChange(const std::list<pqipeer> &plist)
|
||||||
if (c->PeerId() == it->id) {
|
if (c->PeerId() == it->id) {
|
||||||
mHistoryMgr->addMessage(false, c->PeerId(), ownId, c);
|
mHistoryMgr->addMessage(false, c->PeerId(), ownId, c);
|
||||||
|
|
||||||
checkSizeAndSendMessage_deprecated(c); // delete item
|
to_send.push_back(c) ;
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
|
@ -1861,6 +1898,9 @@ void p3ChatService::statusChange(const std::list<pqipeer> &plist)
|
||||||
}
|
}
|
||||||
} /* UNLOCKED */
|
} /* UNLOCKED */
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<to_send.size();++i)
|
||||||
|
checkSizeAndSendMessage_deprecated(to_send[i]); // delete item
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL);
|
rsicontrol->getNotify().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())
|
if(it == _distant_chat_invites.end())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
|
it->second.last_hit_time = time(NULL) ;
|
||||||
return true ;
|
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) ;
|
memcpy(info.aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||||
|
|
||||||
_distant_chat_peers[hash] = info ;
|
_distant_chat_peers[hash] = info ;
|
||||||
|
it->second.last_hit_time = now ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsicontrol->getNotify().notifyChatStatus(hash,"tunnel is up again!",true) ;
|
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 ;
|
DistantChatInvite invite ;
|
||||||
invite.time_of_validity = now + time_of_validity ;
|
invite.time_of_validity = now + time_of_validity ;
|
||||||
invite.time_of_creation = now ;
|
|
||||||
invite.last_hit_time = 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
|
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::string hash = SSLIdType(hash_bytes).toStdString(false) ;
|
||||||
|
|
||||||
std::cerr << "Created new distant chat invite: " << std::endl;
|
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 << " validity time stamp = " << invite.time_of_validity << std::endl;
|
||||||
std::cerr << " hash = " << hash << std::endl;
|
std::cerr << " hash = " << hash << std::endl;
|
||||||
std::cerr << " encryption key = " ;
|
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 ;
|
encrypted_radix64_string = invite.encrypted_radix64_string ;
|
||||||
std::cerr << "Encrypted radix64 string: " << invite.encrypted_radix64_string << std::endl;
|
std::cerr << "Encrypted radix64 string: " << invite.encrypted_radix64_string << std::endl;
|
||||||
|
|
||||||
|
IndicateConfigChanged();
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,6 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi
|
||||||
std::string encrypted_radix64_string ;
|
std::string encrypted_radix64_string ;
|
||||||
std::string destination_pgp_id ;
|
std::string destination_pgp_id ;
|
||||||
time_t time_of_validity ;
|
time_t time_of_validity ;
|
||||||
time_t time_of_creation ;
|
|
||||||
time_t last_hit_time ;
|
time_t last_hit_time ;
|
||||||
};
|
};
|
||||||
struct DistantChatPeerInfo
|
struct DistantChatPeerInfo
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue