Fixed resource exhaustion due to message/group notification not being handled

Added message/group size limit
Added message validation (identity and publish key)
Added code for message/grp fragmentation/defragmentation (not integrated yet) 
Added crude id picker to photoshare


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6106 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
chrisparker126 2013-02-07 23:04:16 +00:00
parent 635f915f46
commit 7867063734
21 changed files with 735 additions and 264 deletions

View File

@ -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,9 @@ 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;
msgMeta.signSet = signSet;
if (signOk == 1) if (signOk == 1)
{ {

View File

@ -134,6 +134,7 @@ const std::string RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG = KEY_GRP_SUBCR_
const std::string RsGeneralDataService::MSG_META_SERV_STRING = KEY_NXS_SERV_STRING; const std::string RsGeneralDataService::MSG_META_SERV_STRING = KEY_NXS_SERV_STRING;
const std::string RsGeneralDataService::MSG_META_STATUS = KEY_MSG_STATUS; const std::string RsGeneralDataService::MSG_META_STATUS = KEY_MSG_STATUS;
const uint32_t RsGeneralDataService::GXS_MAX_ITEM_SIZE = 1572864; // 1.5 Mbytes
RsDataService::RsDataService(const std::string &serviceDir, const std::string &dbName, uint16_t serviceType, RsDataService::RsDataService(const std::string &serviceDir, const std::string &dbName, uint16_t serviceType,
RsGxsSearchModule *mod) RsGxsSearchModule *mod)
@ -453,6 +454,9 @@ int RsDataService::storeMessage(std::map<RsNxsMsg *, RsGxsMsgMetaData *> &msg)
RsNxsMsg* msgPtr = mit->first; RsNxsMsg* msgPtr = mit->first;
RsGxsMsgMetaData* msgMetaPtr = mit->second; RsGxsMsgMetaData* msgMetaPtr = mit->second;
// skip msg item if size if greater than
if(!validSize(msgPtr)) continue;
// create or access file in binary // create or access file in binary
std::string msgFile = mServiceDir + "/" + msgPtr->grpId + "-msgs"; std::string msgFile = mServiceDir + "/" + msgPtr->grpId + "-msgs";
std::fstream ostrm(msgFile.c_str(), std::ios::binary | std::ios::app | std::ios::out); std::fstream ostrm(msgFile.c_str(), std::ios::binary | std::ios::app | std::ios::out);
@ -519,6 +523,13 @@ int RsDataService::storeMessage(std::map<RsNxsMsg *, RsGxsMsgMetaData *> &msg)
return ret; return ret;
} }
bool RsDataService::validSize(RsNxsMsg* msg) const
{
if((msg->msg.TlvSize() + msg->meta.TlvSize()) <= GXS_MAX_ITEM_SIZE) return true;
return false;
}
int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp) int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
{ {
@ -536,6 +547,9 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
RsNxsGrp* grpPtr = sit->first; RsNxsGrp* grpPtr = sit->first;
RsGxsGrpMetaData* grpMetaPtr = sit->second; RsGxsGrpMetaData* grpMetaPtr = sit->second;
// if data is larger than max item size do not add
if(!validSize(grpPtr)) continue;
std::string grpFile = mServiceDir + "/" + grpPtr->grpId; std::string grpFile = mServiceDir + "/" + grpPtr->grpId;
std::fstream ostrm(grpFile.c_str(), std::ios::binary | std::ios::app | std::ios::out); std::fstream ostrm(grpFile.c_str(), std::ios::binary | std::ios::app | std::ios::out);
ostrm.seekg(0, std::ios::end); // go to end to append ostrm.seekg(0, std::ios::end); // go to end to append
@ -607,6 +621,12 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
return ret; return ret;
} }
bool RsDataService::validSize(RsNxsGrp* grp) const
{
if((grp->grp.TlvSize() + grp->meta.TlvSize()) <= GXS_MAX_ITEM_SIZE) return true;
return false;
}
int RsDataService::retrieveNxsGrps(std::map<std::string, RsNxsGrp *> &grp, bool withMeta, bool cache){ int RsDataService::retrieveNxsGrps(std::map<std::string, RsNxsGrp *> &grp, bool withMeta, bool cache){
if(grp.empty()){ if(grp.empty()){
@ -969,6 +989,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);

View File

@ -132,6 +132,11 @@ public:
*/ */
int resetDataStore(); int resetDataStore();
bool validSize(RsNxsMsg* msg) const;
bool validSize(RsNxsGrp* grp) const;
private: private:
/*! /*!

View File

@ -105,6 +105,8 @@ class RsGeneralDataService
public: public:
static const uint32_t GXS_MAX_ITEM_SIZE;
static const std::string MSG_META_SERV_STRING; static const std::string MSG_META_SERV_STRING;
static const std::string MSG_META_STATUS; static const std::string MSG_META_STATUS;
@ -210,6 +212,22 @@ public:
*/ */
virtual int resetDataStore() = 0; virtual int resetDataStore() = 0;
/*!
* Use to determine if message isn't over the storage
* limit for a single message item
* @param msg the message to check size validity
* @return whether the size of of msg is valid
*/
virtual bool validSize(RsNxsMsg* msg) const = 0 ;
/*!
* Use to determine if group isn't over the storage limit
* for a single group item
* @param grp the group to check size validity
* @return whether the size of grp is valid for storage
*/
virtual bool validSize(RsNxsGrp* grp) const = 0 ;
}; };

View File

@ -101,20 +101,20 @@ void RsGenExchange::tick()
publishMsgs(); publishMsgs();
processGrpMetaChanges(); processGrpMetaChanges();
processMsgMetaChanges(); processMsgMetaChanges();
processRecvdData(); processRecvdData();
if(!mNotifications.empty()) if(!mNotifications.empty())
{ {
notifyChanges(mNotifications); notifyChanges(mNotifications);
mNotifications.clear(); mNotifications.clear();
} }
// implemented service tick function // implemented service tick function
service_tick(); service_tick();
} }
bool RsGenExchange::acknowledgeTokenMsg(const uint32_t& token, bool RsGenExchange::acknowledgeTokenMsg(const uint32_t& token,
@ -160,7 +160,8 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token,
return true; return true;
} }
void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys) void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet,
RsTlvSecurityKeySet& publickeySet, bool genPublishKeys)
{ {
/* create Keys */ /* create Keys */
@ -174,8 +175,10 @@ 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 = adminKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
privAdminKey.startTS = adminKey.startTS; privAdminKey.startTS = adminKey.startTS;
privAdminKey.endTS = 0; /* no end */ privAdminKey.endTS = 0; /* no end */
@ -184,8 +187,8 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPubli
adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY; adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY;
privAdminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL; privAdminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL;
keySet.keys[adminKey.keyId] = adminKey; publickeySet.keys[adminKey.keyId] = adminKey;
keySet.keys[privAdminKey.keyId] = privAdminKey; privatekeySet.keys[privAdminKey.keyId] = privAdminKey;
// clean up // clean up
RSA_free(rsa_admin); RSA_free(rsa_admin);
@ -204,6 +207,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;
@ -213,16 +217,15 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPubli
pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY; pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY;
privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL; privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL;
keySet.keys[pubKey.keyId] = pubKey; publickeySet.keys[pubKey.keyId] = pubKey;
keySet.keys[privPubKey.keyId] = privPubKey; privatekeySet.keys[privPubKey.keyId] = privPubKey;
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& privateKeySet, RsTlvSecurityKeySet& publicKeySet)
{ {
std::cerr << "RsGenExchange::createGroup()"; std::cerr << "RsGenExchange::createGroup()";
std::cerr << std::endl; std::cerr << std::endl;
@ -233,22 +236,14 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
// find private admin key // find private admin key
RsTlvSecurityKey privAdminKey; RsTlvSecurityKey privAdminKey;
std::map<std::string, RsTlvSecurityKey>::iterator mit = keySet.keys.begin(); std::map<std::string, RsTlvSecurityKey>::iterator mit = privateKeySet.keys.begin();
bool privKeyFound = false; bool privKeyFound = false; // private admin key
for(; mit != keySet.keys.end(); mit++) for(; mit != privateKeySet.keys.end(); mit++)
{ {
RsTlvSecurityKey& key = mit->second; RsTlvSecurityKey& key = mit->second;
// add public admin key if((key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (key.keyFlags & RSTLV_KEY_TYPE_FULL))
if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY))
meta->keys.keys.insert(std::make_pair(key.keyId, key));
// add public publish key
if(key.keyFlags & (RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY))
meta->keys.keys.insert(std::make_pair(key.keyId, key));
if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
{ {
privAdminKey = key; privAdminKey = key;
privKeyFound = true; privKeyFound = true;
@ -263,6 +258,8 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
return false; return false;
} }
meta->keys = publicKeySet; // only public keys are included to be transported
// group is self signing // group is self signing
// for the creation of group signature // for the creation of group signature
// only public admin and publish keys are present in meta // only public admin and publish keys are present in meta
@ -288,9 +285,9 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
grp->meta.setBinData(metaData, metaDataLen); grp->meta.setBinData(metaData, metaDataLen);
// but meta that is stored locally // but meta that is stored locally
// has all keys // has private keys
// nxs net transports only bin data // nxs net transports only bin data
meta->keys = keySet; meta->keys = privateKeySet;
// clean up // clean up
delete[] allGrpData; delete[] allGrpData;
@ -432,7 +429,7 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina
// poll immediately but, don't spend more than a second polling // poll immediately but, don't spend more than a second polling
while( (mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey) == -1) && while( (mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey) == -1) &&
((now + 1) >> time(NULL)) ((now + 5) > time(NULL))
) )
{ {
#ifndef WINDOWS_SYS #ifndef WINDOWS_SYS
@ -606,16 +603,30 @@ 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
{ {
valid = false; valid = false;
} }
} }
@ -647,7 +658,7 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec
#endif #endif
} }
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY];
valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey);
}else }else
{ {
@ -808,14 +819,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 +946,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
@ -1225,7 +1240,7 @@ void RsGenExchange::publishMsgs()
RsGxsMessageId msgId; RsGxsMessageId msgId;
RsGxsGroupId grpId = msgItem->meta.mGroupId; RsGxsGroupId grpId = msgItem->meta.mGroupId;
bool msgDoesnExist = false; bool msgDoesnExist = false, validSize = false;
if(createOk) if(createOk)
{ {
@ -1247,6 +1262,11 @@ void RsGenExchange::publishMsgs()
} }
if(createOk && msgDoesnExist) if(createOk && msgDoesnExist)
{
validSize = mDataStore->validSize(msg);
}
if(createOk && msgDoesnExist && validSize)
{ {
// empty orig msg id means this is the original // empty orig msg id means this is the original
// msg // msg
@ -1334,16 +1354,16 @@ void RsGenExchange::publishGrps()
RsNxsGrp* grp = new RsNxsGrp(mServType); RsNxsGrp* grp = new RsNxsGrp(mServType);
RsGxsGrpItem* grpItem = mit->second; RsGxsGrpItem* grpItem = mit->second;
RsTlvSecurityKeySet keySet; RsTlvSecurityKeySet privatekeySet, publicKeySet, tempKeySet;
generateGroupKeys(keySet, generateGroupKeys(privatekeySet, publicKeySet,
!(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC)); !(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC));
// find private admin key // find private admin key
RsTlvSecurityKey privAdminKey; RsTlvSecurityKey privAdminKey;
std::map<std::string, RsTlvSecurityKey>::iterator mit_keys = keySet.keys.begin(); std::map<std::string, RsTlvSecurityKey>::iterator mit_keys = privatekeySet.keys.begin();
bool privKeyFound = false; bool privKeyFound = false;
for(; mit_keys != keySet.keys.end(); mit_keys++) for(; mit_keys != privatekeySet.keys.end(); mit_keys++)
{ {
RsTlvSecurityKey& key = mit_keys->second; RsTlvSecurityKey& key = mit_keys->second;
@ -1366,8 +1386,14 @@ void RsGenExchange::publishGrps()
ok = false; ok = false;
} }
//tempKeySet = privatekeySet;
privatekeySet.keys.insert(publicKeySet.keys.begin(),
publicKeySet.keys.end());
service_CreateGroup(grpItem, privatekeySet);
//privatekeySet = tempKeySet;
service_CreateGroup(grpItem, keySet);
uint32_t size = mSerialiser->size(grpItem); uint32_t size = mSerialiser->size(grpItem);
char gData[size]; char gData[size];
@ -1387,21 +1413,28 @@ void RsGenExchange::publishGrps()
*(grp->metaData) = grpItem->meta; *(grp->metaData) = grpItem->meta;
grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN;
ok &= createGroup(grp, keySet); if (!createGroup(grp, privatekeySet, publicKeySet))
if (!ok)
{ {
std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl; std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl;
} }
else
{
RsGxsGroupId grpId = grp->grpId; // ensure group size is not too large
mDataAccess->addGroupData(grp); ok &= mDataStore->validSize(grp);
std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl; if(ok)
{
RsGxsGroupId grpId = grp->grpId;
mDataAccess->addGroupData(grp);
// add to published to allow acknowledgement std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl;
mGrpNotify.insert(std::make_pair(mit->first, grpId));
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); // add to published to allow acknowledgement
mGrpNotify.insert(std::make_pair(mit->first, grpId));
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
}
}
} }
if(!ok) if(!ok)
@ -1485,16 +1518,16 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem)
bool ok = mSerialiser->serialise(grpItem, gData, &size); bool ok = mSerialiser->serialise(grpItem, gData, &size);
grp->grp.setBinData(gData, size); grp->grp.setBinData(gData, size);
RsTlvSecurityKeySet keySet; RsTlvSecurityKeySet privateKeySet, publicKeySet;
generateGroupKeys(keySet, generateGroupKeys(privateKeySet, publicKeySet,
!(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC)); !(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC));
// find private admin key // find private admin key
RsTlvSecurityKey privAdminKey; RsTlvSecurityKey privAdminKey;
std::map<std::string, RsTlvSecurityKey>::iterator mit_keys = keySet.keys.begin(); std::map<std::string, RsTlvSecurityKey>::iterator mit_keys = privateKeySet.keys.begin();
bool privKeyFound = false; bool privKeyFound = false;
for(; mit_keys != keySet.keys.end(); mit_keys++) for(; mit_keys != privateKeySet.keys.end(); mit_keys++)
{ {
RsTlvSecurityKey& key = mit_keys->second; RsTlvSecurityKey& key = mit_keys->second;
@ -1516,7 +1549,7 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem)
ok = false; ok = false;
} }
service_CreateGroup(grpItem, keySet); service_CreateGroup(grpItem, privateKeySet);
if(ok) if(ok)
{ {
@ -1524,7 +1557,7 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem)
grpItem->meta.mPublishTs = time(NULL); grpItem->meta.mPublishTs = time(NULL);
*(grp->metaData) = grpItem->meta; *(grp->metaData) = grpItem->meta;
grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN;
createGroup(grp, keySet); createGroup(grp, privateKeySet, publicKeySet);
mDataAccess->addGroupData(grp); mDataAccess->addGroupData(grp);
} }
@ -1584,9 +1617,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;

