mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-08-06 13:24:16 -04:00
Fix for msg validation (error in key generation, public keys were not
created) , synchronisation was not broken incidentally. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs_sync-validate-fix@6071 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
890d7891c4
commit
8d89d0bc95
9 changed files with 106 additions and 59 deletions
|
@ -130,6 +130,10 @@ bool GxsSecurity::validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSe
|
||||||
RsTlvKeySignatureSet signSet = msgMeta.signSet;
|
RsTlvKeySignatureSet signSet = msgMeta.signSet;
|
||||||
msgMeta.signSet.TlvClear();
|
msgMeta.signSet.TlvClear();
|
||||||
|
|
||||||
|
RsGxsMessageId msgId = msgMeta.mMsgId, origMsgId = msgMeta.mOrigMsgId;
|
||||||
|
msgMeta.mOrigMsgId.clear();
|
||||||
|
msgMeta.mMsgId.clear();
|
||||||
|
|
||||||
uint32_t metaDataLen = msgMeta.serial_size();
|
uint32_t metaDataLen = msgMeta.serial_size();
|
||||||
uint32_t allMsgDataLen = metaDataLen + msg.msg.bin_len;
|
uint32_t allMsgDataLen = metaDataLen + msg.msg.bin_len;
|
||||||
char* metaData = new char[metaDataLen];
|
char* metaData = new char[metaDataLen];
|
||||||
|
@ -156,6 +160,8 @@ bool GxsSecurity::validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSe
|
||||||
EVP_PKEY_free(signKey);
|
EVP_PKEY_free(signKey);
|
||||||
EVP_MD_CTX_destroy(mdctx);
|
EVP_MD_CTX_destroy(mdctx);
|
||||||
|
|
||||||
|
msgMeta.mOrigMsgId = origMsgId;
|
||||||
|
msgMeta.mMsgId = msgId;
|
||||||
|
|
||||||
if (signOk == 1)
|
if (signOk == 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -969,6 +969,7 @@ int RsDataService::resetDataStore()
|
||||||
std::string msgFile = file + "-msgs";
|
std::string msgFile = file + "-msgs";
|
||||||
remove(file.c_str()); // remove group file
|
remove(file.c_str()); // remove group file
|
||||||
remove(msgFile.c_str()); // and remove messages file
|
remove(msgFile.c_str()); // and remove messages file
|
||||||
|
delete mit->second;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mDbMutex);
|
RsStackMutex stack(mDbMutex);
|
||||||
|
|
|
@ -174,6 +174,8 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPubli
|
||||||
GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub);
|
GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub);
|
||||||
GxsSecurity::setRSAPrivateKey(privAdminKey, rsa_admin);
|
GxsSecurity::setRSAPrivateKey(privAdminKey, rsa_admin);
|
||||||
|
|
||||||
|
adminKey.keyId = adminKey.keyId + "_public";
|
||||||
|
|
||||||
adminKey.startTS = time(NULL);
|
adminKey.startTS = time(NULL);
|
||||||
adminKey.endTS = 0; /* no end */
|
adminKey.endTS = 0; /* no end */
|
||||||
|
|
||||||
|
@ -204,6 +206,7 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPubli
|
||||||
GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish);
|
GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish);
|
||||||
|
|
||||||
pubKey.startTS = adminKey.startTS;
|
pubKey.startTS = adminKey.startTS;
|
||||||
|
pubKey.keyId = pubKey.keyId + "_public";
|
||||||
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
|
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
|
||||||
|
|
||||||
privPubKey.startTS = adminKey.startTS;
|
privPubKey.startTS = adminKey.startTS;
|
||||||
|
@ -219,7 +222,6 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPubli
|
||||||
RSA_free(rsa_publish);
|
RSA_free(rsa_publish);
|
||||||
RSA_free(rsa_publish_pub);
|
RSA_free(rsa_publish_pub);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
|
bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
|
||||||
|
@ -241,14 +243,14 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
|
||||||
RsTlvSecurityKey& key = mit->second;
|
RsTlvSecurityKey& key = mit->second;
|
||||||
|
|
||||||
// add public admin key
|
// add public admin key
|
||||||
if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY))
|
if((key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (key.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY))
|
||||||
meta->keys.keys.insert(std::make_pair(key.keyId, key));
|
meta->keys.keys.insert(std::make_pair(key.keyId, key));
|
||||||
|
|
||||||
// add public publish key
|
// add public publish key
|
||||||
if(key.keyFlags & (RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY))
|
if((key.keyFlags & RSTLV_KEY_DISTRIB_PUBLIC) && (key.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY))
|
||||||
meta->keys.keys.insert(std::make_pair(key.keyId, key));
|
meta->keys.keys.insert(std::make_pair(key.keyId, key));
|
||||||
|
|
||||||
if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
|
if((key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (key.keyFlags & RSTLV_KEY_TYPE_FULL))
|
||||||
{
|
{
|
||||||
privAdminKey = key;
|
privAdminKey = key;
|
||||||
privKeyFound = true;
|
privKeyFound = true;
|
||||||
|
@ -606,10 +608,25 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec
|
||||||
{
|
{
|
||||||
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
|
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
|
||||||
|
|
||||||
if(grpKeySet.keys.find(sign.keyId) != grpKeySet.keys.end())
|
std::map<std::string, RsTlvSecurityKey>& keys = grpKeySet.keys;
|
||||||
|
std::map<std::string, RsTlvSecurityKey>::iterator mit = keys.begin();
|
||||||
|
|
||||||
|
std::string keyId;
|
||||||
|
for(; mit != keys.end() ; mit++)
|
||||||
{
|
{
|
||||||
RsTlvSecurityKey publishKey = grpKeySet.keys[sign.keyId];
|
RsTlvSecurityKey& key = mit->second;
|
||||||
valid &= GxsSecurity::validateNxsMsg(*msg, sign, publishKey);
|
|
||||||
|
if((key.keyFlags & RSTLV_KEY_DISTRIB_PUBLIC) &&
|
||||||
|
(key.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY))
|
||||||
|
{
|
||||||
|
keyId = key.keyId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!keyId.empty())
|
||||||
|
{
|
||||||
|
RsTlvSecurityKey& key = keys[keyId];
|
||||||
|
valid &= GxsSecurity::validateNxsMsg(*msg, sign, key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -808,14 +825,14 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vector<RsGxsGrpItem
|
||||||
{
|
{
|
||||||
RsGxsGrpItem* gItem = dynamic_cast<RsGxsGrpItem*>(item);
|
RsGxsGrpItem* gItem = dynamic_cast<RsGxsGrpItem*>(item);
|
||||||
gItem->meta = *((*lit)->metaData);
|
gItem->meta = *((*lit)->metaData);
|
||||||
grpItem.push_back(gItem);
|
grpItem.push_back(gItem);
|
||||||
delete *lit;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "RsGenExchange::getGroupData() ERROR deserialising item";
|
std::cerr << "RsGenExchange::getGroupData() ERROR deserialising item";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
|
delete *lit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -935,16 +952,20 @@ bool RsGenExchange::setAuthenPolicyFlag(const uint8_t &msgFlag, uint32_t& authen
|
||||||
|
|
||||||
void RsGenExchange::notifyNewGroups(std::vector<RsNxsGrp *> &groups)
|
void RsGenExchange::notifyNewGroups(std::vector<RsNxsGrp *> &groups)
|
||||||
{
|
{
|
||||||
|
RsStackMutex stack(mGenMtx);
|
||||||
|
|
||||||
std::vector<RsNxsGrp*>::iterator vit = groups.begin();
|
std::vector<RsNxsGrp*>::iterator vit = groups.begin();
|
||||||
|
|
||||||
// store these for tick() to pick them up
|
// store these for tick() to pick them up
|
||||||
for(; vit != groups.end(); vit++)
|
for(; vit != groups.end(); vit++)
|
||||||
mReceivedGrps.push_back(*vit);
|
mReceivedGrps.push_back(*vit);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsGenExchange::notifyNewMessages(std::vector<RsNxsMsg *>& messages)
|
void RsGenExchange::notifyNewMessages(std::vector<RsNxsMsg *>& messages)
|
||||||
{
|
{
|
||||||
|
RsStackMutex stack(mGenMtx);
|
||||||
|
|
||||||
std::vector<RsNxsMsg*>::iterator vit = messages.begin();
|
std::vector<RsNxsMsg*>::iterator vit = messages.begin();
|
||||||
|
|
||||||
// store these for tick() to pick them up
|
// store these for tick() to pick them up
|
||||||
|
@ -1584,9 +1605,9 @@ void RsGenExchange::processRecvdMessages()
|
||||||
if(mit != grpMetas.end()){
|
if(mit != grpMetas.end()){
|
||||||
RsGxsGrpMetaData* grpMeta = mit->second;
|
RsGxsGrpMetaData* grpMeta = mit->second;
|
||||||
ok = true;
|
ok = true;
|
||||||
// msg->metaData = meta;
|
msg->metaData = meta;
|
||||||
// ok &= validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys);
|
ok &= validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys);
|
||||||
// msg->metaData = NULL;
|
msg->metaData = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ok = false;
|
ok = false;
|
||||||
|
|
|
@ -254,7 +254,8 @@ protected:
|
||||||
&msg->msg.bin_len);
|
&msg->msg.bin_len);
|
||||||
GxsMsgType* mItem = dynamic_cast<GxsMsgType*>(item);
|
GxsMsgType* mItem = dynamic_cast<GxsMsgType*>(item);
|
||||||
|
|
||||||
if(mItem == NULL){
|
if(mItem == NULL)
|
||||||
|
{
|
||||||
delete msg;
|
delete msg;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,9 +142,17 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize)
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
int RsGxsMsgMetaData::refcount = 0;
|
||||||
|
|
||||||
RsGxsMsgMetaData::RsGxsMsgMetaData(){
|
RsGxsMsgMetaData::RsGxsMsgMetaData(){
|
||||||
|
|
||||||
|
//std::cout << "\nrefcount++ : " << ++refcount << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsMsgMetaData::~RsGxsMsgMetaData(){
|
||||||
|
//std::cout << "\nrefcount-- : " << --refcount << std::endl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RsGxsMsgMetaData::serial_size()
|
uint32_t RsGxsMsgMetaData::serial_size()
|
||||||
|
|
|
@ -87,7 +87,8 @@ class RsGxsMsgMetaData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RsGxsMsgMetaData();
|
explicit RsGxsMsgMetaData();
|
||||||
|
~RsGxsMsgMetaData();
|
||||||
bool deserialise(void *data, uint32_t *size);
|
bool deserialise(void *data, uint32_t *size);
|
||||||
bool serialise(void* data, uint32_t *size);
|
bool serialise(void* data, uint32_t *size);
|
||||||
uint32_t serial_size();
|
uint32_t serial_size();
|
||||||
|
@ -96,7 +97,7 @@ public:
|
||||||
|
|
||||||
RsGxsGroupId mGroupId;
|
RsGxsGroupId mGroupId;
|
||||||
RsGxsMessageId mMsgId;
|
RsGxsMessageId mMsgId;
|
||||||
|
static int refcount;
|
||||||
RsGxsMessageId mThreadId;
|
RsGxsMessageId mThreadId;
|
||||||
RsGxsMessageId mParentId;
|
RsGxsMessageId mParentId;
|
||||||
RsGxsMessageId mOrigMsgId;
|
RsGxsMessageId mOrigMsgId;
|
||||||
|
|
|
@ -54,10 +54,17 @@ void RsGxsIfaceImpl::groupsChanged(std::list<RsGxsGroupId> &grpIds)
|
||||||
|
|
||||||
bool RsGxsIfaceImpl::updated()
|
bool RsGxsIfaceImpl::updated()
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mGxsIfaceMutex);
|
bool changed = false;
|
||||||
|
{
|
||||||
|
RsStackMutex stack(mGxsIfaceMutex);
|
||||||
|
|
||||||
bool changed = (!mGroupChange.empty() || !mMsgChange.empty());
|
changed = (!mGroupChange.empty() || !mMsgChange.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs;
|
||||||
|
// msgsChanged(msgs);
|
||||||
|
// std::list<RsGxsGroupId> grpIds;
|
||||||
|
// groupsChanged(grpIds);
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,14 +79,14 @@ void RsGxsNetService::syncWithPeers()
|
||||||
|
|
||||||
std::set<std::string>::iterator sit = peers.begin();
|
std::set<std::string>::iterator sit = peers.begin();
|
||||||
|
|
||||||
// for now just grps
|
// for now just grps
|
||||||
for(; sit != peers.end(); sit++)
|
for(; sit != peers.end(); sit++)
|
||||||
{
|
{
|
||||||
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
|
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
|
||||||
grp->clear();
|
grp->clear();
|
||||||
grp->PeerId(*sit);
|
grp->PeerId(*sit);
|
||||||
sendItem(grp);
|
sendItem(grp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef GXS_ENABLE_SYNC_MSGS
|
#ifdef GXS_ENABLE_SYNC_MSGS
|
||||||
|
@ -152,41 +152,42 @@ void RsGxsNetService::recvNxsItemQueue(){
|
||||||
while(NULL != (item=recvItem()))
|
while(NULL != (item=recvItem()))
|
||||||
{
|
{
|
||||||
#ifdef NXS_NET_DEBUG
|
#ifdef NXS_NET_DEBUG
|
||||||
std::cerr << "RsGxsNetService Item:" << (void*)item << std::endl ;
|
std::cerr << "RsGxsNetService Item:" << (void*)item << std::endl ;
|
||||||
#endif
|
#endif
|
||||||
// RsNxsItem needs dynamic_cast, since they have derived siblings.
|
// RsNxsItem needs dynamic_cast, since they have derived siblings.
|
||||||
//
|
//
|
||||||
RsNxsItem *ni = dynamic_cast<RsNxsItem*>(item) ;
|
RsNxsItem *ni = dynamic_cast<RsNxsItem*>(item) ;
|
||||||
if(ni != NULL)
|
if(ni != NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
// a live transaction has a non zero value
|
// a live transaction has a non zero value
|
||||||
if(ni->transactionNumber != 0){
|
if(ni->transactionNumber != 0){
|
||||||
|
|
||||||
#ifdef NXS_NET_DEBUG
|
#ifdef NXS_NET_DEBUG
|
||||||
std::cerr << "recvNxsItemQueue()" << std::endl;
|
std::cerr << "recvNxsItemQueue()" << std::endl;
|
||||||
std::cerr << "handlingTransaction, transN" << ni->transactionNumber << std::endl;
|
std::cerr << "handlingTransaction, transN" << ni->transactionNumber << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(handleTransaction(ni))
|
if(handleTransaction(ni))
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch(ni->PacketSubType())
|
switch(ni->PacketSubType())
|
||||||
{
|
{
|
||||||
case RS_PKT_SUBTYPE_NXS_SYNC_GRP: handleRecvSyncGroup (dynamic_cast<RsNxsSyncGrp*>(ni)) ; break ;
|
case RS_PKT_SUBTYPE_NXS_SYNC_GRP: handleRecvSyncGroup (dynamic_cast<RsNxsSyncGrp*>(ni)) ; break ;
|
||||||
case RS_PKT_SUBTYPE_NXS_SYNC_MSG: handleRecvSyncMessage (dynamic_cast<RsNxsSyncMsg*>(ni)) ; break ;
|
case RS_PKT_SUBTYPE_NXS_SYNC_MSG: handleRecvSyncMessage (dynamic_cast<RsNxsSyncMsg*>(ni)) ; break ;
|
||||||
default:
|
default:
|
||||||
std::cerr << "Unhandled item subtype " << ni->PacketSubType() << " in RsGxsNetService: " << std::endl; break;
|
std::cerr << "Unhandled item subtype " << ni->PacketSubType() << " in RsGxsNetService: " << std::endl; break;
|
||||||
}
|
}
|
||||||
delete item ;
|
delete item ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
bool RsGxsNetService::handleTransaction(RsNxsItem* item)
|
||||||
|
{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This attempts to handle a transaction
|
* This attempts to handle a transaction
|
||||||
|
@ -201,9 +202,9 @@ bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
||||||
RsNxsTransac* transItem = dynamic_cast<RsNxsTransac*>(item);
|
RsNxsTransac* transItem = dynamic_cast<RsNxsTransac*>(item);
|
||||||
|
|
||||||
// if this is a RsNxsTransac item process
|
// if this is a RsNxsTransac item process
|
||||||
if(transItem){
|
if(transItem)
|
||||||
return locked_processTransac(transItem);
|
return locked_processTransac(transItem);
|
||||||
}
|
|
||||||
|
|
||||||
// then this must be transaction content to be consumed
|
// then this must be transaction content to be consumed
|
||||||
// first check peer exist for transaction
|
// first check peer exist for transaction
|
||||||
|
@ -221,7 +222,8 @@ bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
||||||
|
|
||||||
transExists = transMap.find(transN) != transMap.end();
|
transExists = transMap.find(transN) != transMap.end();
|
||||||
|
|
||||||
if(transExists){
|
if(transExists)
|
||||||
|
{
|
||||||
|
|
||||||
#ifdef NXS_NET_DEBUG
|
#ifdef NXS_NET_DEBUG
|
||||||
std::cerr << "handleTransaction() " << std::endl;
|
std::cerr << "handleTransaction() " << std::endl;
|
||||||
|
@ -231,13 +233,12 @@ bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
||||||
|
|
||||||
tr = transMap[transN];
|
tr = transMap[transN];
|
||||||
tr->mItems.push_back(item);
|
tr->mItems.push_back(item);
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
return true;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsGxsNetService::locked_processTransac(RsNxsTransac* item)
|
bool RsGxsNetService::locked_processTransac(RsNxsTransac* item)
|
||||||
|
@ -368,8 +369,8 @@ void RsGxsNetService::run(){
|
||||||
|
|
||||||
bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr)
|
bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr)
|
||||||
{
|
{
|
||||||
return tr->mTimeOut < ((uint32_t) time(NULL));
|
//return tr->mTimeOut < ((uint32_t) time(NULL));
|
||||||
// return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsGxsNetService::processTransactions(){
|
void RsGxsNetService::processTransactions(){
|
||||||
|
@ -1027,7 +1028,7 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
|
||||||
|
|
||||||
uint32_t transN = locked_getTransactionId();
|
uint32_t transN = locked_getTransactionId();
|
||||||
|
|
||||||
// store msg items to send in transaction
|
// store msg items to send in transaction
|
||||||
GxsMsgResult::iterator mit = msgs.begin();
|
GxsMsgResult::iterator mit = msgs.begin();
|
||||||
std::string peerId = tr->mTransaction->PeerId();
|
std::string peerId = tr->mTransaction->PeerId();
|
||||||
uint32_t msgSize = 0;
|
uint32_t msgSize = 0;
|
||||||
|
|
|
@ -58,6 +58,7 @@ class GroupIdReq : public GxsRequest
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::list<std::string> mGroupIds;
|
std::list<std::string> mGroupIds;
|
||||||
std::list<std::string> mGroupIdResult;
|
std::list<std::string> mGroupIdResult;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue