mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-30 18:06:18 -05:00
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:
parent
635f915f46
commit
7867063734
@ -130,6 +130,10 @@ bool GxsSecurity::validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSe
|
||||
RsTlvKeySignatureSet signSet = msgMeta.signSet;
|
||||
msgMeta.signSet.TlvClear();
|
||||
|
||||
RsGxsMessageId msgId = msgMeta.mMsgId, origMsgId = msgMeta.mOrigMsgId;
|
||||
msgMeta.mOrigMsgId.clear();
|
||||
msgMeta.mMsgId.clear();
|
||||
|
||||
uint32_t metaDataLen = msgMeta.serial_size();
|
||||
uint32_t allMsgDataLen = metaDataLen + msg.msg.bin_len;
|
||||
char* metaData = new char[metaDataLen];
|
||||
@ -156,6 +160,9 @@ bool GxsSecurity::validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSe
|
||||
EVP_PKEY_free(signKey);
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
|
||||
msgMeta.mOrigMsgId = origMsgId;
|
||||
msgMeta.mMsgId = msgId;
|
||||
msgMeta.signSet = signSet;
|
||||
|
||||
if (signOk == 1)
|
||||
{
|
||||
|
@ -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_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,
|
||||
RsGxsSearchModule *mod)
|
||||
@ -453,6 +454,9 @@ int RsDataService::storeMessage(std::map<RsNxsMsg *, RsGxsMsgMetaData *> &msg)
|
||||
RsNxsMsg* msgPtr = mit->first;
|
||||
RsGxsMsgMetaData* msgMetaPtr = mit->second;
|
||||
|
||||
// skip msg item if size if greater than
|
||||
if(!validSize(msgPtr)) continue;
|
||||
|
||||
// create or access file in binary
|
||||
std::string msgFile = mServiceDir + "/" + msgPtr->grpId + "-msgs";
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -536,6 +547,9 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
|
||||
RsNxsGrp* grpPtr = sit->first;
|
||||
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::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
|
||||
@ -607,6 +621,12 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
|
||||
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){
|
||||
|
||||
if(grp.empty()){
|
||||
@ -969,6 +989,7 @@ int RsDataService::resetDataStore()
|
||||
std::string msgFile = file + "-msgs";
|
||||
remove(file.c_str()); // remove group file
|
||||
remove(msgFile.c_str()); // and remove messages file
|
||||
delete mit->second;
|
||||
}
|
||||
{
|
||||
RsStackMutex stack(mDbMutex);
|
||||
|
@ -132,6 +132,11 @@ public:
|
||||
*/
|
||||
int resetDataStore();
|
||||
|
||||
|
||||
bool validSize(RsNxsMsg* msg) const;
|
||||
bool validSize(RsNxsGrp* grp) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/*!
|
||||
|
@ -105,6 +105,8 @@ class RsGeneralDataService
|
||||
|
||||
public:
|
||||
|
||||
static const uint32_t GXS_MAX_ITEM_SIZE;
|
||||
|
||||
static const std::string MSG_META_SERV_STRING;
|
||||
static const std::string MSG_META_STATUS;
|
||||
|
||||
@ -210,6 +212,22 @@ public:
|
||||
*/
|
||||
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 ;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -101,20 +101,20 @@ void RsGenExchange::tick()
|
||||
|
||||
publishMsgs();
|
||||
|
||||
processGrpMetaChanges();
|
||||
processGrpMetaChanges();
|
||||
|
||||
processMsgMetaChanges();
|
||||
processMsgMetaChanges();
|
||||
|
||||
processRecvdData();
|
||||
processRecvdData();
|
||||
|
||||
if(!mNotifications.empty())
|
||||
{
|
||||
notifyChanges(mNotifications);
|
||||
mNotifications.clear();
|
||||
}
|
||||
if(!mNotifications.empty())
|
||||
{
|
||||
notifyChanges(mNotifications);
|
||||
mNotifications.clear();
|
||||
}
|
||||
|
||||
// implemented service tick function
|
||||
service_tick();
|
||||
// implemented service tick function
|
||||
service_tick();
|
||||
}
|
||||
|
||||
bool RsGenExchange::acknowledgeTokenMsg(const uint32_t& token,
|
||||
@ -160,7 +160,8 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token,
|
||||
return true;
|
||||
}
|
||||
|
||||
void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys)
|
||||
void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet,
|
||||
RsTlvSecurityKeySet& publickeySet, bool genPublishKeys)
|
||||
{
|
||||
/* create Keys */
|
||||
|
||||
@ -174,8 +175,10 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPubli
|
||||
GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub);
|
||||
GxsSecurity::setRSAPrivateKey(privAdminKey, rsa_admin);
|
||||
|
||||
adminKey.keyId = adminKey.keyId + "_public";
|
||||
|
||||
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.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;
|
||||
privAdminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL;
|
||||
|
||||
keySet.keys[adminKey.keyId] = adminKey;
|
||||
keySet.keys[privAdminKey.keyId] = privAdminKey;
|
||||
publickeySet.keys[adminKey.keyId] = adminKey;
|
||||
privatekeySet.keys[privAdminKey.keyId] = privAdminKey;
|
||||
|
||||
// clean up
|
||||
RSA_free(rsa_admin);
|
||||
@ -204,6 +207,7 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPubli
|
||||
GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish);
|
||||
|
||||
pubKey.startTS = adminKey.startTS;
|
||||
pubKey.keyId = pubKey.keyId + "_public";
|
||||
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
|
||||
|
||||
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;
|
||||
privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL;
|
||||
|
||||
keySet.keys[pubKey.keyId] = pubKey;
|
||||
keySet.keys[privPubKey.keyId] = privPubKey;
|
||||
publickeySet.keys[pubKey.keyId] = pubKey;
|
||||
privatekeySet.keys[privPubKey.keyId] = privPubKey;
|
||||
|
||||
RSA_free(rsa_publish);
|
||||
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 << std::endl;
|
||||
@ -233,22 +236,14 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
|
||||
|
||||
// find private admin key
|
||||
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;
|
||||
for(; mit != keySet.keys.end(); mit++)
|
||||
bool privKeyFound = false; // private admin key
|
||||
for(; mit != privateKeySet.keys.end(); mit++)
|
||||
{
|
||||
RsTlvSecurityKey& key = mit->second;
|
||||
|
||||
// add public admin key
|
||||
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))
|
||||
if((key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (key.keyFlags & RSTLV_KEY_TYPE_FULL))
|
||||
{
|
||||
privAdminKey = key;
|
||||
privKeyFound = true;
|
||||
@ -263,6 +258,8 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
|
||||
return false;
|
||||
}
|
||||
|
||||
meta->keys = publicKeySet; // only public keys are included to be transported
|
||||
|
||||
// group is self signing
|
||||
// for the creation of group signature
|
||||
// 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);
|
||||
|
||||
// but meta that is stored locally
|
||||
// has all keys
|
||||
// has private keys
|
||||
// nxs net transports only bin data
|
||||
meta->keys = keySet;
|
||||
meta->keys = privateKeySet;
|
||||
|
||||
// clean up
|
||||
delete[] allGrpData;
|
||||
@ -432,7 +429,7 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina
|
||||
|
||||
// poll immediately but, don't spend more than a second polling
|
||||
while( (mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey) == -1) &&
|
||||
((now + 1) >> time(NULL))
|
||||
((now + 5) > time(NULL))
|
||||
)
|
||||
{
|
||||
#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];
|
||||
|
||||
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];
|
||||
valid &= GxsSecurity::validateNxsMsg(*msg, sign, publishKey);
|
||||
RsTlvSecurityKey& key = mit->second;
|
||||
|
||||
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
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -647,7 +658,7 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec
|
||||
#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);
|
||||
}else
|
||||
{
|
||||
@ -808,14 +819,14 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vector<RsGxsGrpItem
|
||||
{
|
||||
RsGxsGrpItem* gItem = dynamic_cast<RsGxsGrpItem*>(item);
|
||||
gItem->meta = *((*lit)->metaData);
|
||||
grpItem.push_back(gItem);
|
||||
delete *lit;
|
||||
grpItem.push_back(gItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "RsGenExchange::getGroupData() ERROR deserialising item";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
delete *lit;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
@ -935,16 +946,20 @@ bool RsGenExchange::setAuthenPolicyFlag(const uint8_t &msgFlag, uint32_t& authen
|
||||
|
||||
void RsGenExchange::notifyNewGroups(std::vector<RsNxsGrp *> &groups)
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
|
||||
std::vector<RsNxsGrp*>::iterator vit = groups.begin();
|
||||
|
||||
// store these for tick() to pick them up
|
||||
for(; vit != groups.end(); vit++)
|
||||
mReceivedGrps.push_back(*vit);
|
||||
mReceivedGrps.push_back(*vit);
|
||||
|
||||
}
|
||||
|
||||
void RsGenExchange::notifyNewMessages(std::vector<RsNxsMsg *>& messages)
|
||||
{
|
||||
RsStackMutex stack(mGenMtx);
|
||||
|
||||
std::vector<RsNxsMsg*>::iterator vit = messages.begin();
|
||||
|
||||
// store these for tick() to pick them up
|
||||
@ -1225,7 +1240,7 @@ void RsGenExchange::publishMsgs()
|
||||
RsGxsMessageId msgId;
|
||||
RsGxsGroupId grpId = msgItem->meta.mGroupId;
|
||||
|
||||
bool msgDoesnExist = false;
|
||||
bool msgDoesnExist = false, validSize = false;
|
||||
|
||||
if(createOk)
|
||||
{
|
||||
@ -1247,6 +1262,11 @@ void RsGenExchange::publishMsgs()
|
||||
}
|
||||
|
||||
if(createOk && msgDoesnExist)
|
||||
{
|
||||
validSize = mDataStore->validSize(msg);
|
||||
}
|
||||
|
||||
if(createOk && msgDoesnExist && validSize)
|
||||
{
|
||||
// empty orig msg id means this is the original
|
||||
// msg
|
||||
@ -1334,16 +1354,16 @@ void RsGenExchange::publishGrps()
|
||||
RsNxsGrp* grp = new RsNxsGrp(mServType);
|
||||
RsGxsGrpItem* grpItem = mit->second;
|
||||
|
||||
RsTlvSecurityKeySet keySet;
|
||||
generateGroupKeys(keySet,
|
||||
RsTlvSecurityKeySet privatekeySet, publicKeySet, tempKeySet;
|
||||
generateGroupKeys(privatekeySet, publicKeySet,
|
||||
!(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC));
|
||||
|
||||
// find private admin key
|
||||
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;
|
||||
for(; mit_keys != keySet.keys.end(); mit_keys++)
|
||||
for(; mit_keys != privatekeySet.keys.end(); mit_keys++)
|
||||
{
|
||||
RsTlvSecurityKey& key = mit_keys->second;
|
||||
|
||||
@ -1366,8 +1386,14 @@ void RsGenExchange::publishGrps()
|
||||
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);
|
||||
char gData[size];
|
||||
@ -1387,21 +1413,28 @@ void RsGenExchange::publishGrps()
|
||||
*(grp->metaData) = grpItem->meta;
|
||||
grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN;
|
||||
|
||||
ok &= createGroup(grp, keySet);
|
||||
|
||||
if (!ok)
|
||||
if (!createGroup(grp, privatekeySet, publicKeySet))
|
||||
{
|
||||
std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
RsGxsGroupId grpId = grp->grpId;
|
||||
mDataAccess->addGroupData(grp);
|
||||
// ensure group size is not too large
|
||||
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
|
||||
mGrpNotify.insert(std::make_pair(mit->first, grpId));
|
||||
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
|
||||
std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl;
|
||||
|
||||
// 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)
|
||||
@ -1485,16 +1518,16 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem)
|
||||
bool ok = mSerialiser->serialise(grpItem, gData, &size);
|
||||
grp->grp.setBinData(gData, size);
|
||||
|
||||
RsTlvSecurityKeySet keySet;
|
||||
generateGroupKeys(keySet,
|
||||
RsTlvSecurityKeySet privateKeySet, publicKeySet;
|
||||
generateGroupKeys(privateKeySet, publicKeySet,
|
||||
!(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC));
|
||||
|
||||
// find private admin key
|
||||
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;
|
||||
for(; mit_keys != keySet.keys.end(); mit_keys++)
|
||||
for(; mit_keys != privateKeySet.keys.end(); mit_keys++)
|
||||
{
|
||||
RsTlvSecurityKey& key = mit_keys->second;
|
||||
|
||||
@ -1516,7 +1549,7 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem)
|
||||
ok = false;
|
||||
}
|
||||
|
||||
service_CreateGroup(grpItem, keySet);
|
||||
service_CreateGroup(grpItem, privateKeySet);
|
||||
|
||||
if(ok)
|
||||
{
|
||||
@ -1524,7 +1557,7 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem)
|
||||
grpItem->meta.mPublishTs = time(NULL);
|
||||
*(grp->metaData) = grpItem->meta;
|
||||
grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN;
|
||||
createGroup(grp, keySet);
|
||||
createGroup(grp, privateKeySet, publicKeySet);
|
||||
|
||||
mDataAccess->addGroupData(grp);
|
||||
}
|
||||
@ -1584,9 +1617,9 @@ void RsGenExchange::processRecvdMessages()
|
||||
if(mit != grpMetas.end()){
|
||||
RsGxsGrpMetaData* grpMeta = mit->second;
|
||||
ok = true;
|
||||
// msg->metaData = meta;
|
||||
// ok &= validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys);
|
||||
// msg->metaData = NULL;
|
||||
msg->metaData = meta;
|
||||
ok &= validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys);
|
||||
msg->metaData = NULL;
|
||||
}
|
||||
else
|
||||
ok = false;
|
||||
|
@ -254,7 +254,8 @@ protected:
|
||||
&msg->msg.bin_len);
|
||||
GxsMsgType* mItem = dynamic_cast<GxsMsgType*>(item);
|
||||
|
||||
if(mItem == NULL){
|
||||
if(mItem == NULL)
|
||||
{
|
||||
delete msg;
|
||||
continue;
|
||||
}
|
||||
@ -474,7 +475,7 @@ private:
|
||||
* Meta is serialised and stored in group at this point also
|
||||
* @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
|
||||
@ -503,10 +504,11 @@ private:
|
||||
|
||||
/*!
|
||||
* Generate a set of keys that can define a GXS group
|
||||
* @param keySet this is set generated keys
|
||||
* @param genPublicKeys should public keys also be generated
|
||||
* @param privatekeySet contains private generated keys
|
||||
* @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
|
||||
|
@ -142,9 +142,17 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize)
|
||||
|
||||
return ok;
|
||||
}
|
||||
int RsGxsMsgMetaData::refcount = 0;
|
||||
|
||||
RsGxsMsgMetaData::RsGxsMsgMetaData(){
|
||||
|
||||
//std::cout << "\nrefcount++ : " << ++refcount << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsGxsMsgMetaData::~RsGxsMsgMetaData(){
|
||||
//std::cout << "\nrefcount-- : " << --refcount << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t RsGxsMsgMetaData::serial_size()
|
||||
|
@ -87,7 +87,8 @@ class RsGxsMsgMetaData
|
||||
{
|
||||
public:
|
||||
|
||||
RsGxsMsgMetaData();
|
||||
explicit RsGxsMsgMetaData();
|
||||
~RsGxsMsgMetaData();
|
||||
bool deserialise(void *data, uint32_t *size);
|
||||
bool serialise(void* data, uint32_t *size);
|
||||
uint32_t serial_size();
|
||||
@ -96,7 +97,7 @@ public:
|
||||
|
||||
RsGxsGroupId mGroupId;
|
||||
RsGxsMessageId mMsgId;
|
||||
|
||||
static int refcount;
|
||||
RsGxsMessageId mThreadId;
|
||||
RsGxsMessageId mParentId;
|
||||
RsGxsMessageId mOrigMsgId;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
*/
|
||||
RsGxsIfaceImpl(RsGenExchange* gxs);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Gxs services should call this for automatic handling of
|
||||
* changes, send
|
||||
@ -53,14 +54,20 @@ public:
|
||||
*/
|
||||
void receiveChanges(std::vector<RsGxsNotify*>& changes);
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Checks to see if a change has been received for
|
||||
* 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
|
||||
* @see groupsChanged
|
||||
* @see msgsChanged
|
||||
*/
|
||||
virtual bool updated();
|
||||
|
||||
public:
|
||||
virtual bool updated(bool willCallGrpChanged = false, bool willCallMsgChanged = false);
|
||||
|
||||
/*!
|
||||
* The groups changed. \n
|
||||
@ -68,7 +75,8 @@ public:
|
||||
* the group actually set for ui notification.
|
||||
* If receivedChanges is not passed RsGxsNotify changes
|
||||
* this function does nothing
|
||||
* @param grpIds
|
||||
* @param grpIds returns list of grpIds that have changed
|
||||
* @see updated
|
||||
*/
|
||||
virtual void groupsChanged(std::list<RsGxsGroupId>& grpIds);
|
||||
|
||||
@ -78,7 +86,8 @@ public:
|
||||
* the msg actually set for ui notification.
|
||||
* If receivedChanges is not passed RsGxsNotify changes
|
||||
* this function does nothing
|
||||
* @param msgs
|
||||
* @param msgs returns map of message ids that have changed
|
||||
* @see updated
|
||||
*/
|
||||
virtual void msgsChanged(std::map<RsGxsGroupId,
|
||||
std::vector<RsGxsMessageId> >& msgs);
|
||||
|
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "rsgxsnetservice.h"
|
||||
#include "rsgxsflags.h"
|
||||
@ -34,6 +35,7 @@
|
||||
#define SYNC_PERIOD 12 // in microseconds every 10 seconds (1 second for testing)
|
||||
#define TRANSAC_TIMEOUT 5 // 5 seconds
|
||||
|
||||
const uint32_t RsGxsNetService::FRAGMENT_SIZE = 150000;
|
||||
|
||||
RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
|
||||
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs)
|
||||
@ -79,15 +81,14 @@ void RsGxsNetService::syncWithPeers()
|
||||
|
||||
std::set<std::string>::iterator sit = peers.begin();
|
||||
|
||||
// for now just grps
|
||||
for(; sit != peers.end(); sit++)
|
||||
{
|
||||
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
|
||||
grp->clear();
|
||||
grp->PeerId(*sit);
|
||||
sendItem(grp);
|
||||
}
|
||||
|
||||
// for now just grps
|
||||
for(; sit != peers.end(); sit++)
|
||||
{
|
||||
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
|
||||
grp->clear();
|
||||
grp->PeerId(*sit);
|
||||
sendItem(grp);
|
||||
}
|
||||
|
||||
#ifdef GXS_ENABLE_SYNC_MSGS
|
||||
std::map<RsGxsGroupId, RsGxsGrpMetaData* > grpMeta;
|
||||
@ -130,6 +131,236 @@ void RsGxsNetService::syncWithPeers()
|
||||
#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)
|
||||
{
|
||||
return false;
|
||||
@ -152,41 +383,42 @@ void RsGxsNetService::recvNxsItemQueue(){
|
||||
while(NULL != (item=recvItem()))
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG
|
||||
std::cerr << "RsGxsNetService Item:" << (void*)item << std::endl ;
|
||||
std::cerr << "RsGxsNetService Item:" << (void*)item << std::endl ;
|
||||
#endif
|
||||
// RsNxsItem needs dynamic_cast, since they have derived siblings.
|
||||
//
|
||||
RsNxsItem *ni = dynamic_cast<RsNxsItem*>(item) ;
|
||||
if(ni != NULL)
|
||||
{
|
||||
// RsNxsItem needs dynamic_cast, since they have derived siblings.
|
||||
//
|
||||
RsNxsItem *ni = dynamic_cast<RsNxsItem*>(item) ;
|
||||
if(ni != NULL)
|
||||
{
|
||||
|
||||
// a live transaction has a non zero value
|
||||
if(ni->transactionNumber != 0){
|
||||
// a live transaction has a non zero value
|
||||
if(ni->transactionNumber != 0){
|
||||
|
||||
#ifdef NXS_NET_DEBUG
|
||||
std::cerr << "recvNxsItemQueue()" << std::endl;
|
||||
std::cerr << "handlingTransaction, transN" << ni->transactionNumber << std::endl;
|
||||
std::cerr << "recvNxsItemQueue()" << std::endl;
|
||||
std::cerr << "handlingTransaction, transN" << ni->transactionNumber << std::endl;
|
||||
#endif
|
||||
|
||||
if(handleTransaction(ni))
|
||||
continue ;
|
||||
}
|
||||
if(handleTransaction(ni))
|
||||
continue ;
|
||||
}
|
||||
|
||||
|
||||
switch(ni->PacketSubType())
|
||||
{
|
||||
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 ;
|
||||
default:
|
||||
std::cerr << "Unhandled item subtype " << ni->PacketSubType() << " in RsGxsNetService: " << std::endl; break;
|
||||
}
|
||||
delete item ;
|
||||
}
|
||||
switch(ni->PacketSubType())
|
||||
{
|
||||
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 ;
|
||||
default:
|
||||
std::cerr << "Unhandled item subtype " << ni->PacketSubType() << " in RsGxsNetService: " << std::endl; break;
|
||||
}
|
||||
delete item ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
||||
bool RsGxsNetService::handleTransaction(RsNxsItem* item)
|
||||
{
|
||||
|
||||
/*!
|
||||
* This attempts to handle a transaction
|
||||
@ -201,9 +433,9 @@ bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
||||
RsNxsTransac* transItem = dynamic_cast<RsNxsTransac*>(item);
|
||||
|
||||
// if this is a RsNxsTransac item process
|
||||
if(transItem){
|
||||
if(transItem)
|
||||
return locked_processTransac(transItem);
|
||||
}
|
||||
|
||||
|
||||
// then this must be transaction content to be consumed
|
||||
// first check peer exist for transaction
|
||||
@ -221,7 +453,8 @@ bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
||||
|
||||
transExists = transMap.find(transN) != transMap.end();
|
||||
|
||||
if(transExists){
|
||||
if(transExists)
|
||||
{
|
||||
|
||||
#ifdef NXS_NET_DEBUG
|
||||
std::cerr << "handleTransaction() " << std::endl;
|
||||
@ -231,13 +464,12 @@ bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
||||
|
||||
tr = transMap[transN];
|
||||
tr->mItems.push_back(item);
|
||||
}
|
||||
|
||||
}else{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RsGxsNetService::locked_processTransac(RsNxsTransac* item)
|
||||
@ -368,8 +600,8 @@ void RsGxsNetService::run(){
|
||||
|
||||
bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr)
|
||||
{
|
||||
return tr->mTimeOut < ((uint32_t) time(NULL));
|
||||
// return false;
|
||||
//return tr->mTimeOut < ((uint32_t) time(NULL));
|
||||
return false;
|
||||
}
|
||||
|
||||
void RsGxsNetService::processTransactions(){
|
||||
@ -1027,7 +1259,7 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
|
||||
|
||||
uint32_t transN = locked_getTransactionId();
|
||||
|
||||
// store msg items to send in transaction
|
||||
// store msg items to send in transaction
|
||||
GxsMsgResult::iterator mit = msgs.begin();
|
||||
std::string peerId = tr->mTransaction->PeerId();
|
||||
uint32_t msgSize = 0;
|
||||
|
@ -133,7 +133,7 @@ class RsGxsNetService : public RsNetworkExchangeService, public p3ThreadedServic
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
static const uint32_t FRAGMENT_SIZE;
|
||||
/*!
|
||||
* only one observer is allowed
|
||||
* @param servType service type
|
||||
@ -365,6 +365,60 @@ 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 ***/
|
||||
|
||||
/// active transactions
|
||||
|
@ -58,6 +58,7 @@ class GroupIdReq : public GxsRequest
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
std::list<std::string> mGroupIds;
|
||||
std::list<std::string> mGroupIdResult;
|
||||
};
|
||||
|
@ -2263,7 +2263,6 @@ int RsServer::StartupRetroShare()
|
||||
mPluginsManager->registerClientServices(pqih) ;
|
||||
mPluginsManager->registerCacheServices() ;
|
||||
|
||||
|
||||
#ifdef RS_ENABLE_GXS
|
||||
|
||||
// The idea is that if priorGxsDir is non
|
||||
@ -2331,9 +2330,9 @@ int RsServer::StartupRetroShare()
|
||||
RsGenExchange::RESTRICTED_GRP_BITS);
|
||||
|
||||
// Re-enable later, photo not using gixs yet
|
||||
// flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
|
||||
// RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy,
|
||||
// RsGenExchange::RESTRICTED_GRP_BITS);
|
||||
flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN; // should be GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN for comments
|
||||
RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy,
|
||||
RsGenExchange::RESTRICTED_GRP_BITS);
|
||||
|
||||
flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN;
|
||||
RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy,
|
||||
|
@ -248,6 +248,7 @@ bool RsNxsSerialiser::serialiseNxsMsg(RsNxsMsg *item, void *data, uint32_t *size
|
||||
offset += 8;
|
||||
|
||||
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_GROUPID, item->grpId);
|
||||
ok &= item->msg.SetTlv(data, tlvsize, &offset);
|
||||
@ -299,6 +300,7 @@ bool RsNxsSerialiser::serialiseNxsGrp(RsNxsGrp *item, void *data, uint32_t *size
|
||||
|
||||
// grp id
|
||||
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 &= item->grp.SetTlv(data, tlvsize, &offset);
|
||||
ok &= item->meta.SetTlv(data, *size, &offset);
|
||||
@ -564,6 +566,7 @@ RsNxsGrp* RsNxsSerialiser::deserialNxsGrp(void *data, uint32_t *size){
|
||||
offset += 8;
|
||||
|
||||
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 &= item->grp.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;
|
||||
|
||||
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_GROUPID, item->grpId);
|
||||
ok &= item->msg.GetTlv(data, *size, &offset);
|
||||
@ -1015,6 +1019,7 @@ uint32_t RsNxsSerialiser::sizeNxsMsg(RsNxsMsg *item)
|
||||
uint32_t s = 8; //header size
|
||||
|
||||
s += 4; // transaction number
|
||||
s += 1; // pos
|
||||
s += GetTlvStringSize(item->grpId);
|
||||
s += GetTlvStringSize(item->msgId);
|
||||
s += item->msg.TlvSize();
|
||||
@ -1028,6 +1033,7 @@ uint32_t RsNxsSerialiser::sizeNxsGrp(RsNxsGrp *item)
|
||||
uint32_t s = 8; // header size
|
||||
|
||||
s += 4; // transaction number
|
||||
s += 1; // pos
|
||||
s += GetTlvStringSize(item->grpId);
|
||||
s += item->grp.TlvSize();
|
||||
s += item->meta.TlvSize();
|
||||
@ -1106,9 +1112,9 @@ uint32_t RsNxsSerialiser::sizeNxsExtended(RsNxsExtended *item){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int RsNxsGrp::refcount = 0;
|
||||
/** print and clear functions **/
|
||||
|
||||
int RsNxsMsg::refcount = 0;
|
||||
void RsNxsMsg::clear()
|
||||
{
|
||||
|
||||
@ -1253,6 +1259,8 @@ std::ostream& RsNxsGrp::print(std::ostream &out, uint16_t indent){
|
||||
out << "grpId: " << grpId << std::endl;
|
||||
printIndent(out , int_Indent);
|
||||
out << "grp: " << std::endl;
|
||||
printIndent(out , int_Indent);
|
||||
out << "pos: " << pos << std::endl;
|
||||
grp.print(out, int_Indent);
|
||||
out << "meta: " << std::endl;
|
||||
meta.print(out, int_Indent);
|
||||
@ -1269,6 +1277,8 @@ std::ostream& RsNxsMsg::print(std::ostream &out, uint16_t indent){
|
||||
out << "msgId: " << msgId << std::endl;
|
||||
printIndent(out , int_Indent);
|
||||
out << "grpId: " << grpId << std::endl;
|
||||
printIndent(out , int_Indent);
|
||||
out << "pos: " << pos << std::endl;
|
||||
printIndent(out , int_Indent);
|
||||
out << "msg: " << std::endl;
|
||||
msg.print(out, indent);
|
||||
|
@ -73,6 +73,7 @@ public:
|
||||
setPriorityLevel(QOS_PRIORITY_RS_VOIP_PING);
|
||||
return;
|
||||
}
|
||||
virtual ~RsNxsItem(){ return; }
|
||||
|
||||
virtual void clear() = 0;
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0) = 0;
|
||||
@ -188,15 +189,21 @@ class RsNxsGrp : public RsNxsItem
|
||||
public:
|
||||
|
||||
RsNxsGrp(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP), grp(servtype), meta(servtype),
|
||||
metaData(NULL) { clear(); return; }
|
||||
virtual ~RsNxsGrp() { if(metaData) delete metaData; }
|
||||
metaData(NULL) { clear();
|
||||
//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 std::ostream &print(std::ostream &out, uint16_t indent);
|
||||
|
||||
std::string grpId; /// group Id, needed to complete version Id (ncvi)
|
||||
|
||||
static int refcount;
|
||||
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
|
||||
@ -263,15 +270,27 @@ class RsNxsMsg : public RsNxsItem
|
||||
public:
|
||||
|
||||
RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG), meta(servtype), msg(servtype),
|
||||
metaData(NULL) { clear(); return; }
|
||||
~RsNxsMsg() { if(metaData) delete metaData; }
|
||||
metaData(NULL) {
|
||||
// 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 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 msgId; /// msg id
|
||||
|
||||
static int refcount;
|
||||
/*!
|
||||
* This should contains all the data
|
||||
* which is not specific to the Gxs service data
|
||||
|
@ -691,21 +691,24 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item)
|
||||
|
||||
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 << std::endl;
|
||||
|
||||
/* 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;
|
||||
full_key_ok = true;
|
||||
}
|
||||
|
||||
/* cache public key always */
|
||||
pubkey = kit->second;
|
||||
pub_key_ok = true;
|
||||
if (kit->second.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY)
|
||||
{
|
||||
/* cache public key always */
|
||||
pubkey = kit->second;
|
||||
pub_key_ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,18 +68,18 @@ void p3Posted::service_tick()
|
||||
generatePosts();
|
||||
generateVotesAndComments();
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
if((now > (time_t) (VOTE_UPDATE_PERIOD + mLastUpdate)) &&
|
||||
(mUpdatePhase == UPDATE_PHASE_GRP_REQUEST))
|
||||
{
|
||||
mPostUpdate = true;
|
||||
mLastUpdate = time(NULL);
|
||||
}
|
||||
|
||||
updateVotes();
|
||||
|
||||
processRankings();
|
||||
// time_t now = time(NULL);
|
||||
//
|
||||
// if((now > (time_t) (VOTE_UPDATE_PERIOD + mLastUpdate)) &&
|
||||
// (mUpdatePhase == UPDATE_PHASE_GRP_REQUEST))
|
||||
// {
|
||||
// mPostUpdate = true;
|
||||
// mLastUpdate = time(NULL);
|
||||
// }
|
||||
//
|
||||
// updateVotes();
|
||||
//
|
||||
// processRankings();
|
||||
}
|
||||
|
||||
void p3Posted::generateVotesAndComments()
|
||||
@ -505,7 +505,6 @@ bool p3Posted::requestPostRankings(uint32_t &token, const RankType &rType, const
|
||||
gp->pubToken = token;
|
||||
gp->rankingResult.rType = gp->rType;
|
||||
gp->rankingResult.grpId = gp->grpId;
|
||||
gp->grpId = gp->grpId;
|
||||
|
||||
mPendingPostRanks.push_back(gp);
|
||||
|
||||
@ -768,6 +767,7 @@ bool p3Posted::completePostedPostCalc(GxsPostedPostRanking *gpp)
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Unknown ranking tpye: " << gpp->rType << std::endl;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}else
|
||||
|
@ -24,6 +24,8 @@ PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const RsPhotoPhoto &photo, QW
|
||||
ui->lineEdit_PhotoGrapher->setVisible(false);
|
||||
|
||||
setUp();
|
||||
|
||||
ui->idChooser->setVisible(false);
|
||||
}
|
||||
|
||||
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_PhotoGrapher, SIGNAL(editingFinished()), this, SLOT(setPhotoGrapher()));
|
||||
|
||||
ui->idChooser->loadIds(0, "");
|
||||
|
||||
}
|
||||
|
||||
void PhotoItem::setSelected(bool selected)
|
||||
@ -101,6 +105,15 @@ void PhotoItem::setPhotoGrapher()
|
||||
|
||||
const RsPhotoPhoto& PhotoItem::getPhotoDetails()
|
||||
{
|
||||
|
||||
|
||||
if(ui->idChooser->isVisible())
|
||||
{
|
||||
RsGxsId id;
|
||||
ui->idChooser->getChosenId(id);
|
||||
mPhotoDetails.mMeta.mAuthorId = id;
|
||||
}
|
||||
|
||||
return mPhotoDetails;
|
||||
}
|
||||
|
||||
|
@ -1,110 +1,131 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PhotoItem</class>
|
||||
<widget class="QWidget" name="PhotoItem">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>253</width>
|
||||
<height>233</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="photoFrame">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QFrame#photoFrame{border: 2px solid #CCCCCC;
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 #EEEEEE, stop: 1 #CCCCCC);
|
||||
border-radius: 10px}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_Thumbnail">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="AlbumTitle">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photo Title :</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photographer :</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="editLayOut">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_Title">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_PhotoGrapher"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PhotoItem</class>
|
||||
<widget class="QWidget" name="PhotoItem">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>253</width>
|
||||
<height>233</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="photoFrame">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QFrame#photoFrame{border: 2px solid #CCCCCC;
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 #EEEEEE, stop: 1 #CCCCCC);
|
||||
border-radius: 10px}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_Thumbnail">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="AlbumTitle">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photo Title :</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photographer :</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="identity">
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Author :</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="editLayOut">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_Title">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_PhotoGrapher"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GxsIdChooser" name="idChooser"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>GxsIdChooser</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>gui/gxs/GxsIdChooser.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -223,7 +223,7 @@ void PostedListDialog::updateDisplay()
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs;
|
||||
|
||||
|
||||
if (rsPosted->updated())
|
||||
if (rsPosted->updated(true, true))
|
||||
{
|
||||
/* update Forums List */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user