View File

@ -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;
} }
@ -474,7 +475,7 @@ private:
* Meta is serialised and stored in group at this point also * Meta is serialised and stored in group at this point also
* @param grp Nxs group to create * @param grp Nxs group to create
*/ */
bool createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& keySet); bool createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet);
/*! /*!
* This completes the creation of an instance on RsNxsMsg * This completes the creation of an instance on RsNxsMsg
@ -503,10 +504,11 @@ private:
/*! /*!
* Generate a set of keys that can define a GXS group * Generate a set of keys that can define a GXS group
* @param keySet this is set generated keys * @param privatekeySet contains private generated keys
* @param genPublicKeys should public keys also be generated * @param privatekeySet contains public generated keys (counterpart of private)
* @param genPublicKeys should publish key pair also be generated
*/ */
void generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys); void generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet, bool genPublishKeys);
/*! /*!
* Attempts to validate msg * Attempts to validate msg

View File

@ -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()

View File

@ -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;

View File

@ -52,11 +52,26 @@ void RsGxsIfaceImpl::groupsChanged(std::list<RsGxsGroupId> &grpIds)
} }
} }
bool RsGxsIfaceImpl::updated() bool RsGxsIfaceImpl::updated(bool willCallGrpChanged, bool willCallMsgChanged)
{ {
RsStackMutex stack(mGxsIfaceMutex); bool changed = false;
{
RsStackMutex stack(mGxsIfaceMutex);
bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); changed = (!mGroupChange.empty() || !mMsgChange.empty());
}
if(!willCallGrpChanged)
{
std::list<RsGxsGroupId> grpIds;
groupsChanged(grpIds);
}
if(!willCallMsgChanged)
{
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs;
msgsChanged(msgs);
}
return changed; return changed;
} }

View File

@ -46,6 +46,7 @@ public:
*/ */
RsGxsIfaceImpl(RsGenExchange* gxs); RsGxsIfaceImpl(RsGenExchange* gxs);
protected:
/*! /*!
* Gxs services should call this for automatic handling of * Gxs services should call this for automatic handling of
* changes, send * changes, send
@ -53,14 +54,20 @@ public:
*/ */
void receiveChanges(std::vector<RsGxsNotify*>& changes); void receiveChanges(std::vector<RsGxsNotify*>& changes);
public:
/*! /*!
* Checks to see if a change has been received for * Checks to see if a change has been received for
* for a message or group * for a message or group
* @param willCallGrpChanged if this is set to true, group changed function will return list
* groups that have changed, if false, the group changed list is cleared
* @param willCallMsgChanged if this is set to true, msgChanged function will return map
* messages that have changed, if false, the message changed map is cleared
* @return true if a change has occured for msg or group * @return true if a change has occured for msg or group
* @see groupsChanged
* @see msgsChanged
*/ */
virtual bool updated(); virtual bool updated(bool willCallGrpChanged = false, bool willCallMsgChanged = false);
public:
/*! /*!
* The groups changed. \n * The groups changed. \n
@ -68,7 +75,8 @@ public:
* the group actually set for ui notification. * the group actually set for ui notification.
* If receivedChanges is not passed RsGxsNotify changes * If receivedChanges is not passed RsGxsNotify changes
* this function does nothing * this function does nothing
* @param grpIds * @param grpIds returns list of grpIds that have changed
* @see updated
*/ */
virtual void groupsChanged(std::list<RsGxsGroupId>& grpIds); virtual void groupsChanged(std::list<RsGxsGroupId>& grpIds);
@ -78,7 +86,8 @@ public:
* the msg actually set for ui notification. * the msg actually set for ui notification.
* If receivedChanges is not passed RsGxsNotify changes * If receivedChanges is not passed RsGxsNotify changes
* this function does nothing * this function does nothing
* @param msgs * @param msgs returns map of message ids that have changed
* @see updated
*/ */
virtual void msgsChanged(std::map<RsGxsGroupId, virtual void msgsChanged(std::map<RsGxsGroupId,
std::vector<RsGxsMessageId> >& msgs); std::vector<RsGxsMessageId> >& msgs);

View File

@ -25,6 +25,7 @@
*/ */
#include <unistd.h> #include <unistd.h>
#include <math.h>
#include "rsgxsnetservice.h" #include "rsgxsnetservice.h"
#include "rsgxsflags.h" #include "rsgxsflags.h"
@ -34,6 +35,7 @@
#define SYNC_PERIOD 12 // in microseconds every 10 seconds (1 second for testing) #define SYNC_PERIOD 12 // in microseconds every 10 seconds (1 second for testing)
#define TRANSAC_TIMEOUT 5 // 5 seconds #define TRANSAC_TIMEOUT 5 // 5 seconds
const uint32_t RsGxsNetService::FRAGMENT_SIZE = 150000;
RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds, RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs) RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs)
@ -79,15 +81,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
std::map<RsGxsGroupId, RsGxsGrpMetaData* > grpMeta; std::map<RsGxsGroupId, RsGxsGrpMetaData* > grpMeta;
@ -130,6 +131,236 @@ void RsGxsNetService::syncWithPeers()
#endif #endif
} }
bool RsGxsNetService::fragmentMsg(RsNxsMsg& msg, MsgFragments& msgFragments) const
{
// first determine how many fragments
uint32_t msgSize = msg.msg.TlvSize();
uint32_t dataLeft = msgSize;
uint8_t nFragments = ceil(float(msgSize)/FRAGMENT_SIZE);
char buffer[FRAGMENT_SIZE];
int currPos = 0;
for(uint8_t i=0; i < nFragments; i++)
{
RsNxsMsg* msgFrag = new RsNxsMsg(mServType);
msgFrag->grpId = msg.grpId;
msgFrag->msgId = msg.msgId;
msgFrag->meta = msg.meta;
msgFrag->pos = i;
msgFrag->count = nFragments;
uint32_t fragSize = std::min(dataLeft, FRAGMENT_SIZE);
memcpy(buffer, ((char*)msg.msg.bin_data) + currPos, fragSize);
currPos += fragSize;
dataLeft -= fragSize;
msgFragments.push_back(msgFrag);
}
return true;
}
bool RsGxsNetService::fragmentGrp(RsNxsGrp& grp, GrpFragments& grpFragments) const
{
// first determine how many fragments
uint32_t grpSize = grp.grp.TlvSize();
uint32_t dataLeft = grpSize;
uint8_t nFragments = ceil(float(grpSize)/FRAGMENT_SIZE);
char buffer[FRAGMENT_SIZE];
int currPos = 0;
for(uint8_t i=0; i < nFragments; i++)
{
RsNxsGrp* grpFrag = new RsNxsGrp(mServType);
grpFrag->grpId = grp.grpId;
grpFrag->meta = grp.meta;
grpFrag->pos = i;
grpFrag->count = nFragments;
uint32_t fragSize = std::min(dataLeft, FRAGMENT_SIZE);
memcpy(buffer, ((char*)grp.grp.bin_data) + currPos, fragSize);
currPos += fragSize;
dataLeft -= fragSize;
grpFragments.push_back(grpFrag);
}
return true;
}
RsNxsMsg* RsGxsNetService::deFragmentMsg(MsgFragments& msgFragments) const
{
if(msgFragments.empty()) return NULL;
// first determine total size for binary data
MsgFragments::iterator mit = msgFragments.begin();
uint32_t datSize = 0;
for(; mit != msgFragments.end(); mit++)
datSize += (*mit)->msg.bin_len;
char* data = new char[datSize];
uint32_t currPos = 0;
for(mit = msgFragments.begin(); mit != msgFragments.end(); mit++)
{
RsNxsMsg* msg = *mit;
memcpy(data + (currPos), msg->msg.bin_data, msg->msg.bin_len);
currPos += msg->msg.bin_len;
}
RsNxsMsg* msg = new RsNxsMsg(mServType);
const RsNxsMsg& m = *(*(msgFragments.begin()));
msg->msg.setBinData(data, datSize);
msg->msgId = m.msgId;
msg->grpId = m.grpId;
msg->transactionNumber = m.transactionNumber;
msg->meta = m.meta;
delete[] data;
return msg;
}
RsNxsGrp* RsGxsNetService::deFragmentGrp(GrpFragments& grpFragments) const
{
if(grpFragments.empty()) return NULL;
// first determine total size for binary data
GrpFragments::iterator mit = grpFragments.begin();
uint32_t datSize = 0;
for(; mit != grpFragments.end(); mit++)
datSize += (*mit)->grp.bin_len;
char* data = new char[datSize];
uint32_t currPos = 0;
for(mit = grpFragments.begin(); mit != grpFragments.end(); mit++)
{
RsNxsGrp* grp = *mit;
memcpy(data + (currPos), grp->grp.bin_data, grp->grp.bin_len);
currPos += grp->grp.bin_len;
}
RsNxsGrp* grp = new RsNxsGrp(mServType);
const RsNxsGrp& g = *(*(grpFragments.begin()));
grp->grp.setBinData(data, datSize);
grp->grpId = g.grpId;
grp->transactionNumber = g.transactionNumber;
grp->meta = g.meta;
delete[] data;
return grp;
}
struct GrpFragCollate
{
RsGxsGroupId mGrpId;
GrpFragCollate(const RsGxsGroupId& grpId) : mGrpId(grpId){ }
bool operator()(RsNxsGrp* grp) { return grp->grpId == mGrpId;}
};
void RsGxsNetService::collateGrpFragments(GrpFragments fragments,
std::map<RsGxsGroupId, GrpFragments>& partFragments) const
{
// get all unique grpIds;
GrpFragments::iterator vit = fragments.begin();
std::set<RsGxsGroupId> grpIds;
for(; vit != fragments.end(); vit++)
grpIds.insert( (*vit)->grpId );
std::set<RsGxsGroupId>::iterator sit = grpIds.begin();
for(; sit != grpIds.end(); sit++)
{
const RsGxsGroupId& grpId = *sit;
GrpFragments::iterator bound = std::partition(
fragments.begin(), fragments.end(),
GrpFragCollate(grpId));
// something will always be found for a group id
for(vit = fragments.begin(); vit != bound; )
{
partFragments[grpId].push_back(*vit);
vit = fragments.erase(vit);
}
GrpFragments& f = partFragments[grpId];
RsNxsGrp* grp = *(f.begin());
// if counts of fragments is incorrect remove
// from coalescion
if(grp->count != f.size())
{
GrpFragments::iterator vit2 = f.begin();
for(; vit2 != f.end(); vit2++)
delete *vit2;
partFragments.erase(grpId);
}
}
fragments.clear();
}
struct MsgFragCollate
{
RsGxsGroupId mMsgId;
MsgFragCollate(const RsGxsMessageId& msgId) : mMsgId(msgId){ }
bool operator()(RsNxsMsg* msg) { return msg->msgId == mMsgId;}
};
void RsGxsNetService::collateMsgFragments(MsgFragments fragments, std::map<RsGxsMessageId, MsgFragments>& partFragments) const
{
// get all unique message Ids;
MsgFragments::iterator vit = fragments.begin();
std::set<RsGxsMessageId> msgIds;
for(; vit != fragments.end(); vit++)
msgIds.insert( (*vit)->msgId );
std::set<RsGxsMessageId>::iterator sit = msgIds.begin();
for(; sit != msgIds.end(); sit++)
{
const RsGxsMessageId& msgId = *sit;
MsgFragments::iterator bound = std::partition(
fragments.begin(), fragments.end(),
MsgFragCollate(msgId));
// something will always be found for a group id
for(vit = fragments.begin(); vit != bound; )
{
partFragments[msgId].push_back(*vit);
vit = fragments.erase(vit);
}
MsgFragments& f = partFragments[msgId];
RsNxsMsg* msg = *(f.begin());
// if counts of fragments is incorrect remove
// from coalescion
if(msg->count != f.size())
{
MsgFragments::iterator vit2 = f.begin();
for(; vit2 != f.end(); vit2++)
delete *vit2;
partFragments.erase(msgId);
}
}
fragments.clear();
}
bool RsGxsNetService::loadList(std::list<RsItem*>& load) bool RsGxsNetService::loadList(std::list<RsItem*>& load)
{ {
return false; return false;
@ -152,41 +383,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 +433,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 +453,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 +464,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 +600,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 +1259,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;

View File

@ -133,7 +133,7 @@ class RsGxsNetService : public RsNetworkExchangeService, public p3ThreadedServic
{ {
public: public:
static const uint32_t FRAGMENT_SIZE;
/*! /*!
* only one observer is allowed * only one observer is allowed
* @param servType service type * @param servType service type
@ -365,6 +365,60 @@ private:
private: private:
typedef std::vector<RsNxsGrp*> GrpFragments;
typedef std::vector<RsNxsMsg*> MsgFragments;
/*!
* Fragment a message into individual fragments which are at most 150kb
* @param msg message to fragment
* @param msgFragments fragmented message
* @return false if fragmentation fails true otherwise
*/
bool fragmentMsg(RsNxsMsg& msg, MsgFragments& msgFragments) const;
/*!
* Fragment a group into individual fragments which are at most 150kb
* @param grp group to fragment
* @param grpFragments fragmented group
* @return false if fragmentation fails true other wise
*/
bool fragmentGrp(RsNxsGrp& grp, GrpFragments& grpFragments) const;
/*!
* Fragment a message into individual fragments which are at most 150kb
* @param msg message to fragment
* @param msgFragments fragmented message
* @return NULL if not possible to reconstruct message from fragment,
* pointer to defragments nxs message is possible
*/
RsNxsMsg* deFragmentMsg(MsgFragments& msgFragments) const;
/*!
* Fragment a group into individual fragments which are at most 150kb
* @param grp group to fragment
* @param grpFragments fragmented group
* @return NULL if not possible to reconstruct group from fragment,
* pointer to defragments nxs group is possible
*/
RsNxsGrp* deFragmentGrp(GrpFragments& grpFragments) const;
/*!
* Note that if all fragments for a message are not found then its fragments are dropped
* @param fragments message fragments which are not necessarily from the same message
* @param partFragments the partitioned fragments (into message ids)
*/
void collateMsgFragments(MsgFragments fragments, std::map<RsGxsMessageId, MsgFragments>& partFragments) const;
/*!
* Note that if all fragments for a group are not found then its fragments are dropped
* @param fragments group fragments which are not necessarily from the same group
* @param partFragments the partitioned fragments (into message ids)
*/
void collateGrpFragments(GrpFragments fragments, std::map<RsGxsGroupId, GrpFragments>& partFragments) const;
private:
/*** transactions ***/ /*** transactions ***/
/// active transactions /// active transactions

View File

@ -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;
}; };

View File

@ -2263,7 +2263,6 @@ int RsServer::StartupRetroShare()
mPluginsManager->registerClientServices(pqih) ; mPluginsManager->registerClientServices(pqih) ;
mPluginsManager->registerCacheServices() ; mPluginsManager->registerCacheServices() ;
#ifdef RS_ENABLE_GXS #ifdef RS_ENABLE_GXS
// The idea is that if priorGxsDir is non // The idea is that if priorGxsDir is non
@ -2331,9 +2330,9 @@ int RsServer::StartupRetroShare()
RsGenExchange::RESTRICTED_GRP_BITS); RsGenExchange::RESTRICTED_GRP_BITS);
// Re-enable later, photo not using gixs yet // Re-enable later, photo not using gixs yet
// flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN; // should be GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN for comments
// RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy,
// RsGenExchange::RESTRICTED_GRP_BITS); RsGenExchange::RESTRICTED_GRP_BITS);
flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy,

View File

@ -248,6 +248,7 @@ bool RsNxsSerialiser::serialiseNxsMsg(RsNxsMsg *item, void *data, uint32_t *size
offset += 8; offset += 8;
ok &= setRawUInt32(data, *size, &offset, item->transactionNumber); ok &= setRawUInt32(data, *size, &offset, item->transactionNumber);
ok &= setRawUInt8(data, *size, &offset, item->pos);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_MSGID, item->msgId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_MSGID, item->msgId);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GROUPID, item->grpId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= item->msg.SetTlv(data, tlvsize, &offset); ok &= item->msg.SetTlv(data, tlvsize, &offset);
@ -299,6 +300,7 @@ bool RsNxsSerialiser::serialiseNxsGrp(RsNxsGrp *item, void *data, uint32_t *size
// grp id // grp id
ok &= setRawUInt32(data, *size, &offset, item->transactionNumber); ok &= setRawUInt32(data, *size, &offset, item->transactionNumber);
ok &= setRawUInt8(data, *size, &offset, item->pos);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GROUPID, item->grpId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= item->grp.SetTlv(data, tlvsize, &offset); ok &= item->grp.SetTlv(data, tlvsize, &offset);
ok &= item->meta.SetTlv(data, *size, &offset); ok &= item->meta.SetTlv(data, *size, &offset);
@ -564,6 +566,7 @@ RsNxsGrp* RsNxsSerialiser::deserialNxsGrp(void *data, uint32_t *size){
offset += 8; offset += 8;
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber)); ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
ok &= getRawUInt8(data, *size, &offset, &(item->pos));
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId); ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= item->grp.GetTlv(data, *size, &offset); ok &= item->grp.GetTlv(data, *size, &offset);
ok &= item->meta.GetTlv(data, *size, &offset); ok &= item->meta.GetTlv(data, *size, &offset);
@ -632,6 +635,7 @@ RsNxsMsg* RsNxsSerialiser::deserialNxsMsg(void *data, uint32_t *size){
offset += 8; offset += 8;
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber)); ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
ok &= getRawUInt8(data, *size, &offset, &(item->pos));
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_MSGID, item->msgId); ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_MSGID, item->msgId);
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId); ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= item->msg.GetTlv(data, *size, &offset); ok &= item->msg.GetTlv(data, *size, &offset);
@ -1015,6 +1019,7 @@ uint32_t RsNxsSerialiser::sizeNxsMsg(RsNxsMsg *item)
uint32_t s = 8; //header size uint32_t s = 8; //header size
s += 4; // transaction number s += 4; // transaction number
s += 1; // pos
s += GetTlvStringSize(item->grpId); s += GetTlvStringSize(item->grpId);
s += GetTlvStringSize(item->msgId); s += GetTlvStringSize(item->msgId);
s += item->msg.TlvSize(); s += item->msg.TlvSize();
@ -1028,6 +1033,7 @@ uint32_t RsNxsSerialiser::sizeNxsGrp(RsNxsGrp *item)
uint32_t s = 8; // header size uint32_t s = 8; // header size
s += 4; // transaction number s += 4; // transaction number
s += 1; // pos
s += GetTlvStringSize(item->grpId); s += GetTlvStringSize(item->grpId);
s += item->grp.TlvSize(); s += item->grp.TlvSize();
s += item->meta.TlvSize(); s += item->meta.TlvSize();
@ -1106,9 +1112,9 @@ uint32_t RsNxsSerialiser::sizeNxsExtended(RsNxsExtended *item){
return 0; return 0;
} }
int RsNxsGrp::refcount = 0;
/** print and clear functions **/ /** print and clear functions **/
int RsNxsMsg::refcount = 0;
void RsNxsMsg::clear() void RsNxsMsg::clear()
{ {
@ -1253,6 +1259,8 @@ std::ostream& RsNxsGrp::print(std::ostream &out, uint16_t indent){
out << "grpId: " << grpId << std::endl; out << "grpId: " << grpId << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "grp: " << std::endl; out << "grp: " << std::endl;
printIndent(out , int_Indent);
out << "pos: " << pos << std::endl;
grp.print(out, int_Indent); grp.print(out, int_Indent);
out << "meta: " << std::endl; out << "meta: " << std::endl;
meta.print(out, int_Indent); meta.print(out, int_Indent);
@ -1269,6 +1277,8 @@ std::ostream& RsNxsMsg::print(std::ostream &out, uint16_t indent){
out << "msgId: " << msgId << std::endl; out << "msgId: " << msgId << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "grpId: " << grpId << std::endl; out << "grpId: " << grpId << std::endl;
printIndent(out , int_Indent);
out << "pos: " << pos << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "msg: " << std::endl; out << "msg: " << std::endl;
msg.print(out, indent); msg.print(out, indent);

View File

@ -73,6 +73,7 @@ public:
setPriorityLevel(QOS_PRIORITY_RS_VOIP_PING); setPriorityLevel(QOS_PRIORITY_RS_VOIP_PING);
return; return;
} }
virtual ~RsNxsItem(){ return; }
virtual void clear() = 0; virtual void clear() = 0;
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0) = 0; virtual std::ostream &print(std::ostream &out, uint16_t indent = 0) = 0;
@ -188,15 +189,21 @@ class RsNxsGrp : public RsNxsItem
public: public:
RsNxsGrp(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP), grp(servtype), meta(servtype), RsNxsGrp(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP), grp(servtype), meta(servtype),
metaData(NULL) { clear(); return; } metaData(NULL) { clear();
virtual ~RsNxsGrp() { if(metaData) delete metaData; } //std::cout << "\nGrp refcount++ : " << ++refcount << std::endl;
return; }
virtual ~RsNxsGrp() { if(metaData) delete metaData;
//std::cout << "\nGrp refcount-- : " << --refcount << std::endl;
}
virtual void clear(); virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::string grpId; /// group Id, needed to complete version Id (ncvi) std::string grpId; /// group Id, needed to complete version Id (ncvi)
static int refcount;
RsTlvBinaryData grp; /// actual group data RsTlvBinaryData grp; /// actual group data
uint8_t pos; /// used for splitting up grp
uint8_t count; /// number of split up messages
/*! /*!
* This should contains all data * This should contains all data
@ -263,15 +270,27 @@ class RsNxsMsg : public RsNxsItem
public: public:
RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG), meta(servtype), msg(servtype), RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG), meta(servtype), msg(servtype),
metaData(NULL) { clear(); return; } metaData(NULL) {
~RsNxsMsg() { if(metaData) delete metaData; } // std::cout << "\nrefcount++ : " << ++refcount << std::endl;
clear(); return;
}
virtual ~RsNxsMsg()
{
//std::cout << "\nrefcount-- : " << --refcount << std::endl;
if(metaData){
//std::cout << "\ndeleted\n";
delete metaData;
}
}
virtual void clear(); virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint8_t pos; /// used for splitting up msg
uint8_t count; /// number of split up messages
std::string grpId; /// group id, forms part of version id std::string grpId; /// group id, forms part of version id
std::string msgId; /// msg id std::string msgId; /// msg id
static int refcount;
/*! /*!
* This should contains all the data * This should contains all the data
* which is not specific to the Gxs service data * which is not specific to the Gxs service data

View File

@ -691,21 +691,24 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item)
for (kit = keySet.keys.begin(); kit != keySet.keys.end(); kit++) for (kit = keySet.keys.begin(); kit != keySet.keys.end(); kit++)
{ {
if (kit->second.keyFlags | RSTLV_KEY_DISTRIB_ADMIN) if (kit->second.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
{ {
std::cerr << "p3IdService::cache_store() Found Admin Key"; std::cerr << "p3IdService::cache_store() Found Admin Key";
std::cerr << std::endl; std::cerr << std::endl;
/* save full key - if we have it */ /* save full key - if we have it */
if (kit->second.keyFlags | RSTLV_KEY_TYPE_FULL) if (kit->second.keyFlags & RSTLV_KEY_TYPE_FULL)
{ {
fullkey = kit->second; fullkey = kit->second;
full_key_ok = true; full_key_ok = true;
} }
/* cache public key always */ if (kit->second.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY)
pubkey = kit->second; {
pub_key_ok = true; /* cache public key always */
pubkey = kit->second;
pub_key_ok = true;
}
} }
} }

View File

@ -68,18 +68,18 @@ void p3Posted::service_tick()
generatePosts(); generatePosts();
generateVotesAndComments(); generateVotesAndComments();
time_t now = time(NULL); // time_t now = time(NULL);
//
if((now > (time_t) (VOTE_UPDATE_PERIOD + mLastUpdate)) && // if((now > (time_t) (VOTE_UPDATE_PERIOD + mLastUpdate)) &&
(mUpdatePhase == UPDATE_PHASE_GRP_REQUEST)) // (mUpdatePhase == UPDATE_PHASE_GRP_REQUEST))
{ // {
mPostUpdate = true; // mPostUpdate = true;
mLastUpdate = time(NULL); // mLastUpdate = time(NULL);
} // }
//
updateVotes(); // updateVotes();
//
processRankings(); // processRankings();
} }
void p3Posted::generateVotesAndComments() void p3Posted::generateVotesAndComments()
@ -505,7 +505,6 @@ bool p3Posted::requestPostRankings(uint32_t &token, const RankType &rType, const
gp->pubToken = token; gp->pubToken = token;
gp->rankingResult.rType = gp->rType; gp->rankingResult.rType = gp->rType;
gp->rankingResult.grpId = gp->grpId; gp->rankingResult.grpId = gp->grpId;
gp->grpId = gp->grpId;
mPendingPostRanks.push_back(gp); mPendingPostRanks.push_back(gp);
@ -768,6 +767,7 @@ bool p3Posted::completePostedPostCalc(GxsPostedPostRanking *gpp)
break; break;
default: default:
std::cerr << "Unknown ranking tpye: " << gpp->rType << std::endl; std::cerr << "Unknown ranking tpye: " << gpp->rType << std::endl;
break;
} }
return true; return true;
}else }else

View File

@ -24,6 +24,8 @@ PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const RsPhotoPhoto &photo, QW
ui->lineEdit_PhotoGrapher->setVisible(false); ui->lineEdit_PhotoGrapher->setVisible(false);
setUp(); setUp();
ui->idChooser->setVisible(false);
} }
PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget *parent) : PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget *parent) :
@ -43,6 +45,8 @@ PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget
connect(ui->lineEdit_Title, SIGNAL(editingFinished()), this, SLOT(setTitle())); connect(ui->lineEdit_Title, SIGNAL(editingFinished()), this, SLOT(setTitle()));
connect(ui->lineEdit_PhotoGrapher, SIGNAL(editingFinished()), this, SLOT(setPhotoGrapher())); connect(ui->lineEdit_PhotoGrapher, SIGNAL(editingFinished()), this, SLOT(setPhotoGrapher()));
ui->idChooser->loadIds(0, "");
} }
void PhotoItem::setSelected(bool selected) void PhotoItem::setSelected(bool selected)
@ -101,6 +105,15 @@ void PhotoItem::setPhotoGrapher()
const RsPhotoPhoto& PhotoItem::getPhotoDetails() const RsPhotoPhoto& PhotoItem::getPhotoDetails()
{ {
if(ui->idChooser->isVisible())
{
RsGxsId id;
ui->idChooser->getChosenId(id);
mPhotoDetails.mMeta.mAuthorId = id;
}
return mPhotoDetails; return mPhotoDetails;
} }

View File

@ -28,7 +28,7 @@ border-radius: 10px}</string>
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QLabel" name="label_Thumbnail"> <widget class="QLabel" name="label_Thumbnail">
<property name="text"> <property name="text">
@ -67,6 +67,17 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="identity">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; font-weight:600;&quot;&gt;Author :&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -81,6 +92,9 @@ p, li { white-space: pre-wrap; }
<item> <item>
<widget class="QLineEdit" name="lineEdit_PhotoGrapher"/> <widget class="QLineEdit" name="lineEdit_PhotoGrapher"/>
</item> </item>
<item>
<widget class="GxsIdChooser" name="idChooser"/>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -105,6 +119,13 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>GxsIdChooser</class>
<extends>QComboBox</extends>
<header>gui/gxs/GxsIdChooser.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@ -223,7 +223,7 @@ void PostedListDialog::updateDisplay()
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs; std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs;
if (rsPosted->updated()) if (rsPosted->updated(true, true))
{ {
/* update Forums List */ /* update Forums List */