merging rs_gxs-finale to v0.6 branch

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.6-initdev@6953 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
chrisparker126 2013-12-21 18:20:47 +00:00
commit 39909b705f
67 changed files with 5686 additions and 488 deletions

View file

@ -38,7 +38,7 @@ GxsSecurity::~GxsSecurity()
{ {
} }
RSA *GxsSecurity::extractPublicKey(RsTlvSecurityKey& key) RSA *GxsSecurity::extractPublicKey(const RsTlvSecurityKey& key)
{ {
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len; long keylen = key.keyData.bin_len;
@ -489,7 +489,7 @@ void GxsSecurity::setRSAPrivateKey(RsTlvSecurityKey & key, RSA *rsa_priv)
key.keyId = keyId; key.keyId = keyId;
} }
RSA *GxsSecurity::extractPrivateKey(RsTlvSecurityKey & key) RSA *GxsSecurity::extractPrivateKey(const RsTlvSecurityKey & key)
{ {
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len; long keylen = key.keyData.bin_len;

View file

@ -51,14 +51,14 @@ public:
* @param key RsTlvSecurityKey to extract public RSA key from * @param key RsTlvSecurityKey to extract public RSA key from
* @return pointer to the public RSA key if successful, null otherwise * @return pointer to the public RSA key if successful, null otherwise
*/ */
static RSA *extractPublicKey(RsTlvSecurityKey &key); static RSA *extractPublicKey(const RsTlvSecurityKey &key);
/*! /*!
* extracts the public key from an RsTlvSecurityKey * extracts the public key from an RsTlvSecurityKey
* @param key RsTlvSecurityKey to extract private RSA key from * @param key RsTlvSecurityKey to extract private RSA key from
* @return pointer to the private RSA key if successful, null otherwise * @return pointer to the private RSA key if successful, null otherwise
*/ */
static RSA *extractPrivateKey(RsTlvSecurityKey &key); static RSA *extractPrivateKey(const RsTlvSecurityKey &key);
/*! /*!
* stores the rsa public key in a RsTlvSecurityKey * stores the rsa public key in a RsTlvSecurityKey

View file

@ -34,6 +34,8 @@
#define MSG_TABLE_NAME std::string("MESSAGES") #define MSG_TABLE_NAME std::string("MESSAGES")
#define GRP_TABLE_NAME std::string("GROUPS") #define GRP_TABLE_NAME std::string("GROUPS")
#define GRP_LAST_POST_UPDATE_TRIGGER std::string("LAST_POST_UPDATE")
// generic // generic
#define KEY_NXS_FILE std::string("nxsFile") #define KEY_NXS_FILE std::string("nxsFile")
@ -48,6 +50,7 @@
#define KEY_NXS_META std::string("meta") #define KEY_NXS_META std::string("meta")
#define KEY_NXS_SERV_STRING std::string("serv_str") #define KEY_NXS_SERV_STRING std::string("serv_str")
#define KEY_NXS_HASH std::string("hash") #define KEY_NXS_HASH std::string("hash")
#define KEY_RECV_TS std::string("recv_time_stamp")
// grp table columns // grp table columns
@ -111,6 +114,7 @@
#define COL_GRP_INTERN_CIRCLE 18 #define COL_GRP_INTERN_CIRCLE 18
#define COL_GRP_ORIGINATOR 19 #define COL_GRP_ORIGINATOR 19
#define COL_GRP_AUTHEN_FLAGS 20 #define COL_GRP_AUTHEN_FLAGS 20
#define COL_GRP_RECV_TS 21
// msg col numbers // msg col numbers
@ -122,6 +126,7 @@
#define COL_THREAD_ID 11 #define COL_THREAD_ID 11
#define COL_MSG_NAME 12 #define COL_MSG_NAME 12
#define COL_MSG_SERV_STRING 13 #define COL_MSG_SERV_STRING 13
#define COL_MSG_RECV_TS 14
// generic meta shared col numbers // generic meta shared col numbers
#define COL_GRP_ID 0 #define COL_GRP_ID 0
@ -154,7 +159,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
msgMetaColumns.push_back(KEY_SIGN_SET); msgMetaColumns.push_back(KEY_NXS_IDENTITY); msgMetaColumns.push_back(KEY_NXS_HASH); msgMetaColumns.push_back(KEY_SIGN_SET); msgMetaColumns.push_back(KEY_NXS_IDENTITY); msgMetaColumns.push_back(KEY_NXS_HASH);
msgMetaColumns.push_back(KEY_MSG_ID); msgMetaColumns.push_back(KEY_ORIG_MSG_ID); msgMetaColumns.push_back(KEY_MSG_STATUS); msgMetaColumns.push_back(KEY_MSG_ID); msgMetaColumns.push_back(KEY_ORIG_MSG_ID); msgMetaColumns.push_back(KEY_MSG_STATUS);
msgMetaColumns.push_back(KEY_CHILD_TS); msgMetaColumns.push_back(KEY_MSG_PARENT_ID); msgMetaColumns.push_back(KEY_MSG_THREAD_ID); msgMetaColumns.push_back(KEY_CHILD_TS); msgMetaColumns.push_back(KEY_MSG_PARENT_ID); msgMetaColumns.push_back(KEY_MSG_THREAD_ID);
msgMetaColumns.push_back(KEY_MSG_NAME); msgMetaColumns.push_back(KEY_NXS_SERV_STRING); msgMetaColumns.push_back(KEY_MSG_NAME); msgMetaColumns.push_back(KEY_NXS_SERV_STRING); msgMetaColumns.push_back(KEY_RECV_TS);
// for retrieving actual data // for retrieving actual data
msgColumns.push_back(KEY_GRP_ID); msgColumns.push_back(KEY_NXS_FILE); msgColumns.push_back(KEY_NXS_FILE_OFFSET); msgColumns.push_back(KEY_GRP_ID); msgColumns.push_back(KEY_NXS_FILE); msgColumns.push_back(KEY_NXS_FILE_OFFSET);
@ -168,7 +173,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); grpMetaColumns.push_back(KEY_NXS_SERV_STRING); grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); grpMetaColumns.push_back(KEY_NXS_SERV_STRING);
grpMetaColumns.push_back(KEY_GRP_SIGN_FLAGS); grpMetaColumns.push_back(KEY_GRP_CIRCLE_ID); grpMetaColumns.push_back(KEY_GRP_CIRCLE_TYPE); grpMetaColumns.push_back(KEY_GRP_SIGN_FLAGS); grpMetaColumns.push_back(KEY_GRP_CIRCLE_ID); grpMetaColumns.push_back(KEY_GRP_CIRCLE_TYPE);
grpMetaColumns.push_back(KEY_GRP_INTERNAL_CIRCLE); grpMetaColumns.push_back(KEY_GRP_ORIGINATOR); grpMetaColumns.push_back(KEY_GRP_INTERNAL_CIRCLE); grpMetaColumns.push_back(KEY_GRP_ORIGINATOR);
grpMetaColumns.push_back(KEY_GRP_AUTHEN_FLAGS); grpMetaColumns.push_back(KEY_GRP_AUTHEN_FLAGS); grpMetaColumns.push_back(KEY_RECV_TS);
// for retrieving actual grp data // for retrieving actual grp data
grpColumns.push_back(KEY_GRP_ID); grpColumns.push_back(KEY_NXS_FILE); grpColumns.push_back(KEY_NXS_FILE_OFFSET); grpColumns.push_back(KEY_GRP_ID); grpColumns.push_back(KEY_NXS_FILE); grpColumns.push_back(KEY_NXS_FILE_OFFSET);
@ -177,6 +182,8 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
// for retrieving msg offsets // for retrieving msg offsets
mMsgOffSetColumns.push_back(KEY_MSG_ID); mMsgOffSetColumns.push_back(KEY_NXS_FILE_OFFSET); mMsgOffSetColumns.push_back(KEY_MSG_ID); mMsgOffSetColumns.push_back(KEY_NXS_FILE_OFFSET);
mMsgOffSetColumns.push_back(KEY_NXS_FILE_LEN); mMsgOffSetColumns.push_back(KEY_NXS_FILE_LEN);
grpIdColumn.push_back(KEY_GRP_ID);
} }
RsDataService::~RsDataService(){ RsDataService::~RsDataService(){
@ -210,6 +217,7 @@ void RsDataService::initialise(){
KEY_MSG_NAME + " TEXT," + KEY_MSG_NAME + " TEXT," +
KEY_NXS_SERV_STRING + " TEXT," + KEY_NXS_SERV_STRING + " TEXT," +
KEY_NXS_HASH + " TEXT," + KEY_NXS_HASH + " TEXT," +
KEY_RECV_TS + " INT," +
KEY_NXS_FILE_LEN + " INT);"); KEY_NXS_FILE_LEN + " INT);");
// create table for grp data // create table for grp data
@ -238,8 +246,15 @@ void RsDataService::initialise(){
KEY_GRP_INTERNAL_CIRCLE + " TEXT," + KEY_GRP_INTERNAL_CIRCLE + " TEXT," +
KEY_GRP_ORIGINATOR + " TEXT," + KEY_GRP_ORIGINATOR + " TEXT," +
KEY_NXS_HASH + " TEXT," + KEY_NXS_HASH + " TEXT," +
KEY_RECV_TS + " INT," +
KEY_SIGN_SET + " BLOB);"); KEY_SIGN_SET + " BLOB);");
mDb->execSQL("CREATE TRIGGER " + GRP_LAST_POST_UPDATE_TRIGGER +
" INSERT ON " + MSG_TABLE_NAME +
std::string(" BEGIN ") +
" UPDATE " + GRP_TABLE_NAME + " SET " + KEY_GRP_LAST_POST + "= new."
+ KEY_RECV_TS + " WHERE " + KEY_GRP_ID + "=new." + KEY_GRP_ID + ";"
+ std::string("END;"));
} }
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c) RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
@ -291,6 +306,7 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
c.getString(COL_GRP_INTERN_CIRCLE, grpMeta->mInternalCircle); c.getString(COL_GRP_INTERN_CIRCLE, grpMeta->mInternalCircle);
c.getString(COL_GRP_ORIGINATOR, grpMeta->mOriginator); c.getString(COL_GRP_ORIGINATOR, grpMeta->mOriginator);
grpMeta->mAuthenFlags = c.getInt32(COL_GRP_AUTHEN_FLAGS); grpMeta->mAuthenFlags = c.getInt32(COL_GRP_AUTHEN_FLAGS);
grpMeta->mRecvTS = c.getInt32(COL_GRP_RECV_TS);
if(ok) if(ok)
@ -377,6 +393,7 @@ RsGxsMsgMetaData* RsDataService::locked_getMsgMeta(RetroCursor &c)
c.getString(COL_MSG_NAME, msgMeta->mMsgName); c.getString(COL_MSG_NAME, msgMeta->mMsgName);
c.getString(COL_MSG_SERV_STRING, msgMeta->mServiceString); c.getString(COL_MSG_SERV_STRING, msgMeta->mServiceString);
c.getString(COL_HASH, msgMeta->mHash); c.getString(COL_HASH, msgMeta->mHash);
msgMeta->recvTS = c.getInt32(COL_MSG_RECV_TS);
offset = 0; offset = 0;
data = (char*)c.getData(COL_SIGN_SET, data_len); data = (char*)c.getData(COL_SIGN_SET, data_len);
@ -489,6 +506,7 @@ int RsDataService::storeMessage(std::map<RsNxsMsg *, RsGxsMsgMetaData *> &msg)
cv.put(KEY_GRP_ID, msgMetaPtr->mGroupId); cv.put(KEY_GRP_ID, msgMetaPtr->mGroupId);
cv.put(KEY_NXS_SERV_STRING, msgMetaPtr->mServiceString); cv.put(KEY_NXS_SERV_STRING, msgMetaPtr->mServiceString);
cv.put(KEY_NXS_HASH, msgMetaPtr->mHash); cv.put(KEY_NXS_HASH, msgMetaPtr->mHash);
cv.put(KEY_RECV_TS, (int32_t)msgMetaPtr->recvTS);
char signSetData[msgMetaPtr->signSet.TlvSize()]; char signSetData[msgMetaPtr->signSet.TlvSize()];
@ -596,6 +614,7 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator); cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator);
cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags); cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags);
cv.put(KEY_NXS_HASH, grpMetaPtr->mHash); cv.put(KEY_NXS_HASH, grpMetaPtr->mHash);
cv.put(KEY_RECV_TS, (int32_t)grpMetaPtr->mRecvTS);
if(! (grpMetaPtr->mAuthorId.empty()) ){ if(! (grpMetaPtr->mAuthorId.empty()) ){
cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId); cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId);
@ -641,6 +660,98 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
return ret; return ret;
} }
int RsDataService::updateGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
{
RsStackMutex stack(mDbMutex);
std::map<RsNxsGrp*, RsGxsGrpMetaData* >::iterator sit = grp.begin();
// begin transaction
mDb->execSQL("BEGIN;");
for(; sit != grp.end(); sit++)
{
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::ofstream ostrm(grpFile.c_str(), std::ios::binary | std::ios::trunc);
uint32_t offset = 0; // get file offset
/*!
* STORE file offset, file length, file name,
* grpId, flags, publish time stamp, identity,
* id signature, admin signatue, key set, last posting ts
* and meta data
**/
ContentValue cv;
cv.put(KEY_NXS_FILE_OFFSET, (int32_t)offset);
cv.put(KEY_NXS_FILE_LEN, (int32_t)grpPtr->grp.TlvSize());
cv.put(KEY_NXS_FILE, grpFile);
cv.put(KEY_GRP_ID, grpPtr->grpId);
cv.put(KEY_GRP_NAME, grpMetaPtr->mGroupName);
cv.put(KEY_ORIG_GRP_ID, grpMetaPtr->mOrigGrpId);
cv.put(KEY_NXS_SERV_STRING, grpMetaPtr->mServiceString);
cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags);
cv.put(KEY_TIME_STAMP, (int32_t)grpMetaPtr->mPublishTs);
cv.put(KEY_GRP_SIGN_FLAGS, (int32_t)grpMetaPtr->mSignFlags);
cv.put(KEY_GRP_CIRCLE_ID, grpMetaPtr->mCircleId);
cv.put(KEY_GRP_CIRCLE_TYPE, (int32_t)grpMetaPtr->mCircleType);
cv.put(KEY_GRP_INTERNAL_CIRCLE, grpMetaPtr->mInternalCircle);
cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator);
cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags);
cv.put(KEY_NXS_HASH, grpMetaPtr->mHash);
if(! (grpMetaPtr->mAuthorId.empty()) ){
cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId);
}
offset = 0;
char keySetData[grpMetaPtr->keys.TlvSize()];
grpMetaPtr->keys.SetTlv(keySetData, grpMetaPtr->keys.TlvSize(), &offset);
cv.put(KEY_KEY_SET, grpMetaPtr->keys.TlvSize(), keySetData);
offset = 0;
char metaData[grpPtr->meta.TlvSize()];
grpPtr->meta.SetTlv(metaData, grpPtr->meta.TlvSize(), &offset);
cv.put(KEY_NXS_META, grpPtr->meta.TlvSize(), metaData);
// local meta data
cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags);
cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop);
cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mMsgCount);
cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus);
cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost);
offset = 0;
char grpData[grpPtr->grp.TlvSize()];
grpPtr->grp.SetTlv(grpData, grpPtr->grp.TlvSize(), &offset);
ostrm.write(grpData, grpPtr->grp.TlvSize());
ostrm.close();
mDb->sqlUpdate(GRP_TABLE_NAME, "grpId='" + grpPtr->grpId + "'", cv);
}
// finish transaction
bool ret = mDb->execSQL("COMMIT;");
for(sit = grp.begin(); sit != grp.end(); sit++)
{
//TODO: API encourages aliasing, remove this abomination
if(sit->second != sit->first->metaData)
delete sit->second;
delete sit->first;
}
return ret;
}
bool RsDataService::validSize(RsNxsGrp* grp) const bool RsDataService::validSize(RsNxsGrp* grp) const
{ {
if((grp->grp.TlvSize() + grp->meta.TlvSize()) <= GXS_MAX_ITEM_SIZE) return true; if((grp->grp.TlvSize() + grp->meta.TlvSize()) <= GXS_MAX_ITEM_SIZE) return true;
@ -964,34 +1075,33 @@ int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaDat
}else }else
{ {
std::map<RsGxsGroupId, RsGxsGrpMetaData *>::iterator mit = grp.begin(); std::map<RsGxsGroupId, RsGxsGrpMetaData *>::iterator mit = grp.begin();
for(; mit != grp.end(); mit++) for(; mit != grp.end(); mit++)
{ {
const RsGxsGroupId& grpId = mit->first; const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "grpId='" + grpId + "'", ""); RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "grpId='" + grpId + "'", "");
if(c) if(c)
{ {
bool valid = c->moveToFirst(); bool valid = c->moveToFirst();
while(valid) while(valid)
{ {
RsGxsGrpMetaData* g = locked_getGrpMeta(*c); RsGxsGrpMetaData* g = locked_getGrpMeta(*c);
if(g) if(g)
{ {
grp[g->mGroupId] = g; grp[g->mGroupId] = g;
} }
valid = c->moveToNext(); valid = c->moveToNext();
} }
delete c; delete c;
} }
} }
} }
return 1; return 1;
@ -1010,21 +1120,22 @@ int RsDataService::resetDataStore()
std::map<std::string, RsNxsGrp*>::iterator mit std::map<std::string, RsNxsGrp*>::iterator mit
= grps.begin(); = grps.begin();
// remove all grp msgs files from service dir
for(; mit != grps.end(); mit++){
std::string file = mServiceDir + "/" + mit->first;
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); RsStackMutex stack(mDbMutex);
mDb->closeDb();
}
remove(mDbName.c_str()); // remove db file // remove all grp msgs files from service dir
for(; mit != grps.end(); mit++){
std::string file = mServiceDir + "/" + mit->first;
std::string msgFile = file + "-msgs";
remove(file.c_str()); // remove group file
remove(msgFile.c_str()); // and remove messages file
delete mit->second;
}
mDb->execSQL("DROP TABLE " + MSG_TABLE_NAME);
mDb->execSQL("DROP TABLE " + GRP_TABLE_NAME);
mDb->execSQL("DROP TRIGGER " + GRP_LAST_POST_UPDATE_TRIGGER);
}
// recreate database // recreate database
initialise(); initialise();
@ -1177,6 +1288,31 @@ int RsDataService::removeGroups(const std::vector<std::string> &grpIds)
return 1; return 1;
} }
int RsDataService::retrieveGroupIds(std::vector<std::string> &grpIds)
{
RsStackMutex stack(mDbMutex);
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpIdColumn, "", "");
if(c)
{
bool valid = c->moveToFirst();
while(valid)
{
std::string grpId;
c->getString(0, grpId);
grpIds.push_back(grpId);
valid = c->moveToNext();
}
delete c;
}else
{
return 0;
}
return 1;
}
bool RsDataService::locked_updateMessageEntries(const MsgUpdates& updates) bool RsDataService::locked_updateMessageEntries(const MsgUpdates& updates)
{ {

View file

@ -106,6 +106,13 @@ public:
*/ */
int removeGroups(const std::vector<RsGxsGroupId>& grpIds); int removeGroups(const std::vector<RsGxsGroupId>& grpIds);
/*!
* Retrieves all group ids in store
* @param grpIds all grpids in store is inserted into this vector
* @return error code
*/
int retrieveGroupIds(std::vector<std::string> &grpIds);
/*! /*!
* @return the cache size set for this RsGeneralDataService in bytes * @return the cache size set for this RsGeneralDataService in bytes
*/ */
@ -130,6 +137,13 @@ public:
*/ */
int storeGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grp); int storeGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grp);
/*!
* Updates group entries in Db
* @param grp map of group and decoded meta data
* @return error code
*/
int updateGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp);
/*! /*!
* @param metaData The meta data item to update * @param metaData The meta data item to update
* @return error code * @return error code
@ -238,6 +252,7 @@ private:
std::list<std::string> grpColumns; std::list<std::string> grpColumns;
std::list<std::string> grpMetaColumns; std::list<std::string> grpMetaColumns;
std::list<std::string> grpIdColumn;
std::string mServiceDir, mDbName; std::string mServiceDir, mDbName;
uint16_t mServType; uint16_t mServType;

View file

@ -169,6 +169,13 @@ public:
*/ */
virtual int removeGroups(const std::vector<RsGxsGroupId>& grpIds) = 0; virtual int removeGroups(const std::vector<RsGxsGroupId>& grpIds) = 0;
/*!
* Retrieves all group ids in store
* @param grpIds all grpids in store is inserted into this vector
* @return error code
*/
virtual int retrieveGroupIds(std::vector<RsGxsGroupId>& grpIds) = 0;
/*! /*!
* @return the cache size set for this RsGeneralDataService in bytes * @return the cache size set for this RsGeneralDataService in bytes
*/ */
@ -194,6 +201,13 @@ public:
virtual int storeGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp) = 0; virtual int storeGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp) = 0;
/*!
* Updates group entries in Db
* @param grp map of group and decoded meta data
* @return error code
*/
virtual int updateGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp) = 0;
/*! /*!
* @param metaData * @param metaData
*/ */

View file

@ -113,6 +113,8 @@ void RsGenExchange::tick()
publishMsgs(); publishMsgs();
processGroupUpdatePublish();
processRecvdData(); processRecvdData();
if(!mNotifications.empty()) if(!mNotifications.empty())
@ -273,6 +275,56 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet,
} }
} }
void RsGenExchange::generatePublicFromPrivateKeys(const RsTlvSecurityKeySet &privatekeySet,
RsTlvSecurityKeySet &publickeySet)
{
// actually just copy settings of one key except mark its key flags public
typedef std::map<std::string, RsTlvSecurityKey> keyMap;
const keyMap& allKeys = privatekeySet.keys;
keyMap::const_iterator cit = allKeys.begin();
bool adminFound = false, publishFound = false;
for(; cit != allKeys.end(); cit++)
{
const RsTlvSecurityKey& privKey = cit->second;
if(privKey.keyFlags & RSTLV_KEY_TYPE_FULL)
{
RsTlvSecurityKey pubKey;
pubKey = privKey;
RSA *rsaPrivKey = NULL, *rsaPubKey = NULL;
rsaPrivKey = GxsSecurity::extractPrivateKey(privKey);
if(rsaPrivKey)
rsaPubKey = RSAPublicKey_dup(rsaPrivKey);
if(rsaPrivKey && rsaPubKey)
{
GxsSecurity::setRSAPublicKey(pubKey, rsaPubKey);
if(pubKey.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
pubKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY;
if(pubKey.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE)
pubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_PUBLIC_ONLY;
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
publickeySet.keys.insert(std::make_pair(pubKey.keyId, pubKey));
}
if(rsaPrivKey)
RSA_free(rsaPrivKey);
if(rsaPubKey)
RSA_free(rsaPubKey);
}
}
}
uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet) uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet)
{ {
std::cerr << "RsGenExchange::createGroup()"; std::cerr << "RsGenExchange::createGroup()";
@ -763,6 +815,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu
}else }else
{ {
std::list<std::string> peers; std::list<std::string> peers;
peers.push_back(msg->PeerId());
mGixs->requestKey(metaData.mAuthorId, peers); mGixs->requestKey(metaData.mAuthorId, peers);
return VALIDATE_FAIL_TRY_LATER; return VALIDATE_FAIL_TRY_LATER;
} }
@ -836,6 +889,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp, RsTlvSecurityKeySet& grpKeySet)
}else }else
{ {
std::list<std::string> peers; std::list<std::string> peers;
peers.push_back(grp->PeerId());
mGixs->requestKey(metaData.mAuthorId, peers); mGixs->requestKey(metaData.mAuthorId, peers);
return VALIDATE_FAIL_TRY_LATER; return VALIDATE_FAIL_TRY_LATER;
} }
@ -1364,6 +1418,20 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
} }
void RsGenExchange::updateGroup(uint32_t& token, RsGxsGroupUpdateMeta& updateMeta, RsGxsGrpItem* grpItem)
{
RsStackMutex stack(mGenMtx);
token = mDataAccess->generatePublicToken();
mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, updateMeta, token));
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::updateGroup() token: " << token;
std::cerr << std::endl;
#endif
}
void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
{ {
RsStackMutex stack(mGenMtx); RsStackMutex stack(mGenMtx);
@ -1716,6 +1784,7 @@ void RsGenExchange::publishMsgs()
msg->metaData->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD; msg->metaData->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD;
msgId = msg->msgId; msgId = msg->msgId;
grpId = msg->grpId; grpId = msg->grpId;
msg->metaData->recvTS = time(NULL);
computeHash(msg->msg, msg->metaData->mHash); computeHash(msg->msg, msg->metaData->mHash);
mDataAccess->addMsgData(msg); mDataAccess->addMsgData(msg);
msgChangeMap[grpId].push_back(msgId); msgChangeMap[grpId].push_back(msgId);
@ -1780,6 +1849,115 @@ RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpI
#define PENDING_SIGN_TIMEOUT 10 // 5 seconds #define PENDING_SIGN_TIMEOUT 10 // 5 seconds
void RsGenExchange::processGroupUpdatePublish()
{
RsStackMutex stack(mGenMtx);
// get keys for group update publish
// first build meta request map for groups to be updated
std::map<std::string, RsGxsGrpMetaData*> grpMeta;
std::vector<GroupUpdatePublish>::iterator vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); vit++)
{
GroupUpdatePublish& gup = *vit;
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
grpMeta.insert(std::make_pair(groupId, (RsGxsGrpMetaData*)(NULL)));
}
if(grpMeta.empty())
return;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
// now
vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); vit++)
{
GroupUpdatePublish& gup = *vit;
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
std::map<std::string, RsGxsGrpMetaData*>::iterator mit = grpMeta.find(groupId);
RsGxsGrpMetaData* meta = NULL;
if(mit == grpMeta.end())
{
std::cerr << "Error! could not find meta of old group to update!" << std::endl;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
delete gup.grpItem;
continue;
}else
{
meta = mit->second;
}
gup.grpItem->meta = *meta;
assignMetaUpdates(gup.grpItem->meta, gup.mUpdateMeta);
GxsGrpPendingSign ggps(gup.grpItem, ggps.mToken);
bool publishAndAdminPrivatePresent = checkKeys(meta->keys);
if(publishAndAdminPrivatePresent)
{
ggps.mPrivateKeys = meta->keys;
generatePublicFromPrivateKeys(ggps.mPrivateKeys, ggps.mPublicKeys);
ggps.mHaveKeys = true;
ggps.mStartTS = time(NULL);
ggps.mLastAttemptTS = 0;
ggps.mIsUpdate = true;
ggps.mToken = gup.mToken;
mGrpsToPublish.push_back(ggps);
}else
{
delete gup.grpItem;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
}
delete meta;
}
mGroupUpdatePublish.clear();
}
void RsGenExchange::assignMetaUpdates(RsGroupMetaData& meta, const RsGxsGroupUpdateMeta metaUpdate) const
{
const RsGxsGroupUpdateMeta::GxsMetaUpdate* updates = metaUpdate.getUpdates();
RsGxsGroupUpdateMeta::GxsMetaUpdate::const_iterator mit = updates->begin();
for(; mit != updates->end(); mit++)
{
if(mit->first == RsGxsGroupUpdateMeta::NAME)
meta.mGroupName = mit->second;
}
}
bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet)
{
typedef std::map<std::string, RsTlvSecurityKey> keyMap;
const keyMap& allKeys = keySet.keys;
keyMap::const_iterator cit = allKeys.begin();
bool adminFound = false, publishFound = false;
for(; cit != allKeys.end(); cit++)
{
const RsTlvSecurityKey& key = cit->second;
if(key.keyFlags & RSTLV_KEY_TYPE_FULL)
{
if(key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
adminFound = true;
if(key.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE)
publishFound = true;
}
}
// user must have both private and public parts of publish and admin keys
return adminFound && publishFound;
}
void RsGenExchange::publishGrps() void RsGenExchange::publishGrps()
{ {
RsStackMutex stack(mGenMtx); RsStackMutex stack(mGenMtx);
@ -1850,10 +2028,6 @@ void RsGenExchange::publishGrps()
// get group id from private admin key id // get group id from private admin key id
grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId; grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId;
// what!? this will remove the private keys!
privatekeySet.keys.insert(publicKeySet.keys.begin(),
publicKeySet.keys.end());
ServiceCreate_Return ret = service_CreateGroup(grpItem, privatekeySet); ServiceCreate_Return ret = service_CreateGroup(grpItem, privatekeySet);
@ -1901,7 +2075,12 @@ void RsGenExchange::publishGrps()
{ {
grpId = grp->grpId; grpId = grp->grpId;
computeHash(grp->grp, grp->metaData->mHash); computeHash(grp->grp, grp->metaData->mHash);
mDataAccess->addGroupData(grp); grp->metaData->mRecvTS = time(NULL);
if(ggps.mIsUpdate)
mDataAccess->updateGroupData(grp);
else
mDataAccess->addGroupData(grp);
} }
else else
{ {
@ -2033,6 +2212,8 @@ void RsGenExchange::processRecvdData()
processRecvdGroups(); processRecvdGroups();
processRecvdMessages(); processRecvdMessages();
performUpdateValidation();
} }
@ -2117,6 +2298,7 @@ void RsGenExchange::processRecvdMessages()
if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry); if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry);
computeHash(msg->msg, meta->mHash); computeHash(msg->msg, meta->mHash);
meta->recvTS = time(NULL);
} }
} }
else else
@ -2188,9 +2370,12 @@ void RsGenExchange::processRecvdGroups()
RsStackMutex stack(mGenMtx); RsStackMutex stack(mGenMtx);
NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin(); NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin();
std::vector<std::string> existingGrpIds;
std::list<std::string> grpIds;
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps; std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
std::list<RsGxsGroupId> grpIds; mDataStore->retrieveGroupIds(existingGrpIds);
while( vit != mReceivedGrps.end()) while( vit != mReceivedGrps.end())
{ {
@ -2215,13 +2400,24 @@ void RsGenExchange::processRecvdGroups()
meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD; meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD;
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED; meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
computeHash(grp->grp, meta->mHash); computeHash(grp->grp, meta->mHash);
grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId);
// now check if group already existss
if(std::find(existingGrpIds.begin(), existingGrpIds.end(), grp->grpId) == existingGrpIds.end())
{
meta->mRecvTS = time(NULL);
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId);
}
else
{
GroupUpdate update;
update.newGrp = grp;
mGroupUpdates.push_back(update);
}
erase = true; erase = true;
} }
else if(ret == VALIDATE_FAIL) else if(ret == VALIDATE_FAIL)
@ -2273,3 +2469,99 @@ void RsGenExchange::processRecvdGroups()
mDataStore->storeGroup(grps); mDataStore->storeGroup(grps);
} }
} }
void RsGenExchange::performUpdateValidation()
{
RsStackMutex stack(mGenMtx);
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
if(mGroupUpdates.empty())
return;
std::map<std::string, RsGxsGrpMetaData*> grpMetas;
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); vit++)
grpMetas.insert(std::make_pair(vit->newGrp->grpId, (RsGxsGrpMetaData*)NULL));
if(!grpMetas.empty())
mDataStore->retrieveGxsGrpMetaData(grpMetas);
else
return;
vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); vit++)
{
GroupUpdate& gu = *vit;
std::map<std::string, RsGxsGrpMetaData*>::iterator mit =
grpMetas.find(gu.newGrp->grpId);
gu.oldGrpMeta = mit->second;
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
}
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
vit = mGroupUpdates.begin();
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
for(; vit != mGroupUpdates.end(); vit++)
{
GroupUpdate& gu = *vit;
if(gu.validUpdate)
{
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
grps.insert(std::make_pair(gu.newGrp, gu.newGrp->metaData));
}
else
{
delete gu.newGrp;
}
delete gu.oldGrpMeta;
}
mDataStore->updateGroup(grps);
mGroupUpdates.clear();
}
bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const
{
std::map<SignType, RsTlvKeySignature>& signSet = newGrp.metaData->signSet.keySignSet;
std::map<SignType, RsTlvKeySignature>::iterator mit = signSet.find(GXS_SERV::FLAG_AUTHEN_ADMIN);
if(mit == signSet.end())
{
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::updateValid() new admin sign not found! " << std::endl;
std::cerr << "RsGenExchange::updateValid() grpId: " << oldGrp.grpId << std::endl;
#endif
return false;
}
RsTlvKeySignature adminSign = mit->second;
std::map<std::string, RsTlvSecurityKey>& keys = oldGrpMeta.keys.keys;
std::map<std::string, RsTlvSecurityKey>::iterator keyMit = keys.find(oldGrpMeta.mGroupId);
if(keyMit == keys.end())
{
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::updateValid() admin key not found! " << std::endl;
#endif
return false;
}
// also check this is the latest published group
bool latest = newGrp.metaData->mPublishTs > oldGrpMeta.mPublishTs;
return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest;
}

View file

@ -71,13 +71,14 @@ class GxsGrpPendingSign
public: public:
GxsGrpPendingSign(RsGxsGrpItem* item, uint32_t token): mLastAttemptTS(0), mStartTS(time(NULL)), mToken(token), GxsGrpPendingSign(RsGxsGrpItem* item, uint32_t token): mLastAttemptTS(0), mStartTS(time(NULL)), mToken(token),
mItem(item), mHaveKeys(false) mItem(item), mHaveKeys(false), mIsUpdate(false)
{} {}
time_t mLastAttemptTS, mStartTS; time_t mLastAttemptTS, mStartTS;
uint32_t mToken; uint32_t mToken;
RsGxsGrpItem* mItem; RsGxsGrpItem* mItem;
bool mHaveKeys; // mKeys->first == true if key present bool mHaveKeys; // mKeys->first == true if key present
bool mIsUpdate;
RsTlvSecurityKeySet mPrivateKeys; RsTlvSecurityKeySet mPrivateKeys;
RsTlvSecurityKeySet mPublicKeys; RsTlvSecurityKeySet mPublicKeys;
}; };
@ -516,7 +517,6 @@ protected:
/*! /*!
* Enables publication of a group item \n * Enables publication of a group item \n
* If the item exists already this is simply versioned \n
* This will induce a related change message \n * This will induce a related change message \n
* Ownership of item passes to this rsgenexchange \n * Ownership of item passes to this rsgenexchange \n
* @param token * @param token
@ -524,6 +524,16 @@ protected:
*/ */
void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem); void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem);
/*!
* Updates an existing group item \n
* This will induce a related change message \n
* Ownership of item passes to this rsgenexchange \n
* @param token
* @param grpItem
*/
void updateGroup(uint32_t& token, RsGxsGroupUpdateMeta& updateMeta, RsGxsGrpItem* grpItem);
public: public:
/*! /*!
* Enables publication of a message item \n * Enables publication of a message item \n
@ -629,6 +639,8 @@ private:
void publishGrps(); void publishGrps();
void processGroupUpdatePublish();
void publishMsgs(); void publishMsgs();
/*! /*!
@ -700,11 +712,20 @@ private:
/*! /*!
* Generate a set of keys that can define a GXS group * Generate a set of keys that can define a GXS group
* @param privatekeySet contains private generated keys * @param privatekeySet contains private generated keys
* @param privatekeySet contains public generated keys (counterpart of private) * @param publickeySet contains public generated keys (counterpart of private)
* @param genPublicKeys should publish key pair also be generated * @param genPublicKeys should publish key pair also be generated
*/ */
void generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet, bool genPublishKeys); void generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet, bool genPublishKeys);
/*!
* Generate public set of keys from their private counterparts
* No keys will be generated if one fails
* @param privatekeySet contains private generated keys
* @param publickeySet contains public generated keys (counterpart of private)
* @return false if key gen failed for a key set
*/
void generatePublicFromPrivateKeys(const RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet);
/*! /*!
* Attempts to validate msg signatures * Attempts to validate msg signatures
* @param msg message to be validated * @param msg message to be validated
@ -736,6 +757,32 @@ private:
static void computeHash(const RsTlvBinaryData& data, std::string& hash); static void computeHash(const RsTlvBinaryData& data, std::string& hash);
/*!
* Checks validation of recently received groups to be
* updated
*/
void performUpdateValidation();
/*!
* Checks if the update is valid (i.e. the new admin signature is by the old admin key)
* @param oldGrp the old group to be updated (must have meta data member initialised)
* @param newGrp the new group that updates the old group (must have meta data member initialised)
* @return
*/
bool updateValid(RsGxsGrpMetaData& oldGrp, RsNxsGrp& newGrp) const;
/*!
* convenience function for checking private publish and admin keys are present
* @param keySet The keys set to split into a private and public set
* @return false, if private admin and publish keys cannot be found, true otherwise
*/
bool checkKeys(const RsTlvSecurityKeySet& keySet);
/*!
* Convenience function for assigning the meta update items to the actual group meta
*/
void assignMetaUpdates(RsGroupMetaData& meta, const RsGxsGroupUpdateMeta metaUpdate) const;
private: private:
RsMutex mGenMtx; RsMutex mGenMtx;
@ -798,6 +845,13 @@ private:
const uint8_t CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER, SIGN_MAX_ATTEMPTS; const uint8_t CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER, SIGN_MAX_ATTEMPTS;
const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER; const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER;
const uint8_t VALIDATE_FAIL, VALIDATE_SUCCESS, VALIDATE_FAIL_TRY_LATER, VALIDATE_MAX_ATTEMPTS; const uint8_t VALIDATE_FAIL, VALIDATE_SUCCESS, VALIDATE_FAIL_TRY_LATER, VALIDATE_MAX_ATTEMPTS;
private:
std::vector<GroupUpdate> mGroupUpdates, mPeersGroupUpdate;
std::vector<GroupUpdatePublish> mGroupUpdatePublish;
}; };
#endif // RSGENEXCHANGE_H #endif // RSGENEXCHANGE_H

View file

@ -176,7 +176,7 @@ class RsGixsReputation
public: public:
// get Reputation. // get Reputation.
virtual bool haveReputation(const RsGxsId &id) = 0; virtual bool haveReputation(const RsGxsId &id) = 0;
virtual bool loadReputation(const RsGxsId &id) = 0; virtual bool loadReputation(const RsGxsId &id, const std::list<std::string>& peers) = 0;
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep) = 0; virtual bool getReputation(const RsGxsId &id, GixsReputation &rep) = 0;
}; };

View file

@ -74,6 +74,7 @@ void RsGxsGrpMetaData::clear(){
mOriginator.clear(); mOriginator.clear();
mCircleType = 0; mCircleType = 0;
mAuthenFlags = 0; mAuthenFlags = 0;
mRecvTS = 0;
} }
@ -196,6 +197,7 @@ void RsGxsMsgMetaData::clear()
mMsgFlags = 0; mMsgFlags = 0;
mMsgStatus = 0; mMsgStatus = 0;
mChildTs = 0; mChildTs = 0;
recvTS = 0;
} }
bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size) bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size)

View file

@ -70,17 +70,16 @@ public:
uint32_t mPop; // HOW DO WE DO THIS NOW. uint32_t mPop; // HOW DO WE DO THIS NOW.
uint32_t mMsgCount; // ??? uint32_t mMsgCount; // ???
time_t mLastPost; // ??? uint32_t mLastPost; // ???
uint32_t mGroupStatus; uint32_t mGroupStatus;
uint32_t mRecvTS;
std::string mOriginator; std::string mOriginator;
std::string mInternalCircle; std::string mInternalCircle;
std::string mHash; std::string mHash;
}; };
class RsGxsMsgMetaData class RsGxsMsgMetaData
{ {
public: public:
@ -114,6 +113,7 @@ public:
uint32_t mMsgStatus; uint32_t mMsgStatus;
time_t mChildTs; time_t mChildTs;
uint32_t recvTS;
std::string mHash; std::string mHash;
bool validated; bool validated;

View file

@ -1487,7 +1487,14 @@ bool RsGxsDataAccess::addGroupData(RsNxsGrp* grp) {
return mDataStore->storeGroup(grpM); return mDataStore->storeGroup(grpM);
} }
bool RsGxsDataAccess::updateGroupData(RsNxsGrp* grp) {
RsStackMutex stack(mDataMutex);
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grpM;
grpM.insert(std::make_pair(grp, grp->metaData));
return mDataStore->updateGroup(grpM);
}
bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) { bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) {

View file

@ -126,14 +126,21 @@ public:
public: public:
/*! /*!
* This adds a groups to the gxs data base, this is a blocking call * This adds a groups to the gxs data base, this is a blocking call \n
* Responsibility for grp still lies with callee \n
* If function returns successfully DataAccess can be queried for grp * If function returns successfully DataAccess can be queried for grp
* @param grp the group to add, responsibility grp passed lies with callee * @param grp the group to add, responsibility grp passed lies with callee
* @return false if group cound not be added * @return false if group cound not be added
*/ */
bool addGroupData(RsNxsGrp* grp); bool addGroupData(RsNxsGrp* grp);
/*!
* This updates a groups in the gxs data base, this is a blocking call \n
* If function returns successfully DataAccess can be queried for grp
* @param grp the group to add, responsibility grp passed lies with callee
* @return false if group cound not be added
*/
bool updateGroupData(RsNxsGrp* grp);
/*! /*!
* This adds a group to the gxs data base, this is a blocking call \n * This adds a group to the gxs data base, this is a blocking call \n
* Responsibility for msg still lies with callee \n * Responsibility for msg still lies with callee \n

View file

@ -36,16 +36,16 @@
#define GIXS_CUT_OFF 0 #define GIXS_CUT_OFF 0
#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 10 // 10 seconds
const uint32_t RsGxsNetService::FRAGMENT_SIZE = 150000; 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, RsGixsReputation* reputations, RsGcxs* circles) RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs, RsGixsReputation* reputations, RsGcxs* circles, bool grpAutoSync)
: p3Config(servType), p3ThreadedService(servType), : p3Config(servType), p3ThreadedService(servType),
mTransactionTimeOut(TRANSAC_TIMEOUT), mServType(servType), mDataStore(gds), mTransactionN(0), mTransactionTimeOut(TRANSAC_TIMEOUT), mServType(servType), mDataStore(gds), mTransactionN(0),
mObserver(nxsObs), mNxsMutex("RsGxsNetService"), mNetMgr(netMgr), mSYNC_PERIOD(SYNC_PERIOD), mObserver(nxsObs), mNxsMutex("RsGxsNetService"), mNetMgr(netMgr), mSYNC_PERIOD(SYNC_PERIOD),
mSyncTs(0), mReputations(reputations), mCircles(circles) mSyncTs(0), mReputations(reputations), mCircles(circles), mGrpAutoSync(grpAutoSync), mGrpServerUpdateItem(NULL)
{ {
addSerialType(new RsNxsSerialiser(mServType)); addSerialType(new RsNxsSerialiser(mServType));
@ -85,13 +85,27 @@ void RsGxsNetService::syncWithPeers()
std::set<std::string>::iterator sit = peers.begin(); std::set<std::string>::iterator sit = peers.begin();
// for now just grps if(mGrpAutoSync)
for(; sit != peers.end(); sit++)
{ {
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType); // for now just grps
grp->clear(); for(; sit != peers.end(); sit++)
grp->PeerId(*sit); {
sendItem(grp);
const std::string peerId = *sit;
ClientGrpMap::const_iterator cit = mClientGrpUpdateMap.find(peerId);
uint32_t updateTS = 0;
if(cit != mClientGrpUpdateMap.end())
{
const RsGxsGrpUpdateItem *gui = cit->second;
updateTS = gui->grpUpdateTS;
}
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
grp->clear();
grp->PeerId(*sit);
grp->updateTS = updateTS;
sendItem(grp);
}
} }
#ifdef GXS_ENABLE_SYNC_MSGS #ifdef GXS_ENABLE_SYNC_MSGS
@ -108,7 +122,9 @@ void RsGxsNetService::syncWithPeers()
RsGxsGrpMetaData* meta = mit->second; RsGxsGrpMetaData* meta = mit->second;
if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ) if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )
{
grpIds.push_back(mit->first); grpIds.push_back(mit->first);
}
delete meta; delete meta;
} }
@ -122,13 +138,36 @@ void RsGxsNetService::syncWithPeers()
std::vector<RsGxsGroupId>::iterator vit = grpIds.begin(); std::vector<RsGxsGroupId>::iterator vit = grpIds.begin();
// now see if you have an updateTS so optimise whether you need
// to get a new list of peer data
RsGxsMsgUpdateItem* mui = NULL;
ClientMsgMap::const_iterator cit = mClientMsgUpdateMap.find(*sit);
if(cit != mClientMsgUpdateMap.end())
{
mui = cit->second;
}
for(; vit != grpIds.end(); vit++) for(; vit != grpIds.end(); vit++)
{ {
RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType); uint32_t updateTS = 0;
msg->clear(); if(mui)
msg->PeerId(*sit); {
msg->grpId = *vit; std::map<std::string, uint32_t>::const_iterator cit2 = mui->msgUpdateTS.find(*vit);
sendItem(msg);
if(cit2 != mui->msgUpdateTS.end())
{
updateTS = cit2->second;
}
}
RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType);
msg->clear();
msg->PeerId(*sit);
msg->grpId = *vit;
msg->updateTS = updateTS;
sendItem(msg);
} }
} }
#endif #endif
@ -524,20 +563,105 @@ void RsGxsNetService::collateMsgFragments(MsgFragments fragments, std::map<RsGxs
fragments.clear(); fragments.clear();
} }
class StoreHere
bool RsGxsNetService::loadList(std::list<RsItem*>& load)
{ {
return false; public:
StoreHere(RsGxsNetService::ClientGrpMap& cgm, RsGxsNetService::ClientMsgMap& cmm,
RsGxsNetService::ServerMsgMap& smm,
RsGxsServerGrpUpdateItem*& sgm) : mClientGrpMap(cgm), mClientMsgMap(cmm),
mServerMsgMap(smm), mServerGrpUpdateItem(sgm)
{}
void operator() (RsItem* item)
{
RsGxsMsgUpdateItem* mui;
RsGxsGrpUpdateItem* gui;
RsGxsServerGrpUpdateItem* gsui;
RsGxsServerMsgUpdateItem* msui;
if((mui = dynamic_cast<RsGxsMsgUpdateItem*>(item)) != NULL)
mClientMsgMap.insert(std::make_pair(mui->peerId, mui));
else if((gui = dynamic_cast<RsGxsGrpUpdateItem*>(item)) != NULL)
mClientGrpMap.insert(std::make_pair(gui->peerId, gui));
else if((msui = dynamic_cast<RsGxsServerMsgUpdateItem*>(item)) != NULL)
mServerMsgMap.insert(std::make_pair(msui->grpId, msui));
else if((gsui = dynamic_cast<RsGxsServerGrpUpdateItem*>(item)) != NULL)
{
if(mServerGrpUpdateItem == NULL)
{
mServerGrpUpdateItem = gsui;
}
else
{
#ifdef NXS_NET_DEBUG
std::cerr << "Error! More than one server group update item exists!" << std::endl;
#endif
delete gsui;
}
}
else
{
std::cerr << "Type not expected!" << std::endl;
}
}
private:
RsGxsNetService::ClientGrpMap& mClientGrpMap;
RsGxsNetService::ClientMsgMap& mClientMsgMap;
RsGxsNetService::ServerMsgMap& mServerMsgMap;
RsGxsServerGrpUpdateItem*& mServerGrpUpdateItem;
};
bool RsGxsNetService::loadList(std::list<RsItem *> &load)
{
std::for_each(load.begin(), load.end(), StoreHere(mClientGrpUpdateMap, mClientMsgUpdateMap,
mServerMsgUpdateMap, mGrpServerUpdateItem));
return true;
} }
#include <algorithm>
template <typename UpdateMap>
struct get_second : public std::unary_function<typename UpdateMap::value_type, RsItem*>
{
RsItem* operator()(const typename UpdateMap::value_type& value) const
{
return value.second;
}
};
bool RsGxsNetService::saveList(bool& cleanup, std::list<RsItem*>& save) bool RsGxsNetService::saveList(bool& cleanup, std::list<RsItem*>& save)
{ {
return false; RsStackMutex stack(mNxsMutex);
// hardcore templates
std::transform(mClientGrpUpdateMap.begin(), mClientGrpUpdateMap.end(),
std::back_inserter(save), get_second<ClientGrpMap>());
std::transform(mClientMsgUpdateMap.begin(), mClientMsgUpdateMap.end(),
std::back_inserter(save), get_second<ClientMsgMap>());
std::transform(mServerMsgUpdateMap.begin(), mServerMsgUpdateMap.end(),
std::back_inserter(save), get_second<ServerMsgMap>());
save.push_back(mGrpServerUpdateItem);
cleanup = false;
return true;
} }
RsSerialiser *RsGxsNetService::setupSerialiser() RsSerialiser *RsGxsNetService::setupSerialiser()
{ {
return NULL;
RsSerialiser *rss = new RsSerialiser;
rss->addSerialType(new RsGxsUpdateSerialiser(mServType));
return rss;
} }
void RsGxsNetService::recvNxsItemQueue(){ void RsGxsNetService::recvNxsItemQueue(){
@ -749,6 +873,7 @@ void RsGxsNetService::run(){
double timeDelta = 0.2; double timeDelta = 0.2;
int updateCounter = 0;
while(isRunning()){ while(isRunning()){
@ -758,6 +883,14 @@ void RsGxsNetService::run(){
Sleep((int) (timeDelta * 1000)); Sleep((int) (timeDelta * 1000));
#endif #endif
if(updateCounter == 3)
{
updateServerSyncTS();
updateCounter = 0;
}
else
updateCounter++;
// process active transactions // process active transactions
processTransactions(); processTransactions();
@ -767,13 +900,71 @@ void RsGxsNetService::run(){
// vetting of id and circle info // vetting of id and circle info
runVetting(); runVetting();
processExplicitGroupRequests();
} }
} }
void RsGxsNetService::updateServerSyncTS()
{
RsStackMutex stack(mNxsMutex);
std::map<RsGxsGroupId, RsGxsGrpMetaData*> gxsMap;
// retrieve all grps and update TS
mDataStore->retrieveGxsGrpMetaData(gxsMap);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = gxsMap.begin();
// as a grp list server also note this is the latest item you have
if(mGrpServerUpdateItem == NULL)
{
mGrpServerUpdateItem = new RsGxsServerGrpUpdateItem(mServType);
}
bool change = false;
for(; mit != gxsMap.end(); mit++)
{
const RsGxsGroupId& grpId = mit->first;
RsGxsGrpMetaData* grpMeta = mit->second;
ServerMsgMap::iterator mapIT = mServerMsgUpdateMap.find(grpId);
RsGxsServerMsgUpdateItem* msui = NULL;
if(mapIT == mServerMsgUpdateMap.end())
{
msui = new RsGxsServerMsgUpdateItem(mServType);
msui->grpId = grpMeta->mGroupId;
mServerMsgUpdateMap.insert(std::make_pair(msui->grpId, msui));
}else
{
msui = mapIT->second;
}
if(grpMeta->mLastPost > msui->msgUpdateTS )
{
change = true;
msui->msgUpdateTS = grpMeta->mLastPost;
}
// this might be very inefficient with time
if(grpMeta->mRecvTS > mGrpServerUpdateItem->grpUpdateTS)
{
mGrpServerUpdateItem->grpUpdateTS = grpMeta->mRecvTS;
change = true;
}
}
// actual change in config settings, then save configuration
if(change)
IndicateConfigChanged();
freeAndClearContainerResource<std::map<RsGxsGroupId, RsGxsGrpMetaData*>,
RsGxsGrpMetaData*>(gxsMap);
}
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;
} }
void RsGxsNetService::processTransactions(){ void RsGxsNetService::processTransactions(){
@ -1036,25 +1227,52 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
// notify listener of grps // notify listener of grps
mObserver->notifyNewGroups(grps); mObserver->notifyNewGroups(grps);
// now note this as the latest you've received from this peer
std::string peerFrom = tr->mTransaction->PeerId();
uint32_t updateTS = tr->mTransaction->updateTS;
ClientGrpMap::iterator it = mClientGrpUpdateMap.find(peerFrom);
RsGxsGrpUpdateItem* item = NULL;
if(it != mClientGrpUpdateMap.end())
{
item = it->second;
}else
{
item = new RsGxsGrpUpdateItem(mServType);
mClientGrpUpdateMap.insert(
std::make_pair(peerFrom, item));
}
item->grpUpdateTS = updateTS;
item->peerId = peerFrom;
IndicateConfigChanged();
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS) }else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
{ {
std::vector<RsNxsMsg*> msgs; std::vector<RsNxsMsg*> msgs;
std::string grpId;
while(tr->mItems.size() > 0) while(tr->mItems.size() > 0)
{ {
RsNxsMsg* msg = dynamic_cast<RsNxsMsg*>(tr->mItems.front()); RsNxsMsg* msg = dynamic_cast<RsNxsMsg*>(tr->mItems.front());
if(msg) if(msg)
{ {
tr->mItems.pop_front(); if(grpId.empty())
msgs.push_back(msg); grpId = msg->grpId;
tr->mItems.pop_front();
msgs.push_back(msg);
} }
else else
{ {
#ifdef NXS_NET_DEBUG #ifdef NXS_NET_DEBUG
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg" std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg"
<< std::endl; << std::endl;
#endif #endif
} }
} }
@ -1078,6 +1296,10 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
// notify listener of msgs // notify listener of msgs
mObserver->notifyNewMessages(msgs); mObserver->notifyNewMessages(msgs);
// now note that this is the latest you've received from this peer
// for the grp id
locked_doMsgUpdateWork(tr->mTransaction, grpId);
} }
}else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){ }else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){
// don't do anything transaction will simply be cleaned // don't do anything transaction will simply be cleaned
@ -1085,6 +1307,33 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
return; return;
} }
void RsGxsNetService::locked_doMsgUpdateWork(const RsNxsTransac *nxsTrans, const std::string &grpId)
{
// firts check if peer exists
const std::string& peerFrom = nxsTrans->PeerId();
ClientMsgMap::iterator it = mClientMsgUpdateMap.find(peerFrom);
RsGxsMsgUpdateItem* mui = NULL;
// now update the peer's entry for this grp id
if(it != mClientMsgUpdateMap.end())
{
mui = it->second;
}
else
{
mui = new RsGxsMsgUpdateItem(mServType);
mClientMsgUpdateMap.insert(std::make_pair(peerFrom, mui));
}
mui->msgUpdateTS[grpId] = nxsTrans->updateTS;
mui->peerId = peerFrom;
IndicateConfigChanged();
}
void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr) void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr)
{ {
uint16_t flag = tr->mTransaction->transactFlag; uint16_t flag = tr->mTransaction->transactFlag;
@ -1125,6 +1374,7 @@ void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr)
std::cerr << "complete Sending Grp Data, transN: " << std::cerr << "complete Sending Grp Data, transN: " <<
tr->mTransaction->transactionNumber << std::endl; tr->mTransaction->transactionNumber << std::endl;
#endif #endif
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS) }else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
{ {
#ifdef NXS_NET_DEBUG #ifdef NXS_NET_DEBUG
@ -1166,7 +1416,7 @@ void RsGxsNetService::locked_pushMsgTransactionFromList(
newTrans->mTimeOut = time(NULL) + mTransactionTimeOut; newTrans->mTimeOut = time(NULL) + mTransactionTimeOut;
// create transaction copy with your id to indicate // create transaction copy with your id to indicate
// its an outgoing transaction // its an outgoing transaction
newTrans->mTransaction = new RsNxsTransac(*transac); newTrans->mTransaction = new RsNxsTransac(*transac);
newTrans->mTransaction->PeerId(mOwnId); newTrans->mTransaction->PeerId(mOwnId);
sendItem(transac); sendItem(transac);
{ {
@ -1248,7 +1498,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
msgIdSet.insert((*vit)->mMsgId); msgIdSet.insert((*vit)->mMsgId);
delete(*vit); delete(*vit);
} }
msgMetaV.clear(); msgMetaV.clear();
// get unique id for this transaction // get unique id for this transaction
uint32_t transN = locked_getTransactionId(); uint32_t transN = locked_getTransactionId();
@ -1261,6 +1511,9 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
MsgAuthorV toVet; MsgAuthorV toVet;
std::list<std::string> peers;
peers.push_back(tr->mTransaction->PeerId());
for(; llit != msgItemL.end(); llit++) for(; llit != msgItemL.end(); llit++)
{ {
RsNxsSyncMsgItem*& syncItem = *llit; RsNxsSyncMsgItem*& syncItem = *llit;
@ -1294,7 +1547,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
else else
{ {
// preload for speed // preload for speed
mReputations->loadReputation(syncItem->authorId); mReputations->loadReputation(syncItem->authorId, peers);
MsgAuthEntry entry; MsgAuthEntry entry;
entry.mAuthorId = syncItem->authorId; entry.mAuthorId = syncItem->authorId;
entry.mGrpId = syncItem->grpId; entry.mGrpId = syncItem->grpId;
@ -1375,6 +1628,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
} }
std::map<std::string, RsGxsGrpMetaData*> grpMetaMap; std::map<std::string, RsGxsGrpMetaData*> grpMetaMap;
std::map<std::string, RsGxsGrpMetaData*>::const_iterator metaIter;
mDataStore->retrieveGxsGrpMetaData(grpMetaMap); mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
// now do compare and add loop // now do compare and add loop
@ -1384,13 +1638,20 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
uint32_t transN = locked_getTransactionId(); uint32_t transN = locked_getTransactionId();
GrpAuthorV toVet; GrpAuthorV toVet;
std::list<std::string> peers;
peers.push_back(tr->mTransaction->PeerId());
for(; llit != grpItemL.end(); llit++) for(; llit != grpItemL.end(); llit++)
{ {
RsNxsSyncGrpItem*& grpSyncItem = *llit; RsNxsSyncGrpItem*& grpSyncItem = *llit;
const std::string& grpId = grpSyncItem->grpId; const std::string& grpId = grpSyncItem->grpId;
metaIter = grpMetaMap.find(grpId);
bool haveItem = metaIter != grpMetaMap.end();
bool latestVersion = false;
if(grpMetaMap.find(grpId) == grpMetaMap.end()){ latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs;
if(!haveItem || (haveItem && latestVersion) ){
// determine if you need to check reputation // determine if you need to check reputation
bool checkRep = !grpSyncItem->authorId.empty(); bool checkRep = !grpSyncItem->authorId.empty();
@ -1412,7 +1673,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
else else
{ {
// preload reputation for later // preload reputation for later
mReputations->loadReputation(grpSyncItem->authorId); mReputations->loadReputation(grpSyncItem->authorId, peers);
GrpAuthEntry entry; GrpAuthEntry entry;
entry.mAuthorId = grpSyncItem->authorId; entry.mAuthorId = grpSyncItem->authorId;
entry.mGrpId = grpSyncItem->grpId; entry.mGrpId = grpSyncItem->grpId;
@ -1505,11 +1766,15 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr)
return; return;
} }
uint32_t updateTS = 0;
if(mGrpServerUpdateItem)
updateTS = mGrpServerUpdateItem->grpUpdateTS;
RsNxsTransac* ntr = new RsNxsTransac(mServType); RsNxsTransac* ntr = new RsNxsTransac(mServType);
ntr->transactionNumber = transN; ntr->transactionNumber = transN;
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 | ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
RsNxsTransac::FLAG_TYPE_GRPS; RsNxsTransac::FLAG_TYPE_GRPS;
ntr->updateTS = updateTS;
ntr->nItems = grps.size(); ntr->nItems = grps.size();
ntr->PeerId(tr->mTransaction->PeerId()); ntr->PeerId(tr->mTransaction->PeerId());
@ -1625,12 +1890,17 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
return; return;
} }
std::string grpId = "";
for(;lit != tr->mItems.end(); lit++) for(;lit != tr->mItems.end(); lit++)
{ {
RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit); RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit);
if (item) if (item)
{ {
msgIds[item->grpId].push_back(item->msgId); msgIds[item->grpId].push_back(item->msgId);
if(grpId.empty())
grpId = item->grpId;
} }
else else
{ {
@ -1687,10 +1957,18 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
return; return;
} }
uint32_t updateTS = 0;
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(grpId);
if(cit != mServerMsgUpdateMap.end())
updateTS = cit->second->msgUpdateTS;
RsNxsTransac* ntr = new RsNxsTransac(mServType); RsNxsTransac* ntr = new RsNxsTransac(mServType);
ntr->transactionNumber = transN; ntr->transactionNumber = transN;
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 | ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
RsNxsTransac::FLAG_TYPE_MSGS; RsNxsTransac::FLAG_TYPE_MSGS;
ntr->updateTS = updateTS;
ntr->nItems = msgSize; ntr->nItems = msgSize;
ntr->PeerId(peerId); ntr->PeerId(peerId);
@ -1766,13 +2044,32 @@ void RsGxsNetService::locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList
locked_addTransaction(tr); locked_addTransaction(tr);
} }
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncGrp *item)
{
// don't sync if you have no new updates for this peer
if(mGrpServerUpdateItem)
{
if(item->updateTS >= mGrpServerUpdateItem->grpUpdateTS && item->updateTS != 0)
{
return false;
}
}
return true;
}
void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item) void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item)
{ {
RsStackMutex stack(mNxsMutex); RsStackMutex stack(mNxsMutex);
if(!locked_CanReceiveUpdate(item))
return;
std::string peer = item->PeerId(); std::string peer = item->PeerId();
std::map<std::string, RsGxsGrpMetaData*> grp; std::map<std::string, RsGxsGrpMetaData*> grp;
mDataStore->retrieveGxsGrpMetaData(grp); mDataStore->retrieveGxsGrpMetaData(grp);
@ -1826,6 +2123,8 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item)
return; return;
} }
bool RsGxsNetService::canSendGrpId(const std::string& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet) bool RsGxsNetService::canSendGrpId(const std::string& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet)
{ {
// first do the simple checks // first do the simple checks
@ -1881,10 +2180,31 @@ bool RsGxsNetService::canSendGrpId(const std::string& sslId, RsGxsGrpMetaData& g
return true; return true;
} }
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsg *item)
{
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
if(cit != mServerMsgUpdateMap.end())
{
const RsGxsServerMsgUpdateItem *msui = cit->second;
if(item->updateTS >= msui->msgUpdateTS && item->updateTS != 0)
{
#ifdef NXS_NET_DEBUG
std::cerr << "RsGxsNetService::locked_CanReceiveUpdate(): Msgs up to date" << std::endl;
#endif
return false;
}
}
return true;
}
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsg* item) void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsg* item)
{ {
RsStackMutex stack(mNxsMutex); RsStackMutex stack(mNxsMutex);
if(!locked_CanReceiveUpdate(item))
return;
const std::string& peer = item->PeerId(); const std::string& peer = item->PeerId();
GxsMsgMetaResult metaResult; GxsMsgMetaResult metaResult;
@ -2066,3 +2386,40 @@ void RsGxsNetService::setSyncAge(uint32_t age)
} }
int RsGxsNetService::requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId)
{
RsStackMutex stack(mNxsMutex);
mExplicitRequest[peerId].assign(grpId.begin(), grpId.end());
return 1;
}
void RsGxsNetService::processExplicitGroupRequests()
{
RsStackMutex stack(mNxsMutex);
std::map<std::string, std::list<RsGxsGroupId> >::const_iterator cit = mExplicitRequest.begin();
for(; cit != mExplicitRequest.end(); cit++)
{
const std::string& peerId = cit->first;
const std::list<RsGxsGroupId>& groupIdList = cit->second;
std::list<RsNxsItem*> grpSyncItems;
std::list<RsGxsGroupId>::const_iterator git = groupIdList.begin();
uint32_t transN = locked_getTransactionId();
for(; git != groupIdList.end(); git++)
{
RsNxsSyncGrpItem* item = new RsNxsSyncGrpItem(mServType);
item->grpId = *git;
item->PeerId(peerId);
item->flag = RsNxsSyncGrpItem::FLAG_REQUEST;
item->transactionNumber = transN;
grpSyncItems.push_back(item);
}
if(!grpSyncItems.empty())
locked_pushGrpTransactionFromList(grpSyncItems, peerId, transN);
}
mExplicitRequest.clear();
}

View file

@ -34,6 +34,7 @@
#include "rsnxsobserver.h" #include "rsnxsobserver.h"
#include "pqi/p3linkmgr.h" #include "pqi/p3linkmgr.h"
#include "serialiser/rsnxsitems.h" #include "serialiser/rsnxsitems.h"
#include "serialiser/rsgxsupdateitems.h"
#include "rsgxsnetutils.h" #include "rsgxsnetutils.h"
#include "pqi/p3cfgmgr.h" #include "pqi/p3cfgmgr.h"
#include "rsgixs.h" #include "rsgixs.h"
@ -73,7 +74,7 @@ public:
* arrive * arrive
*/ */
RsGxsNetService(uint16_t servType, RsGeneralDataService* gds, RsNxsNetMgr* netMgr, RsGxsNetService(uint16_t servType, RsGeneralDataService* gds, RsNxsNetMgr* netMgr,
RsNxsObserver* nxsObs = NULL, RsGixsReputation* repuations = NULL, RsGcxs* circles = NULL); RsNxsObserver* nxsObs = NULL, RsGixsReputation* repuations = NULL, RsGcxs* circles = NULL, bool grpAutoSync = true);
virtual ~RsGxsNetService(); virtual ~RsGxsNetService();
@ -115,7 +116,7 @@ public:
* @param msgId the messages to retrieve * @param msgId the messages to retrieve
* @return request token to be redeemed * @return request token to be redeemed
*/ */
int requestMsg(const std::string& msgId, uint8_t hops){ return 0;} int requestMsg(const RsGxsGrpMsgIdPair& msgId){ return 0;}
/*! /*!
* Request for this group is sent through to peers on your network * Request for this group is sent through to peers on your network
@ -123,7 +124,7 @@ public:
* @param enabled set to false to disable pause, and true otherwise * @param enabled set to false to disable pause, and true otherwise
* @return request token to be redeemed * @return request token to be redeemed
*/ */
int requestGrp(const std::list<std::string>& grpId, uint8_t hops){ return 0;} int requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId);
/* p3Config methods */ /* p3Config methods */
@ -322,6 +323,15 @@ private:
bool locked_canReceive(const RsGxsGrpMetaData * const grpMeta, const std::string& peerId); bool locked_canReceive(const RsGxsGrpMetaData * const grpMeta, const std::string& peerId);
void processExplicitGroupRequests();
void locked_doMsgUpdateWork(const RsNxsTransac* nxsTrans, const std::string& grpId);
void updateServerSyncTS();
bool locked_CanReceiveUpdate(const RsNxsSyncGrp* item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsg* item);
private: private:
typedef std::vector<RsNxsGrp*> GrpFragments; typedef std::vector<RsNxsGrp*> GrpFragments;
@ -418,10 +428,30 @@ private:
RsGcxs* mCircles; RsGcxs* mCircles;
RsGixsReputation* mReputations; RsGixsReputation* mReputations;
bool mGrpAutoSync;
// need to be verfied // need to be verfied
std::vector<AuthorPending*> mPendingResp; std::vector<AuthorPending*> mPendingResp;
std::vector<GrpCircleVetting*> mPendingCircleVets; std::vector<GrpCircleVetting*> mPendingCircleVets;
std::map<std::string, std::list<RsGxsGroupId> > mExplicitRequest;
// nxs sync optimisation
// can pull dynamically the latest timestamp for each message
public:
typedef std::map<std::string, RsGxsMsgUpdateItem*> ClientMsgMap;
typedef std::map<std::string, RsGxsServerMsgUpdateItem*> ServerMsgMap;
typedef std::map<std::string, RsGxsGrpUpdateItem*> ClientGrpMap;
private:
ClientMsgMap mClientMsgUpdateMap;
ServerMsgMap mServerMsgUpdateMap;
ClientGrpMap mClientGrpUpdateMap;
RsGxsServerGrpUpdateItem* mGrpServerUpdateItem;
}; };
#endif // RSGXSNETSERVICE_H #endif // RSGXSNETSERVICE_H

View file

@ -47,14 +47,16 @@ bool AuthorPending::expired() const
} }
bool AuthorPending::getAuthorRep(GixsReputation& rep, bool AuthorPending::getAuthorRep(GixsReputation& rep,
const std::string& authorId) const std::string& authorId, const std::string& peerId)
{ {
if(mRep->haveReputation(authorId)) if(mRep->haveReputation(authorId))
{ {
return mRep->getReputation(authorId, rep); return mRep->getReputation(authorId, rep);
} }
mRep->loadReputation(authorId); std::list<std::string> peers;
peers.push_back(peerId);
mRep->loadReputation(authorId, peers);
return false; return false;
} }
@ -94,7 +96,7 @@ bool MsgRespPending::accepted()
if(!entry.mPassedVetting) if(!entry.mPassedVetting)
{ {
GixsReputation rep; GixsReputation rep;
if(getAuthorRep(rep, entry.mAuthorId)) if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
{ {
if(rep.score > mCutOff) if(rep.score > mCutOff)
{ {
@ -129,7 +131,7 @@ bool GrpRespPending::accepted()
{ {
GixsReputation rep; GixsReputation rep;
if(getAuthorRep(rep, entry.mAuthorId)) if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
{ {
if(rep.score > mCutOff) if(rep.score > mCutOff)
{ {

View file

@ -141,7 +141,7 @@ protected:
* @param authorId reputation to get * @param authorId reputation to get
* @return true if successfully retrieve repution * @return true if successfully retrieve repution
*/ */
bool getAuthorRep(GixsReputation& rep, const std::string& authorId); bool getAuthorRep(GixsReputation& rep, const std::string& authorId, const std::string& peerId);
private: private:

View file

@ -129,4 +129,24 @@ private:
}; };
class GroupUpdate
{
public:
GroupUpdate() : oldGrpMeta(NULL), newGrp(NULL), validUpdate(false)
{}
RsGxsGrpMetaData* oldGrpMeta;
RsNxsGrp* newGrp;
bool validUpdate;
};
class GroupUpdatePublish
{
public:
GroupUpdatePublish(RsGxsGrpItem* item, RsGxsGroupUpdateMeta updateMeta, uint32_t token)
: grpItem(item), mToken(token), mUpdateMeta(updateMeta) {}
RsGxsGrpItem* grpItem;
RsGxsGroupUpdateMeta mUpdateMeta;
uint32_t mToken;
};
#endif /* GXSUTIL_H_ */ #endif /* GXSUTIL_H_ */

View file

@ -68,21 +68,6 @@ public:
*/ */
virtual void setSyncAge(uint32_t age) = 0; virtual void setSyncAge(uint32_t age) = 0;
/*!
* Explicitly requests all the groups contained by a peer
* Circumvents polling of peers for message
* @param peerId id of peer
*/
virtual void requestGroupsOfPeer(const std::string& peerId) = 0;
/*!
* get messages of a peer for a given group id, this circumvents the normal
* polling of peers for messages of given group id
* @param peerId Id of peer
* @param grpId id of group to request messages for
*/
virtual void requestMessagesOfPeer(const std::string& peerId, const std::string& grpId) = 0;
/*! /*!
* Initiates a search through the network * Initiates a search through the network
* This returns messages which contains the search terms set in RsGxsSearch * This returns messages which contains the search terms set in RsGxsSearch
@ -116,7 +101,7 @@ public:
* @param msgId the messages to retrieve * @param msgId the messages to retrieve
* @return request token to be redeemed * @return request token to be redeemed
*/ */
virtual int requestMsg(const std::string& msgId, uint8_t hops) = 0; virtual int requestMsg(const RsGxsGrpMsgIdPair& msgId) = 0;
/*! /*!
* Request for this group is sent through to peers on your network * Request for this group is sent through to peers on your network
@ -124,7 +109,7 @@ public:
* @param enabled set to false to disable pause, and true otherwise * @param enabled set to false to disable pause, and true otherwise
* @return request token to be redeemed * @return request token to be redeemed
*/ */
virtual int requestGrp(const std::list<std::string>& grpId, uint8_t hops) = 0; virtual int requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId) = 0;
}; };

View file

@ -390,6 +390,9 @@ HEADERS += serialiser/rsbaseserial.h \
serialiser/rsdiscovery2items.h \ serialiser/rsdiscovery2items.h \
serialiser/rsheartbeatitems.h \ serialiser/rsheartbeatitems.h \
serialiser/rsrttitems.h \ serialiser/rsrttitems.h \
serialiser/rsgxsrecognitems.h \
serialiser/rstunnelitems.h \
serialiser/rsgxsupdateitems.h
HEADERS += services/p3chatservice.h \ HEADERS += services/p3chatservice.h \
services/p3msgservice.h \ services/p3msgservice.h \
@ -425,6 +428,7 @@ HEADERS += util/folderiterator.h \
util/pugiconfig.h \ util/pugiconfig.h \
util/rsmemcache.h \ util/rsmemcache.h \
util/rstickevent.h \ util/rstickevent.h \
util/rsrecogn.h \
SOURCES += dbase/cachestrapper.cc \ SOURCES += dbase/cachestrapper.cc \
dbase/fimonitor.cc \ dbase/fimonitor.cc \
@ -522,6 +526,9 @@ SOURCES += serialiser/rsbaseserial.cc \
serialiser/rsdiscovery2items.cc \ serialiser/rsdiscovery2items.cc \
serialiser/rsheartbeatitems.cc \ serialiser/rsheartbeatitems.cc \
serialiser/rsrttitems.cc \ serialiser/rsrttitems.cc \
serialiser/rsgxsrecognitems.cc \
serialiser/rstunnelitems.cc \
serialiser/rsgxsupdateitems.cc
SOURCES += services/p3chatservice.cc \ SOURCES += services/p3chatservice.cc \
services/p3msgservice.cc \ services/p3msgservice.cc \
@ -559,6 +566,7 @@ SOURCES += util/folderiterator.cc \
util/rsaes.cc \ util/rsaes.cc \
util/rsrandom.cc \ util/rsrandom.cc \
util/rstickevent.cc \ util/rstickevent.cc \
util/rsrecogn.cc \
upnp_miniupnpc { upnp_miniupnpc {

View file

@ -84,6 +84,14 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0; virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0; virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0;
/*!
* To update forum group with new information
* @param token the token used to check completion status of update
* @param group group to be updated, groupId element must be set or will be rejected
* @return false groupId not set, true if set and accepted (still check token for completion)
*/
virtual bool updateGroup(uint32_t &token, RsGxsGroupUpdateMeta&, RsGxsForumGroup &group) = 0;
}; };

View file

@ -46,8 +46,9 @@ public:
mGroupStatus = 0; mGroupStatus = 0;
mCircleType = 0; mCircleType = 0;
mAuthenFlags = 0;
//mPublishTs = 0; mPublishTs = 0;
} }
void operator =(const RsGxsGrpMetaData& rGxsMeta); void operator =(const RsGxsGrpMetaData& rGxsMeta);
@ -128,7 +129,6 @@ public:
class GxsGroupStatistic class GxsGroupStatistic
{ {
public: public:
/// number of message /// number of message
RsGxsGroupId mGrpId; RsGxsGroupId mGrpId;
uint32_t mNumMsgs; uint32_t mNumMsgs;
@ -147,4 +147,56 @@ public:
uint32_t mSizeStore; uint32_t mSizeStore;
}; };
class UpdateItem
{
public:
virtual ~UpdateItem() { }
};
class StringUpdateItem : public UpdateItem
{
public:
StringUpdateItem(const std::string update) : mUpdate(update) {}
const std::string& getUpdate() const { return mUpdate; }
private:
std::string mUpdate;
};
class RsGxsGroupUpdateMeta
{
public:
// expand as support is added for other utypes
enum UpdateType { DESCRIPTION, NAME };
RsGxsGroupUpdateMeta(const std::string& groupId) : mGroupId(groupId) {}
typedef std::map<UpdateType, std::string> GxsMetaUpdate;
/*!
* Only one item of a utype can exist
* @param utype the type of meta update
* @param item update item containing the change value
*/
void setMetaUpdate(UpdateType utype, const std::string& update)
{
mUpdates[utype] = update;
}
/*!
* @param utype update type to remove
* @return false if update did not exist, true if update successfully removed
*/
bool removeUpdateType(UpdateType utype){ return mUpdates.erase(utype) == 1; }
const GxsMetaUpdate* getUpdates() const { return &mUpdates; }
const std::string& getGroupId() const { return mGroupId; }
private:
GxsMetaUpdate mUpdates;
std::string mGroupId;
};
#endif /* RSGXSIFACETYPES_H_ */ #endif /* RSGXSIFACETYPES_H_ */

View file

@ -55,6 +55,8 @@ extern RsIdentity *rsIdentity;
#define RSID_RELATION_OTHER 0x0008 #define RSID_RELATION_OTHER 0x0008
#define RSID_RELATION_UNKNOWN 0x0010 #define RSID_RELATION_UNKNOWN 0x0010
#define RSRECOGN_MAX_TAGINFO 5
std::string rsIdTypeToString(uint32_t idtype); std::string rsIdTypeToString(uint32_t idtype);
class RsGxsIdGroup class RsGxsIdGroup
@ -82,6 +84,9 @@ class RsGxsIdGroup
std::string mPgpIdHash; std::string mPgpIdHash;
std::string mPgpIdSign; // Need a signature as proof - otherwise anyone could add others Hashes. std::string mPgpIdSign; // Need a signature as proof - otherwise anyone could add others Hashes.
// Recognition Strings. MAX# defined above.
std::list<std::string> mRecognTags;
// Not Serialised - for GUI's benefit. // Not Serialised - for GUI's benefit.
bool mPgpKnown; bool mPgpKnown;
std::string mPgpId; std::string mPgpId;
@ -163,6 +168,36 @@ class RsIdOpinion
typedef std::string RsGxsId; // TMP. => typedef std::string RsGxsId; // TMP. =>
class RsRecognTag
{
public:
RsRecognTag(uint16_t tc, uint16_t tt, bool v)
:tag_class(tc), tag_type(tt), valid(v) { return; }
uint16_t tag_class;
uint16_t tag_type;
bool valid;
};
class RsRecognTagDetails
{
public:
RsRecognTagDetails()
:valid_from(0), valid_to(0), tag_class(0), tag_type(0),
is_valid(false), is_pending(false) { return; }
time_t valid_from;
time_t valid_to;
uint16_t tag_class;
uint16_t tag_type;
std::string signer;
bool is_valid;
bool is_pending;
};
class RsIdentityDetails class RsIdentityDetails
{ {
public: public:
@ -181,6 +216,9 @@ class RsIdentityDetails
bool mPgpKnown; bool mPgpKnown;
std::string mPgpId; std::string mPgpId;
// Recogn details.
std::list<RsRecognTag> mRecognTags;
// reputation details. // reputation details.
double mOpinion; double mOpinion;
double mReputation; double mReputation;
@ -230,6 +268,13 @@ virtual bool getOwnIds(std::list<RsGxsId> &ownIds) = 0;
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion) = 0; virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion) = 0;
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params) = 0; virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params) = 0;
virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group) = 0;
virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
const std::string &tag, RsRecognTagDetails &details) = 0;
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag) = 0;
// Specific RsIdentity Functions.... // Specific RsIdentity Functions....
/* Specific Service Data */ /* Specific Service Data */
/* We expose these initially for testing / GUI purposes. /* We expose these initially for testing / GUI purposes.

View file

@ -2282,7 +2282,7 @@ int RsServer::StartupRetroShare()
std::string currGxsDir = RsInitConfig::configDir + "/GXS_phase2"; std::string currGxsDir = RsInitConfig::configDir + "/GXS_phase2";
#ifdef GXS_DEV_TESTNET // Different Directory for testing. #ifdef GXS_DEV_TESTNET // Different Directory for testing.
currGxsDir += "_TESTNET5"; currGxsDir += "_TESTNET6";
#endif #endif
bool cleanUpGxsDir = false; bool cleanUpGxsDir = false;
@ -2323,8 +2323,10 @@ int RsServer::StartupRetroShare()
// create GXS photo service // create GXS photo service
RsGxsNetService* gxsid_ns = new RsGxsNetService( RsGxsNetService* gxsid_ns = new RsGxsNetService(
RS_SERVICE_GXSV2_TYPE_GXSID, gxsid_ds, nxsMgr, RS_SERVICE_GXSV2_TYPE_GXSID, gxsid_ds, nxsMgr,
mGxsIdService, mGxsIdService, mGxsCircles); mGxsIdService, mGxsIdService, mGxsCircles,
false); // don't synchronise group automatic (need explicit group request)
mGxsIdService->setNes(gxsid_ns);
/**** GxsCircle service ****/ /**** GxsCircle service ****/
@ -2543,6 +2545,19 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("bitdht.cfg", mBitDht); mConfigMgr->addConfiguration("bitdht.cfg", mBitDht);
#endif #endif
#ifdef RS_ENABLE_GXS
mConfigMgr->addConfiguration("identity.cfg", gxsid_ns);
mConfigMgr->addConfiguration("gxsforums.cfg", gxsforums_ns);
mConfigMgr->addConfiguration("gxschannels.cfg", gxschannels_ns);
mConfigMgr->addConfiguration("gxscircles.cfg", gxscircles_ns);
mConfigMgr->addConfiguration("posted.cfg", posted_ns);
mConfigMgr->addConfiguration("wire.cfg", wire_ns);
mConfigMgr->addConfiguration("wiki.cfg", wiki_ns);
mConfigMgr->addConfiguration("photo.cfg", photo_ns);
#endif
mPluginsManager->addConfigurations(mConfigMgr) ; mPluginsManager->addConfigurations(mConfigMgr) ;
ftserver->addConfiguration(mConfigMgr); ftserver->addConfiguration(mConfigMgr);
@ -2683,7 +2698,6 @@ int RsServer::StartupRetroShare()
createThread(*gxsforums_ns); createThread(*gxsforums_ns);
createThread(*gxschannels_ns); createThread(*gxschannels_ns);
#endif // RS_ENABLE_GXS #endif // RS_ENABLE_GXS
ftserver->StartupThreads(); ftserver->StartupThreads();

View file

@ -122,20 +122,30 @@ void RsGxsIdGroupItem::clear()
group.mPgpIdHash.clear(); group.mPgpIdHash.clear();
group.mPgpIdSign.clear(); group.mPgpIdSign.clear();
group.mRecognTags.clear();
group.mPgpKnown = false; group.mPgpKnown = false;
group.mPgpId.clear(); group.mPgpId.clear();
} }
std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent) std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent)
{ {
printRsItemBase(out, "RsGxsIdGroupItem", indent); printRsItemBase(out, "RsGxsIdGroupItem", indent);
uint16_t int_Indent = indent + 2; uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "MetaData: " << meta << std::endl;
printIndent(out, int_Indent); printIndent(out, int_Indent);
out << "PgpIdHash: " << group.mPgpIdHash << std::endl; out << "PgpIdHash: " << group.mPgpIdHash << std::endl;
printIndent(out, int_Indent); printIndent(out, int_Indent);
out << "PgpIdSign: " << group.mPgpIdSign << std::endl; out << "PgpIdSign: " << group.mPgpIdSign << std::endl;
printIndent(out, int_Indent);
out << "RecognTags:" << std::endl;
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, group.mRecognTags);
set.print(out, int_Indent + 2);
printRsItemEnd(out ,"RsGxsIdGroupItem", indent); printRsItemEnd(out ,"RsGxsIdGroupItem", indent);
return out; return out;
@ -151,6 +161,9 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdGroupItem(RsGxsIdGroupItem *item)
s += GetTlvStringSize(group.mPgpIdHash); s += GetTlvStringSize(group.mPgpIdHash);
s += GetTlvStringSize(group.mPgpIdSign); s += GetTlvStringSize(group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
s += set.TlvSize();
return s; return s;
} }
@ -182,6 +195,9 @@ bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *da
ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdHash); ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdHash);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdSign); ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
ok &= set.SetTlv(data, tlvsize, &offset);
if(offset != tlvsize) if(offset != tlvsize)
{ {
#ifdef GXSID_DEBUG #ifdef GXSID_DEBUG
@ -239,6 +255,10 @@ RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint3
ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdHash); ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdHash);
ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdSign); ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
ok &= set.GetTlv(data, rssize, &offset);
if (offset != rssize) if (offset != rssize)
{ {
#ifdef GXSID_DEBUG #ifdef GXSID_DEBUG

View file

@ -52,7 +52,8 @@
std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta) std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta)
{ {
out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]"; out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName;
out << " PublishTs: " << meta.mPublishTs << " ]";
return out; return out;
} }

View file

@ -0,0 +1,600 @@
/*
* libretroshare/src/serialiser: rsgxsrecogitems.cc
*
* RetroShare Serialiser.
*
* Copyright 2013-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "serialiser/rsbaseserial.h"
#include "serialiser/rsgxsrecognitems.h"
/***
#define RSSERIAL_DEBUG 1
***/
#include <iostream>
/*************************************************************************/
RsGxsRecognReqItem::~RsGxsRecognReqItem()
{
return;
}
void RsGxsRecognReqItem::clear()
{
issued_at = 0;
period = 0;
tag_class = 0;
tag_type = 0;
identity.clear();
nickname.clear();
comment.clear();
sign.TlvClear();
}
std::ostream &RsGxsRecognReqItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognReqItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "issued_at: " << issued_at << std::endl;
printIndent(out, int_Indent);
out << "period: " << period << std::endl;
printIndent(out, int_Indent);
out << "tag_class: " << tag_class << std::endl;
printIndent(out, int_Indent);
out << "tag_type: " << tag_type << std::endl;
printIndent(out, int_Indent);
out << "identity: " << identity << std::endl;
printIndent(out, int_Indent);
out << "nickname: " << nickname << std::endl;
printIndent(out, int_Indent);
out << "comment: " << comment << std::endl;
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognReqItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeReq(RsGxsRecognReqItem *item)
{
uint32_t s = 8; /* header */
s += 4; // issued_at;
s += 4; // period;
s += 2; // tag_class;
s += 2; // tag_type;
s += GetTlvStringSize(item->identity);
s += GetTlvStringSize(item->nickname);
s += GetTlvStringSize(item->comment);
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseReq(RsGxsRecognReqItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeReq(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->issued_at);
ok &= setRawUInt32(data, tlvsize, &offset, item->period);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_class);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_type);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->comment);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognReqItem *RsGxsRecognSerialiser::deserialiseReq(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_REQ != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognReqItem *item = new RsGxsRecognReqItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= getRawUInt32(data, tlvsize, &offset, &(item->issued_at));
ok &= getRawUInt32(data, tlvsize, &offset, &(item->period));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_class));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_type));
ok &= GetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->comment);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
RsGxsRecognTagItem::~RsGxsRecognTagItem()
{
return;
}
void RsGxsRecognTagItem::clear()
{
valid_from = 0;
valid_to = 0;
tag_class = 0;
tag_type = 0;
identity.clear();
nickname.clear();
sign.TlvClear();
}
std::ostream &RsGxsRecognTagItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognTagItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "valid_from: " << valid_from << std::endl;
printIndent(out, int_Indent);
out << "valid_to: " << valid_to << std::endl;
printIndent(out, int_Indent);
out << "tag_class: " << tag_class << std::endl;
printIndent(out, int_Indent);
out << "tag_type: " << tag_type << std::endl;
printIndent(out, int_Indent);
out << "identity: " << identity << std::endl;
printIndent(out, int_Indent);
out << "nickname: " << nickname << std::endl;
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognTagItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeTag(RsGxsRecognTagItem *item)
{
uint32_t s = 8; /* header */
s += 4; // valid_from;
s += 4; // valid_to;
s += 2; // tag_class;
s += 2; // tag_type;
s += GetTlvStringSize(item->identity);
s += GetTlvStringSize(item->nickname);
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseTag(RsGxsRecognTagItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeTag(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->valid_from);
ok &= setRawUInt32(data, tlvsize, &offset, item->valid_to);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_class);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_type);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognTagItem *RsGxsRecognSerialiser::deserialiseTag(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_TAG != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognTagItem *item = new RsGxsRecognTagItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= getRawUInt32(data, tlvsize, &offset, &(item->valid_from));
ok &= getRawUInt32(data, tlvsize, &offset, &(item->valid_to));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_class));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_type));
ok &= GetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
RsGxsRecognSignerItem::~RsGxsRecognSignerItem()
{
return;
}
void RsGxsRecognSignerItem::clear()
{
signing_classes.TlvClear();
key.TlvClear();
sign.TlvClear();
}
std::ostream &RsGxsRecognSignerItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognSignerItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "signing_classes: " << std::endl;
signing_classes.print(out, int_Indent + 2);
printIndent(out, int_Indent);
out << "key: " << std::endl;
key.print(out, int_Indent + 2);
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognSignerItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeSigner(RsGxsRecognSignerItem *item)
{
uint32_t s = 8; /* header */
s += item->signing_classes.TlvSize();
s += item->key.TlvSize();
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseSigner(RsGxsRecognSignerItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeSigner(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= item->signing_classes.SetTlv(data, tlvsize, &offset);
ok &= item->key.SetTlv(data, tlvsize, &offset);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognSignerItem *RsGxsRecognSerialiser::deserialiseSigner(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_SIGNER != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognSignerItem *item = new RsGxsRecognSignerItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= item->signing_classes.GetTlv(data, tlvsize, &offset);
ok &= item->key.GetTlv(data, tlvsize, &offset);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
uint32_t RsGxsRecognSerialiser::size(RsItem *i)
{
RsGxsRecognReqItem *rqi;
RsGxsRecognTagItem *rti;
RsGxsRecognSignerItem *rsi;
if (NULL != (rqi = dynamic_cast<RsGxsRecognReqItem *>(i)))
{
return sizeReq(rqi);
}
if (NULL != (rti = dynamic_cast<RsGxsRecognTagItem *>(i)))
{
return sizeTag(rti);
}
if (NULL != (rsi = dynamic_cast<RsGxsRecognSignerItem *>(i)))
{
return sizeSigner(rsi);
}
return 0;
}
bool RsGxsRecognSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
RsGxsRecognReqItem *rri;
RsGxsRecognTagItem *rti;
RsGxsRecognSignerItem *rsi;
if (NULL != (rri = dynamic_cast<RsGxsRecognReqItem *>(i)))
{
return serialiseReq(rri, data, pktsize);
}
if (NULL != (rti = dynamic_cast<RsGxsRecognTagItem *>(i)))
{
return serialiseTag(rti, data, pktsize);
}
if (NULL != (rsi = dynamic_cast<RsGxsRecognSignerItem *>(i)))
{
return serialiseSigner(rsi, data, pktsize);
}
return false;
}
RsItem *RsGxsRecognSerialiser::deserialise(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_RECOGN_REQ:
return deserialiseReq(data, pktsize);
break;
case RS_PKT_SUBTYPE_RECOGN_TAG:
return deserialiseTag(data, pktsize);
break;
case RS_PKT_SUBTYPE_RECOGN_SIGNER:
return deserialiseSigner(data, pktsize);
break;
default:
return NULL;
break;
}
}
/*************************************************************************/

View file

@ -0,0 +1,152 @@
#ifndef RS_GXS_RECOG_ITEMS_H
#define RS_GXS_RECOG_ITEMS_H
/*
* libretroshare/src/serialiser: rsgxsrecogitems.h
*
* RetroShare Serialiser.
*
* Copyright 2013-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <map>
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rstlvkeys.h"
/**************************************************************************/
#define RS_PKT_SUBTYPE_RECOGN_REQ 0x01
#define RS_PKT_SUBTYPE_RECOGN_TAG 0x02
#define RS_PKT_SUBTYPE_RECOGN_SIGNER 0x03
class RsGxsRecognReqItem: public RsItem
{
public:
RsGxsRecognReqItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_REQ)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognReqItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t issued_at;
uint32_t period;
uint16_t tag_class;
uint16_t tag_type;
std::string identity;
std::string nickname;
std::string comment;
RsTlvKeySignature sign;
};
class RsGxsRecognTagItem: public RsItem
{
public:
RsGxsRecognTagItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_TAG)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognTagItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t valid_from;
uint32_t valid_to;
uint16_t tag_class;
uint16_t tag_type;
std::string identity;
std::string nickname;
RsTlvKeySignature sign;
};
class RsGxsRecognSignerItem: public RsItem
{
public:
RsGxsRecognSignerItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_SIGNER)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognSignerItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvServiceIdSet signing_classes;
RsTlvSecurityKey key; // has from->to, and flags.
RsTlvKeySignature sign;
};
class RsGxsRecognSerialiser: public RsSerialType
{
public:
RsGxsRecognSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN)
{ return; }
virtual ~RsGxsRecognSerialiser()
{ return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
virtual uint32_t sizeReq(RsGxsRecognReqItem *);
virtual bool serialiseReq(RsGxsRecognReqItem *item, void *data, uint32_t *size);
virtual RsGxsRecognReqItem *deserialiseReq(void *data, uint32_t *size);
virtual uint32_t sizeTag(RsGxsRecognTagItem *);
virtual bool serialiseTag(RsGxsRecognTagItem *item, void *data, uint32_t *size);
virtual RsGxsRecognTagItem *deserialiseTag(void *data, uint32_t *size);
virtual uint32_t sizeSigner(RsGxsRecognSignerItem *);
virtual bool serialiseSigner(RsGxsRecognSignerItem *item, void *data, uint32_t *size);
virtual RsGxsRecognSignerItem *deserialiseSigner(void *data, uint32_t *size);
};
/**************************************************************************/
#endif /* RS_GXS_RECOGN_ITEMS_H */

View file

@ -0,0 +1,704 @@
/*
* libretroshare/src/serialiser: rsgxsupdateitems.h
*
* RetroShare Serialiser.
*
* Copyright 2012 Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "rsgxsupdateitems.h"
#include "rsbaseserial.h"
void RsGxsGrpUpdateItem::clear()
{
grpUpdateTS = 0;
peerId.clear();
}
std::ostream& RsGxsGrpUpdateItem::print(std::ostream& out, uint16_t indent)
{
}
void RsGxsMsgUpdateItem::clear()
{
msgUpdateTS.clear();
peerId.clear();
}
std::ostream& RsGxsMsgUpdateItem::print(std::ostream& out, uint16_t indent)
{
}
void RsGxsServerMsgUpdateItem::clear()
{
msgUpdateTS = 0;
grpId.clear();
}
std::ostream& RsGxsServerMsgUpdateItem::print(std::ostream& out, uint16_t indent)
{
}
void RsGxsServerGrpUpdateItem::clear()
{
grpUpdateTS = 0;
}
std::ostream& RsGxsServerGrpUpdateItem::print(std::ostream& out, uint16_t indent)
{
}
uint32_t RsGxsUpdateSerialiser::size(RsItem* item)
{
RsGxsMsgUpdateItem* mui = NULL;
RsGxsGrpUpdateItem* gui = NULL;
RsGxsServerGrpUpdateItem* gsui = NULL;
RsGxsServerMsgUpdateItem* msui = NULL;
if((mui = dynamic_cast<RsGxsMsgUpdateItem*>(item)) != NULL)
{
return sizeGxsMsgUpdate(mui);
}else if(( gui = dynamic_cast<RsGxsGrpUpdateItem*>(item)) != NULL){
return sizeGxsGrpUpdate(gui);
}else if((gsui = dynamic_cast<RsGxsServerGrpUpdateItem*>(item)) != NULL)
{
return sizeGxsServerGrpUpdate(gsui);
}else if((msui = dynamic_cast<RsGxsServerMsgUpdateItem*>(item)) != NULL)
{
return sizeGxsServerMsgUpdate(msui);
}else
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::size(): Could not find appropriate size function"
<< std::endl;
#endif
return 0;
}
}
bool RsGxsUpdateSerialiser::serialise(RsItem* item, void* data,
uint32_t* size)
{
RsGxsMsgUpdateItem* mui;
RsGxsGrpUpdateItem* gui;
RsGxsServerGrpUpdateItem* gsui;
RsGxsServerMsgUpdateItem* msui;
if((mui = dynamic_cast<RsGxsMsgUpdateItem*>(item)) != NULL)
return serialiseGxsMsgUpdate(mui, data, size);
else if((gui = dynamic_cast<RsGxsGrpUpdateItem*>(item)) != NULL)
return serialiseGxsGrpUpdate(gui, data, size);
else if((msui = dynamic_cast<RsGxsServerMsgUpdateItem*>(item)) != NULL)
return serialiseGxsServerMsgUpdate(msui, data, size);
else if((gsui = dynamic_cast<RsGxsServerGrpUpdateItem*>(item)) != NULL)
return serialiseGxsServerGrpUpdate(gsui, data, size);
else
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialise() item does not caste to known type"
<< std::endl;
#endif
return false;
}
}
RsItem* RsGxsUpdateSerialiser::deserialise(void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialise()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_GXS_MSG_UPDATE:
return deserialGxsMsgUpdate(data, size);
case RS_PKT_SUBTYPE_GXS_GRP_UPDATE:
return deserialGxsGrpUpddate(data, size);
case RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE:
return deserialGxsServerGrpUpddate(data, size);
case RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE:
return deserialGxsServerMsgUpdate(data, size);
default:
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialise() : data has no type"
<< std::endl;
#endif
return NULL;
}
}
}
uint32_t RsGxsUpdateSerialiser::sizeGxsGrpUpdate(RsGxsGrpUpdateItem* item)
{
uint32_t s = 8; // header size
s += GetTlvStringSize(item->peerId);
s += 4;
return s;
}
uint32_t RsGxsUpdateSerialiser::sizeGxsServerGrpUpdate(RsGxsServerGrpUpdateItem* item)
{
uint32_t s = 8; // header size
s += 4; // time stamp
return s;
}
bool RsGxsUpdateSerialiser::serialiseGxsGrpUpdate(RsGxsGrpUpdateItem* item,
void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsGrpUpdate()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsGrpUpdate(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsGrpUpdate() size do not match" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsGxsGrpUpdateItem */
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_PEERID, item->peerId);
ok &= setRawUInt32(data, *size, &offset, item->grpUpdateTS);
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsGrpUpdate() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsGrpUpdate() NOK" << std::endl;
}
#endif
return ok;
}
bool RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate(RsGxsServerGrpUpdateItem* item,
void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsServerGrpUpdate(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate() size do not match" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsGxsServerGrpUpdateItem */
ok &= setRawUInt32(data, *size, &offset, item->grpUpdateTS);
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate() NOK" << std::endl;
}
#endif
return ok;
}
RsGxsGrpUpdateItem* RsGxsUpdateSerialiser::deserialGxsGrpUpddate(void* data,
uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXS_GRP_UPDATE != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsGrpUpdate() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsGrpUpdate() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsGrpUpdateItem* item = new RsGxsGrpUpdateItem(getRsItemService(rstype));
/* skip the header */
offset += 8;
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_PEERID, item->peerId);
ok &= getRawUInt32(data, *size, &offset, &(item->grpUpdateTS));
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxxGrpUpdate() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsGrpUpdate() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
RsGxsServerGrpUpdateItem* RsGxsUpdateSerialiser::deserialGxsServerGrpUpddate(void* data,
uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsServerGrpUpdateItem* item = new RsGxsServerGrpUpdateItem(getRsItemService(rstype));
/* skip the header */
offset += 8;
ok &= getRawUInt32(data, *size, &offset, &(item->grpUpdateTS));
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
uint32_t RsGxsUpdateSerialiser::sizeGxsMsgUpdate(RsGxsMsgUpdateItem* item)
{
uint32_t s = 8; // header size
s += GetTlvStringSize(item->peerId);
const std::map<std::string, uint32_t>& msgUpdateTS = item->msgUpdateTS;
std::map<std::string, uint32_t>::const_iterator cit = msgUpdateTS.begin();
for(; cit != msgUpdateTS.end(); cit++)
{
s += GetTlvStringSize(cit->first);
s += 4;
}
s += 4; // number of map items
return s;
}
uint32_t RsGxsUpdateSerialiser::sizeGxsServerMsgUpdate(RsGxsServerMsgUpdateItem* item)
{
uint32_t s = 8; // header size
s += GetTlvStringSize(item->grpId);
s += 4; // grp TS
return s;
}
bool RsGxsUpdateSerialiser::serialiseGxsMsgUpdate(RsGxsMsgUpdateItem* item,
void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsMsgUpdate()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsMsgUpdate(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsMsgUpdate() size do not match" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsGxsMsgUpdateItem */
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_PEERID, item->peerId);
const std::map<std::string, uint32_t>& msgUpdateTS = item->msgUpdateTS;
std::map<std::string, uint32_t>::const_iterator cit = msgUpdateTS.begin();
uint32_t numItems = msgUpdateTS.size();
ok &= setRawUInt32(data, *size, &offset, numItems);
for(; cit != msgUpdateTS.end(); cit++)
{
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, cit->first);
ok &= setRawUInt32(data, *size, &offset, cit->second);
}
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsMsgUpdate() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsMsgUpdate() NOK" << std::endl;
}
#endif
return ok;
}
bool RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate(RsGxsServerMsgUpdateItem* item,
void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsServerMsgUpdate(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate() size do not match" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsNxsSyncm */
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= setRawUInt32(data, *size, &offset, item->msgUpdateTS);
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate() NOK" << std::endl;
}
#endif
return ok;
}
RsGxsMsgUpdateItem* RsGxsUpdateSerialiser::deserialGxsMsgUpdate(void* data,
uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXS_MSG_UPDATE != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsMsgUpdateItem* item = new RsGxsMsgUpdateItem(getRsItemService(rstype));
/* skip the header */
offset += 8;
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_PEERID, item->peerId);
uint32_t numUpdateItems;
ok &= getRawUInt32(data, *size, &offset, &(numUpdateItems));
std::map<std::string, uint32_t>& msgUpdateItem = item->msgUpdateTS;
std::string grpId;
uint32_t updateTS;
for(uint32_t i = 0; i < numUpdateItems; i++)
{
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, grpId);
if(!ok)
break;
ok &= getRawUInt32(data, *size, &offset, &(updateTS));
if(!ok)
break;
msgUpdateItem.insert(std::make_pair(grpId, updateTS));
}
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
RsGxsServerMsgUpdateItem* RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate(void* data,
uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsServerMsgUpdateItem* item = new RsGxsServerMsgUpdateItem(getRsItemService(rstype));
/* skip the header */
offset += 8;
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= getRawUInt32(data, *size, &offset, &(item->msgUpdateTS));
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}

View file

@ -0,0 +1,149 @@
#ifndef RSGXSUPDATEITEMS_H_
#define RSGXSUPDATEITEMS_H_
/*
* libretroshare/src/serialiser: rsgxsupdateitems.h
*
* RetroShare Serialiser.
*
* Copyright 2012 Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <map>
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rstlvkeys.h"
#include "gxs/rsgxsdata.h"
const uint8_t RS_PKT_SUBTYPE_GXS_GRP_UPDATE = 0x0001;
const uint8_t RS_PKT_SUBTYPE_GXS_MSG_UPDATE = 0x0002;
const uint8_t RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE = 0x0004;
const uint8_t RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE = 0x0008;
class RsGxsGrpUpdateItem : public RsItem {
public:
RsGxsGrpUpdateItem(uint16_t servType) : RsItem(RS_PKT_VERSION_SERVICE, servType,
RS_PKT_SUBTYPE_GXS_GRP_UPDATE)
{clear();}
virtual ~RsGxsGrpUpdateItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::string peerId;
uint32_t grpUpdateTS;
};
class RsGxsServerGrpUpdateItem : public RsItem {
public:
RsGxsServerGrpUpdateItem(uint16_t servType) : RsItem(RS_PKT_VERSION_SERVICE, servType,
RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE)
{ clear();}
virtual ~RsGxsServerGrpUpdateItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint32_t grpUpdateTS;
};
class RsGxsMsgUpdateItem : public RsItem
{
public:
RsGxsMsgUpdateItem(uint16_t servType) : RsItem(RS_PKT_VERSION_SERVICE, servType, RS_PKT_SUBTYPE_GXS_MSG_UPDATE)
{ clear();}
virtual ~RsGxsMsgUpdateItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::string peerId;
std::map<std::string, uint32_t> msgUpdateTS;
};
class RsGxsServerMsgUpdateItem : public RsItem
{
public:
RsGxsServerMsgUpdateItem(uint16_t servType) : RsItem(RS_PKT_VERSION_SERVICE,
servType, RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE)
{ clear();}
virtual ~RsGxsServerMsgUpdateItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::string grpId;
uint32_t msgUpdateTS; // the last time this group received a new msg
};
class RsGxsUpdateSerialiser : public RsSerialType
{
public:
RsGxsUpdateSerialiser(uint16_t servtype) :
RsSerialType(RS_PKT_VERSION_SERVICE, servtype), SERVICE_TYPE(servtype) { return; }
virtual ~RsGxsUpdateSerialiser() { return; }
virtual uint32_t size(RsItem *item);
virtual bool serialise(RsItem *item, void *data, uint32_t *size);
virtual RsItem* deserialise(void *data, uint32_t *size);
private:
/* for RS_PKT_SUBTYPE_GRP_UPDATE_ITEM */
virtual uint32_t sizeGxsGrpUpdate(RsGxsGrpUpdateItem* item);
virtual bool serialiseGxsGrpUpdate(RsGxsGrpUpdateItem *item, void *data, uint32_t *size);
virtual RsGxsGrpUpdateItem* deserialGxsGrpUpddate(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_GRP_SERVER_UPDATE_ITEM */
virtual uint32_t sizeGxsServerGrpUpdate(RsGxsServerGrpUpdateItem* item);
virtual bool serialiseGxsServerGrpUpdate(RsGxsServerGrpUpdateItem *item, void *data, uint32_t *size);
virtual RsGxsServerGrpUpdateItem* deserialGxsServerGrpUpddate(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_GXS_MSG_UPDATE_ITEM */
virtual uint32_t sizeGxsMsgUpdate(RsGxsMsgUpdateItem* item);
virtual bool serialiseGxsMsgUpdate(RsGxsMsgUpdateItem *item, void *data, uint32_t *size);
virtual RsGxsMsgUpdateItem* deserialGxsMsgUpdate(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_GXS_SERVER_UPDATE_ITEM */
virtual uint32_t sizeGxsServerMsgUpdate(RsGxsServerMsgUpdateItem* item);
virtual bool serialiseGxsServerMsgUpdate(RsGxsServerMsgUpdateItem *item, void *data, uint32_t *size);
virtual RsGxsServerMsgUpdateItem* deserialGxsServerMsgUpdate(void *data, uint32_t *size);
private:
const uint16_t SERVICE_TYPE;
};
#endif /* RSGXSUPDATEITEMS_H_ */

View file

@ -354,8 +354,9 @@ bool RsNxsSerialiser::serialiseNxsSyncGrp(RsNxsSyncGrp *item, void *data, uint32
ok &= setRawUInt32(data, *size, &offset, item->transactionNumber); ok &= setRawUInt32(data, *size, &offset, item->transactionNumber);
ok &= setRawUInt8(data, *size, &offset, item->flag); ok &= setRawUInt8(data, *size, &offset, item->flag);
ok &= setRawUInt32(data, *size, &offset, item->syncAge); ok &= setRawUInt32(data, *size, &offset, item->createdSince);
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash); ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash);
ok &= setRawUInt32(data, *size, &offset, item->updateTS);
if(offset != tlvsize){ if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG #ifdef RSSERIAL_DEBUG
@ -403,7 +404,7 @@ bool RsNxsSerialiser::serialiseNxsTrans(RsNxsTransac *item, void *data, uint32_t
ok &= setRawUInt32(data, *size, &offset, item->transactionNumber); ok &= setRawUInt32(data, *size, &offset, item->transactionNumber);
ok &= setRawUInt16(data, *size, &offset, item->transactFlag); ok &= setRawUInt16(data, *size, &offset, item->transactFlag);
ok &= setRawUInt32(data, *size, &offset, item->nItems); ok &= setRawUInt32(data, *size, &offset, item->nItems);
ok &= setRawUInt32(data, *size, &offset, item->timestamp); ok &= setRawUInt32(data, *size, &offset, item->updateTS);
@ -501,9 +502,10 @@ bool RsNxsSerialiser::serialiseNxsSyncMsg(RsNxsSyncMsg *item, void *data, uint32
ok &= setRawUInt32(data, *size, &offset, item->transactionNumber); ok &= setRawUInt32(data, *size, &offset, item->transactionNumber);
ok &= setRawUInt8(data, *size, &offset, item->flag); ok &= setRawUInt8(data, *size, &offset, item->flag);
ok &= setRawUInt32(data, *size, &offset, item->syncAge); ok &= setRawUInt32(data, *size, &offset, item->createdSince);
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash); ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash);
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId); ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= setRawUInt32(data, *size, &offset, item->updateTS);
if(offset != tlvsize){ if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG #ifdef RSSERIAL_DEBUG
@ -710,8 +712,9 @@ RsNxsSyncGrp* RsNxsSerialiser::deserialNxsSyncGrp(void *data, uint32_t *size){
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber)); ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
ok &= getRawUInt8(data, *size, &offset, &(item->flag)); ok &= getRawUInt8(data, *size, &offset, &(item->flag));
ok &= getRawUInt32(data, *size, &offset, &(item->syncAge)); ok &= getRawUInt32(data, *size, &offset, &(item->createdSince));
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash); ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash);
ok &= getRawUInt32(data, *size, &offset, &(item->updateTS));
if (offset != rssize) if (offset != rssize)
{ {
@ -846,7 +849,7 @@ RsNxsTransac* RsNxsSerialiser::deserialNxsTrans(void *data, uint32_t *size){
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber)); ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
ok &= getRawUInt16(data, *size, &offset, &(item->transactFlag)); ok &= getRawUInt16(data, *size, &offset, &(item->transactFlag));
ok &= getRawUInt32(data, *size, &offset, &(item->nItems)); ok &= getRawUInt32(data, *size, &offset, &(item->nItems));
ok &= getRawUInt32(data, *size, &offset, &(item->timestamp)); ok &= getRawUInt32(data, *size, &offset, &(item->updateTS));
if (offset != rssize) if (offset != rssize)
{ {
@ -984,9 +987,10 @@ RsNxsSyncMsg* RsNxsSerialiser::deserialNxsSyncMsg(void *data, uint32_t *size)
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber)); ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
ok &= getRawUInt8(data, *size, &offset, &(item->flag)); ok &= getRawUInt8(data, *size, &offset, &(item->flag));
ok &= getRawUInt32(data, *size, &offset, &(item->syncAge)); ok &= getRawUInt32(data, *size, &offset, &(item->createdSince));
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash); ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash);
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId); ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= getRawUInt32(data, *size, &offset, &(item->updateTS));
if (offset != rssize) if (offset != rssize)
{ {
@ -1057,6 +1061,7 @@ uint32_t RsNxsSerialiser::sizeNxsSyncGrp(RsNxsSyncGrp *item)
s += 1; // flag s += 1; // flag
s += 4; // sync age s += 4; // sync age
s += GetTlvStringSize(item->syncHash); s += GetTlvStringSize(item->syncHash);
s += 4; // updateTS
return s; return s;
} }
@ -1086,6 +1091,7 @@ uint32_t RsNxsSerialiser::sizeNxsSyncMsg(RsNxsSyncMsg *item)
s += 4; // age s += 4; // age
s += GetTlvStringSize(item->grpId); s += GetTlvStringSize(item->grpId);
s += GetTlvStringSize(item->syncHash); s += GetTlvStringSize(item->syncHash);
s += 4; // updateTS
return s; return s;
} }
@ -1111,7 +1117,7 @@ uint32_t RsNxsSerialiser::sizeNxsTrans(RsNxsTransac *item){
s += 4; // transaction number s += 4; // transaction number
s += 2; // flag s += 2; // flag
s += 4; // nMsgs s += 4; // nMsgs
s += 4; // timeout s += 4; // updateTS
return s; return s;
} }
@ -1141,16 +1147,18 @@ void RsNxsGrp::clear()
void RsNxsSyncGrp::clear() void RsNxsSyncGrp::clear()
{ {
flag = 0; flag = 0;
syncAge = 0; createdSince = 0;
syncHash.clear(); syncHash.clear();
updateTS = 0;
} }
void RsNxsSyncMsg::clear() void RsNxsSyncMsg::clear()
{ {
grpId.clear(); grpId.clear();
flag = 0; flag = 0;
syncAge = 0; createdSince = 0;
syncHash.clear(); syncHash.clear();
updateTS = 0;
} }
void RsNxsSyncGrpItem::clear() void RsNxsSyncGrpItem::clear()
@ -1172,6 +1180,7 @@ void RsNxsSyncMsgItem::clear()
void RsNxsTransac::clear(){ void RsNxsTransac::clear(){
transactFlag = 0; transactFlag = 0;
nItems = 0; nItems = 0;
updateTS = 0;
timestamp = 0; timestamp = 0;
transactionNumber = 0; transactionNumber = 0;
} }
@ -1185,10 +1194,11 @@ std::ostream& RsNxsSyncGrp::print(std::ostream &out, uint16_t indent)
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "Hash: " << syncHash << std::endl; out << "Hash: " << syncHash << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "Sync Age: " << syncAge << std::endl; out << "Sync Age: " << createdSince << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "flag" << flag << std::endl; out << "flag" << flag << std::endl;
printIndent(out , int_Indent);
out << "updateTS" << updateTS << std::endl;
printRsItemEnd(out ,"RsNxsSyncGrp", indent); printRsItemEnd(out ,"RsNxsSyncGrp", indent);
@ -1217,11 +1227,13 @@ std::ostream& RsNxsSyncMsg::print(std::ostream &out, uint16_t indent)
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "GrpId: " << grpId << std::endl; out << "GrpId: " << grpId << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "syncAge: " << syncAge << std::endl; out << "createdSince: " << createdSince << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "syncHash: " << syncHash << std::endl; out << "syncHash: " << syncHash << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "flag: " << flag << std::endl; out << "flag: " << flag << std::endl;
printIndent(out , int_Indent);
out << "updateTS: " << updateTS << std::endl;
printRsItemEnd(out, "RsNxsSyncMsg", indent); printRsItemEnd(out, "RsNxsSyncMsg", indent);
return out; return out;
@ -1316,6 +1328,8 @@ std::ostream& RsNxsTransac::print(std::ostream &out, uint16_t indent){
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "timeout: " << timestamp << std::endl; out << "timeout: " << timestamp << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);
out << "updateTS: " << updateTS << std::endl;
printIndent(out , int_Indent);
out << "transactionNumber: " << transactionNumber << std::endl; out << "transactionNumber: " << transactionNumber << std::endl;
printIndent(out , int_Indent); printIndent(out , int_Indent);

View file

@ -100,7 +100,8 @@ public:
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint8_t flag; // advises whether to use sync hash uint8_t flag; // advises whether to use sync hash
uint32_t syncAge; // how far back to sync data uint32_t createdSince; // how far back to sync data
uint32_t updateTS; // time of last group update
std::string syncHash; // use to determine if changes that have occured since last hash std::string syncHash; // use to determine if changes that have occured since last hash
@ -146,6 +147,9 @@ public:
uint16_t transactFlag; uint16_t transactFlag;
uint32_t nItems; uint32_t nItems;
uint32_t updateTS;
// not serialised
uint32_t timestamp; uint32_t timestamp;
}; };
@ -235,7 +239,8 @@ public:
std::string grpId; std::string grpId;
uint8_t flag; uint8_t flag;
uint32_t syncAge; uint32_t createdSince;
uint32_t updateTS; // time of last update
std::string syncHash; std::string syncHash;
}; };

View file

@ -154,6 +154,8 @@ const uint16_t RS_SERVICE_GXSV3_TYPE_POSTED = 0xf326;
const uint16_t RS_SERVICE_GXSV3_TYPE_CHANNELS = 0xf327; const uint16_t RS_SERVICE_GXSV3_TYPE_CHANNELS = 0xf327;
const uint16_t RS_SERVICE_GXSV3_TYPE_GXSCIRCLE = 0xf328; const uint16_t RS_SERVICE_GXSV3_TYPE_GXSCIRCLE = 0xf328;
const uint16_t RS_SERVICE_TYPE_GXS_RECOGN = 0xf331;
/***************** IDS ALLOCATED FOR PLUGINS ******************/ /***************** IDS ALLOCATED FOR PLUGINS ******************/
const uint16_t RS_SERVICE_TYPE_PLUGIN_ARADO_TEST_ID1 = 0xf401; const uint16_t RS_SERVICE_TYPE_PLUGIN_ARADO_TEST_ID1 = 0xf401;

View file

@ -429,6 +429,165 @@ std::ostream &RsTlvStringSet::printHex(std::ostream &out, uint16_t indent)
} }
/************************************* String Set Ref ************************************/
/* This is exactly the same as StringSet, but it uses an alternative list.
*/
RsTlvStringSetRef::RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids)
:mType(type), ids(refids)
{
}
void RsTlvStringSetRef::TlvClear()
{
ids.clear();
}
uint32_t RsTlvStringSetRef::TlvSize()
{
uint32_t s = TLV_HEADER_SIZE; /* header */
/* determine the total size of ids strings in list */
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
if (it->length() > 0)
s += GetTlvStringSize(*it);
}
return s;
}
bool RsTlvStringSetRef::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
return false; /* not enough space */
bool ok = true;
/* start at data[offset] */
ok &= SetTlvBase(data, tlvend, offset, mType , tlvsize);
/* determine the total size of ids strings in list */
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
if (it->length() > 0)
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, *it);
}
return ok;
}
bool RsTlvStringSetRef::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
return false; /* not enough space */
if (tlvtype != mType) /* check type */
return false;
bool ok = true;
/* ready to load */
TlvClear();
/* skip the header */
(*offset) += TLV_HEADER_SIZE;
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
if (tlvsubtype == TLV_TYPE_STR_GENID)
{
std::string newIds;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, newIds);
if(ok)
{
ids.push_back(newIds);
}
}
else
{
/* Step past unknown TLV TYPE */
ok &= SkipUnknownTlv(data, tlvend, offset);
}
if (!ok)
{
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvPeerIdSetRef::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
/// print to screen RsTlvStringSet contents
std::ostream &RsTlvStringSetRef::print(std::ostream &out, uint16_t indent)
{
printBase(out, "RsTlvStringSetRef", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "type:" << mType;
out << std::endl;
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
printIndent(out, int_Indent);
out << "id:" << *it;
out << std::endl;
}
printEnd(out, "RsTlvStringSetRef", indent);
return out;
}
/************************************* Service Id Set ************************************/ /************************************* Service Id Set ************************************/
void RsTlvServiceIdSet::TlvClear() void RsTlvServiceIdSet::TlvClear()

View file

@ -145,6 +145,22 @@ virtual std::ostream &print(std::ostream &out, uint16_t indent);
}; };
class RsTlvStringSetRef: public RsTlvItem
{
public:
RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids);
virtual ~RsTlvStringSetRef() { return; }
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint16_t mType;
std::list<std::string> &ids; /* Mandatory */
};
/**** MORE TLV ***** /**** MORE TLV *****
* *
* File Items/Data. * File Items/Data.

View file

@ -215,6 +215,21 @@ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
return true; return true;
} }
bool p3GxsForums::updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group)
{
std::cerr << "p3GxsForums::updateGroup()" << std::endl;
if(meta.getGroupId().empty())
return false;
RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem();
grpItem->mGroup = group;
grpItem->meta = group.mMeta;
grpItem->meta.mGroupId = meta.getGroupId();
RsGenExchange::updateGroup(token, meta, grpItem);
return true;
}
bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg) bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg)
{ {

View file

@ -74,6 +74,13 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group); virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group);
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg); virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg);
/*!
* To update forum group with new information
* @param token the token used to check completion status of update
* @param group group to be updated, groupId element must be set or will be rejected
* @return false groupId not set, true if set and accepted (still check token for completion)
*/
virtual bool updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group);
private: private:

File diff suppressed because it is too large Load diff

View file

@ -38,9 +38,12 @@
#include "util/rsmemcache.h" #include "util/rsmemcache.h"
#include "util/rstickevent.h" #include "util/rstickevent.h"
#include "util/rsrecogn.h"
#include "pqi/authgpg.h" #include "pqi/authgpg.h"
#include "serialiser/rsgxsrecognitems.h"
/* /*
* Identity Service * Identity Service
* *
@ -73,6 +76,27 @@ virtual std::string save() const;
std::string pgpId; std::string pgpId;
}; };
class SSGxsIdRecognTags: public SSBit
{
public:
SSGxsIdRecognTags()
:tagFlags(0), publishTs(0), lastCheckTs(0) { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
void setTags(bool processed, bool pending, uint32_t flags);
bool tagsProcessed() const; // have we processed?
bool tagsPending() const; // should we reprocess?
bool tagValid(int i) const;
time_t publishTs;
time_t lastCheckTs;
uint32_t tagFlags;
};
class SSGxsIdScore: public SSBit class SSGxsIdScore: public SSBit
{ {
public: public:
@ -113,6 +137,9 @@ virtual std::string save() const;
// pgphash status // pgphash status
SSGxsIdPgp pgp; SSGxsIdPgp pgp;
// recogTags.
SSGxsIdRecognTags recogntags;
// reputation score. // reputation score.
SSGxsIdScore score; SSGxsIdScore score;
SSGxsIdCumulator opinion; SSGxsIdCumulator opinion;
@ -133,10 +160,14 @@ class RsGxsIdCache
{ {
public: public:
RsGxsIdCache(); RsGxsIdCache();
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey); RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey,
const std::list<RsRecognTag> &tagList);
void updateServiceString(std::string serviceString); void updateServiceString(std::string serviceString);
time_t mPublishTs;
std::list<RsRecognTag> mRecognTags; // Only partially validated.
RsIdentityDetails details; RsIdentityDetails details;
RsTlvSecurityKey pubkey; RsTlvSecurityKey pubkey;
}; };
@ -165,6 +196,12 @@ static uint32_t idAuthenPolicy();
virtual void service_tick(); // needed for background processing. virtual void service_tick(); // needed for background processing.
/*!
* Design hack, id service must be constructed first as it
* is need for construction of subsequent net services
*/
void setNes(RsNetworkExchangeService* nes);
/* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */ /* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */
/* Data Specific Interface */ /* Data Specific Interface */
@ -175,6 +212,7 @@ virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opin
// These are local - and not exposed via RsIdentity. // These are local - and not exposed via RsIdentity.
virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group); virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool updateGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion); virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion);
/**************** RsIdentity External Interface. /**************** RsIdentity External Interface.
@ -197,6 +235,13 @@ virtual bool getOwnIds(std::list<RsGxsId> &ownIds);
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion); virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion);
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params); virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params);
virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group);
virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
const std::string &tag, RsRecognTagDetails &details);
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag);
/**************** RsGixs Implementation /**************** RsGixs Implementation
* Notes: * Notes:
@ -219,7 +264,7 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
// get Reputation. // get Reputation.
virtual bool haveReputation(const RsGxsId &id); virtual bool haveReputation(const RsGxsId &id);
virtual bool loadReputation(const RsGxsId &id); virtual bool loadReputation(const RsGxsId &id, const std::list<std::string>& peers);
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep); virtual bool getReputation(const RsGxsId &id, GixsReputation &rep);
@ -245,16 +290,20 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
*/ */
int cache_tick(); int cache_tick();
bool cache_request_load(const RsGxsId &id); bool cache_request_load(const RsGxsId &id, const std::list<std::string>& peers = std::list<std::string>());
bool cache_start_load(); bool cache_start_load();
bool cache_load_for_token(uint32_t token); bool cache_load_for_token(uint32_t token);
bool cache_store(const RsGxsIdGroupItem *item); bool cache_store(const RsGxsIdGroupItem *item);
bool cache_update_if_cached(const RsGxsId &id, std::string serviceString); bool cache_update_if_cached(const RsGxsId &id, std::string serviceString);
bool isPendingNetworkRequest(const RsGxsId& gxsId) const;
void requestIdsFromNet();
// Mutex protected. // Mutex protected.
std::list<RsGxsId> mCacheLoad_ToCache; //std::list<RsGxsId> mCacheLoad_ToCache;
std::map<RsGxsId, std::list<std::string> > mCacheLoad_ToCache, mPendingCache;
// Switching to RsMemCache for Key Caching. // Switching to RsMemCache for Key Caching.
RsMemCache<RsGxsId, RsGxsIdCache> mPublicKeyCache; RsMemCache<RsGxsId, RsGxsIdCache> mPublicKeyCache;
@ -303,6 +352,39 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
std::map<PGPIdType, PGPFingerprintType> mPgpFingerprintMap; std::map<PGPIdType, PGPFingerprintType> mPgpFingerprintMap;
std::list<RsGxsIdGroup> mGroupsToProcess; std::list<RsGxsIdGroup> mGroupsToProcess;
/************************************************************************
* recogn processing.
*
*/
bool recogn_schedule();
bool recogn_start();
bool recogn_handlerequest(uint32_t token);
bool recogn_process();
// helper functions.
bool recogn_extract_taginfo(const RsGxsIdGroupItem *item, std::list<RsGxsRecognTagItem *> &tagItems);
bool cache_process_recogntaginfo(const RsGxsIdGroupItem *item, std::list<RsRecognTag> &tagList);
bool recogn_checktag(const RsGxsId &id, const std::string &nickname, RsGxsRecognTagItem *item, bool doSignCheck, bool &isPending);
void loadRecognKeys();
/************************************************************************
* for getting identities that are not present
*
*/
void checkPeerForIdentities();
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
bool checkRecognSignature_locked(std::string encoded, RSA &key, std::string signature);
bool getRecognKey_locked(std::string signer, RSA &key);
std::list<RsGxsGroupId> mRecognGroupIds;
std::list<RsGxsIdGroupItem *> mRecognGroupsToProcess;
std::map<std::string, RsGxsRecognSignerItem *> mRecognSignKeys;
std::map<std::string, uint32_t> mRecognOldSignKeys;
/************************************************************************ /************************************************************************
* Below is the background task for processing opinions => reputations * Below is the background task for processing opinions => reputations
* *
@ -348,6 +430,12 @@ std::string genRandomId(int len = 20);
std::vector<RsGxsGroupChange*> mGroupChange; std::vector<RsGxsGroupChange*> mGroupChange;
std::vector<RsGxsMsgChange*> mMsgChange; std::vector<RsGxsMsgChange*> mMsgChange;
private:
std::map<uint32_t, std::set<RsGxsGroupId> > mIdsPendingCache;
std::map<uint32_t, std::list<RsGxsGroupId> > mGroupNotPresent;
std::map<RsGxsId, std::list<std::string> > mIdsNotPresent;
RsNetworkExchangeService* mNes;
}; };
#endif // P3_IDENTITY_SERVICE_HEADER #endif // P3_IDENTITY_SERVICE_HEADER

View file

@ -40,7 +40,6 @@
/**** /****
* #define POSTED_DEBUG 1 * #define POSTED_DEBUG 1
****/ ****/
#define POSTED_DEBUG 1
RsPosted *rsPosted = NULL; RsPosted *rsPosted = NULL;

View file

@ -56,7 +56,9 @@ linux-* {
LIBS += ../../../lib/libretroshare.a LIBS += ../../../lib/libretroshare.a
LIBS += ../../../../../libbitdht/src/lib/libbitdht.a LIBS += ../../../../../libbitdht/src/lib/libbitdht.a
LIBS += ../../../../../openpgpsdk/src/lib/libops.a LIBS += ../../../../../openpgpsdk/src/lib/libops.a
LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lsqlite3 -lbz2 LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lbz2
# We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database.
LIBS += /home/crispy/Development/retroshare/sqlcipher/sqlcipher/.libs/libsqlite3.a
LIBS *= -rdynamic -frtti LIBS *= -rdynamic -frtti
DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions
DEFINES *= UBUNTU DEFINES *= UBUNTU

View file

@ -159,8 +159,9 @@ void GenExchangeTest::setUp()
void GenExchangeTest::breakDown() void GenExchangeTest::breakDown()
{ {
mTestService->join(); mDataService->resetDataStore();
clearAllData(); mTestService->join();
clearAllData();
} }
bool msgDataSort(const RsDummyMsg* m1, const RsDummyMsg* m2) bool msgDataSort(const RsDummyMsg* m1, const RsDummyMsg* m2)

View file

@ -258,7 +258,7 @@ private:
std::list<RsGroupMetaData> mGrpMetaDataOut, mGrpMetaDataIn; std::list<RsGroupMetaData> mGrpMetaDataOut, mGrpMetaDataIn;
std::list<RsGxsGroupId> mGrpIdsOut, mGrpIdsIn; std::list<RsGxsGroupId> mGrpIdsOut, mGrpIdsIn;
DummyMsgMap mMsgDataOut, mMsgDataIn; std::map<RsGxsGroupId, std::vector<RsDummyMsg*> > mMsgDataOut, mMsgDataIn;
GxsMsgMetaMap mMsgMetaDataOut, mMsgMetaDataIn; GxsMsgMetaMap mMsgMetaDataOut, mMsgMetaDataIn;
GxsMsgIdResult mMsgIdsOut, mMsgIdsIn; GxsMsgIdResult mMsgIdsOut, mMsgIdsIn;

View file

@ -17,6 +17,11 @@ void GenExchangeTestService::publishDummyGrp(uint32_t &token, RsDummyGrp *grp)
publishGroup(token, grp); publishGroup(token, grp);
} }
void GenExchangeTestService::updateDummyGrp(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta, RsDummyGrp *group)
{
updateGroup(token, updateMeta, group);
}
void GenExchangeTestService::publishDummyMsg(uint32_t &token, RsDummyMsg *msg) void GenExchangeTestService::publishDummyMsg(uint32_t &token, RsDummyMsg *msg)
{ {
publishMsg(token, msg); publishMsg(token, msg);

View file

@ -15,6 +15,7 @@ public:
void notifyChanges(std::vector<RsGxsNotify*>& changes); void notifyChanges(std::vector<RsGxsNotify*>& changes);
void publishDummyGrp(uint32_t& token, RsDummyGrp* grp); void publishDummyGrp(uint32_t& token, RsDummyGrp* grp);
void updateDummyGrp(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsDummyGrp *group);
void publishDummyMsg(uint32_t& token, RsDummyMsg* msg); void publishDummyMsg(uint32_t& token, RsDummyMsg* msg);
/*! /*!

View file

@ -7,6 +7,7 @@
#include "gxspublishgrouptest.h" #include "gxspublishgrouptest.h"
#include "util/utest.h" #include "util/utest.h"
#include "support.h"
#define POLLING_TIME_OUT 5 #define POLLING_TIME_OUT 5
@ -169,6 +170,65 @@ bool GxsPublishGroupTest::testGrpIdRetrieval()
return ok; return ok;
} }
bool GxsPublishGroupTest::testUpdateGroup()
{
setUp();
GenExchangeTestService* testService = getTestService();
RsTokenService* tokenService = getTokenService();
// create some random grps to allow msg testing
RsDummyGrp* dgrp1 = new RsDummyGrp();
RsDummyGrp* dgrp2 = new RsDummyGrp();
RsDummyGrp* dgrp2_copy = new RsDummyGrp();
init(*dgrp1);
init(*dgrp2);
RsTokReqOptions opts;
opts.mReqType = 45000;
uint32_t token;
RsGxsGroupId grpId;
std::vector<RsDummyGrp*> groupsPublished;
std::list<RsGxsGroupId> grpIds;
std::string name = dgrp1->meta.mGroupName;
*dgrp2 = *dgrp1;
testService->publishDummyGrp(token, dgrp1);
bool ok = pollForGrpAcknowledgement(token, grpId);
grpIds.push_back(grpId);
RsGxsGroupUpdateMeta updateMeta(grpId);
updateMeta.setMetaUpdate(RsGxsGroupUpdateMeta::NAME, name);
randString(SHORT_STR, dgrp2->grpData);
dgrp2->meta.mGroupId = grpId;
*dgrp2_copy = *dgrp2;
dgrp2->grpData ="ojfosfjsofjsof";
testService->updateDummyGrp(token, updateMeta, dgrp2);
ok &= pollForGrpAcknowledgement(token, grpId);
groupsPublished.push_back(dgrp2_copy);
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
tokenService->requestGroupInfo(token, 0, opts, grpIds);
pollForToken(token, opts, true);
ok &= compareGrpData();
breakDown();
return ok;
}
bool GxsPublishGroupTest::testGrpMetaRetrieval() bool GxsPublishGroupTest::testGrpMetaRetrieval()
{ {
@ -229,10 +289,11 @@ bool GxsPublishGroupTest::testGrpMetaRetrieval()
} }
void GxsPublishGroupTest::runTests() void GxsPublishGroupTest::runTests()
{ {
CHECK(testGrpSubmissionRetrieval()); // CHECK(testGrpSubmissionRetrieval());
CHECK(testGrpIdRetrieval()); // CHECK(testGrpIdRetrieval());
CHECK(testGrpMetaRetrieval()); // CHECK(testGrpMetaRetrieval());
CHECK(testSpecificGrpRetrieval()); // CHECK(testSpecificGrpRetrieval());
CHECK(testUpdateGroup());
} }

View file

@ -26,6 +26,7 @@ private:
bool testSpecificGrpRetrieval(); bool testSpecificGrpRetrieval();
bool testGrpIdRetrieval(); bool testGrpIdRetrieval();
bool testGrpMetaRetrieval(); bool testGrpMetaRetrieval();
bool testUpdateGroup();
private: private:

View file

@ -49,10 +49,10 @@ bool GxsPublishMsgTest::testMsgSubmissionRetrieval()
msgOut->meta.mMsgId = msgId.second; msgOut->meta.mMsgId = msgId.second;
DummyMsgMap msgMap; DummyMsgMap msgMap;
std::vector<RsDummyMsg*> msgV; std::vector<RsDummyMsg*> msgV;
msgV.push_back(msgOut); msgV.push_back(msgOut);
msgMap[msgOut->meta.mGroupId] = msgV; msgMap[msgOut->meta.mGroupId] = msgV;
storeToMsgDataOutMaps(msgMap); storeToMsgDataOutMaps(msgMap);
RsTokReqOptions opts; RsTokReqOptions opts;

View file

@ -30,16 +30,16 @@ INITTEST();
int main() int main()
{ {
RsGeneralDataService* dataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL); RsGeneralDataService* dataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL, "");
// we want to use default authentication which is NO authentication :) // we want to use default authentication which is NO authentication :)
GenExchangeTestService testService(dataStore, NULL, NULL); GenExchangeTestService testService(dataStore, NULL, NULL);
//GxsPublishGroupTest testGrpPublishing(&testService, dataStore); GxsPublishGroupTest testGrpPublishing(&testService, dataStore);
//testGrpPublishing.runTests(); testGrpPublishing.runTests();
GxsPublishMsgTest testMsgPublishing(&testService, dataStore); //GxsPublishMsgTest testMsgPublishing(&testService, dataStore);
testMsgPublishing.runTests(); //testMsgPublishing.runTests();
FINALREPORT("RsGenExchangeTest"); FINALREPORT("RsGenExchangeTest");

View file

@ -0,0 +1,110 @@
/*
* rsgxsupdateitem_test.cc
*
* Created on: 9 Dec 2013
* Author: crispy
*/
#include "support.h"
#include "rsgxsupdateitem_test.h"
INITTEST();
RsSerialType* init_item(RsGxsGrpUpdateItem& i)
{
i.clear();
i.grpUpdateTS = rand()%2424;
randString(SHORT_STR, i.peerId);
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsGxsMsgUpdateItem& i)
{
i.clear();
randString(SHORT_STR, i.peerId);
int numUpdates = rand()%123;
std::string peer;
for(int j=0; j < numUpdates; j++)
{
randString(SHORT_STR, peer);
i.msgUpdateTS.insert(std::make_pair(peer, rand()%45));
}
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsGxsServerGrpUpdateItem& i)
{
i.clear();
i.grpUpdateTS = rand()%2424;
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsGxsServerMsgUpdateItem& i)
{
i.clear();
randString(SHORT_STR, i.grpId);
i.msgUpdateTS = rand()%4252;
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
bool operator ==(const RsGxsGrpUpdateItem& l, const RsGxsGrpUpdateItem& r)
{
bool ok = l.grpUpdateTS == r.grpUpdateTS;
ok &= l.peerId == r.peerId;
return ok;
}
bool operator ==(const RsGxsMsgUpdateItem& l, const RsGxsMsgUpdateItem& r)
{
bool ok = l.peerId == r.peerId;
const std::map<std::string, uint32_t>& lUp = l.msgUpdateTS, rUp = r.msgUpdateTS;
ok &= lUp.size() == rUp.size();
std::map<std::string, uint32_t>::const_iterator lit = lUp.begin(), rit;
for(; lit != lUp.end(); lit++)
{
std::string key = lit->first;
if((rit = rUp.find(key)) != rUp.end())
ok &= lit->second == rit->second;
else
return false;
}
return ok;
}
bool operator ==(const RsGxsServerGrpUpdateItem& l,
const RsGxsServerGrpUpdateItem& r)
{
return l.grpUpdateTS == r.grpUpdateTS;
}
bool operator ==(const RsGxsServerMsgUpdateItem& l,
const RsGxsServerMsgUpdateItem& r)
{
bool ok = l.grpId == r.grpId;
ok &= l.msgUpdateTS == r.msgUpdateTS;
return ok;
}
int main()
{
std::cerr << "RsGxsUpdateItem Tests" << std::endl;
test_RsItem<RsGxsGrpUpdateItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsGrpUpdateItem");
test_RsItem<RsGxsMsgUpdateItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsMsgUpdateItem");
test_RsItem<RsGxsServerGrpUpdateItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsServerGrpUpdateItem");
test_RsItem<RsGxsServerMsgUpdateItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsServerMsgUpdateItem");
FINALREPORT("RsGxsUpdateItem Tests");
return TESTRESULT();
}

View file

@ -0,0 +1,25 @@
/*
* rsgxsupdateitem_test.h
*
* Created on: 9 Dec 2013
* Author: crispy
*/
#ifndef RSGXSUPDATEITEM_TEST_H_
#define RSGXSUPDATEITEM_TEST_H_
#include "serialiser/rsgxsupdateitems.h"
#include "support.h"
RsSerialType* init_item(RsGxsGrpUpdateItem& i);
RsSerialType* init_item(RsGxsMsgUpdateItem& i);
RsSerialType* init_item(RsGxsServerGrpUpdateItem& i);
RsSerialType* init_item(RsGxsServerMsgUpdateItem& i);
bool operator==(const RsGxsGrpUpdateItem& l, const RsGxsGrpUpdateItem& r);
bool operator==(const RsGxsMsgUpdateItem& l, const RsGxsMsgUpdateItem& r);
bool operator==(const RsGxsServerGrpUpdateItem& l, const RsGxsServerGrpUpdateItem& r);
bool operator==(const RsGxsServerMsgUpdateItem& l, const RsGxsServerMsgUpdateItem& r);
#endif /* RSGXSUPDATEITEM_TEST_H_ */

View file

@ -39,7 +39,7 @@ RsSerialType* init_item(RsNxsSyncGrp& rsg)
{ {
rsg.clear(); rsg.clear();
rsg.flag = RsNxsSyncGrp::FLAG_USE_SYNC_HASH; rsg.flag = RsNxsSyncGrp::FLAG_USE_SYNC_HASH;
rsg.syncAge = rand()%2423; rsg.createdSince = rand()%2423;
randString(3124,rsg.syncHash); randString(3124,rsg.syncHash);
return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
@ -50,7 +50,7 @@ RsSerialType* init_item(RsNxsSyncMsg& rsgm)
rsgm.clear(); rsgm.clear();
rsgm.flag = RsNxsSyncMsg::FLAG_USE_SYNC_HASH; rsgm.flag = RsNxsSyncMsg::FLAG_USE_SYNC_HASH;
rsgm.syncAge = rand()%24232; rsgm.createdSince = rand()%24232;
rsgm.transactionNumber = rand()%23; rsgm.transactionNumber = rand()%23;
randString(SHORT_STR, rsgm.grpId); randString(SHORT_STR, rsgm.grpId);
randString(SHORT_STR, rsgm.syncHash); randString(SHORT_STR, rsgm.syncHash);
@ -120,7 +120,7 @@ bool operator==(const RsNxsSyncGrp& l, const RsNxsSyncGrp& r)
if(l.syncHash != r.syncHash) return false; if(l.syncHash != r.syncHash) return false;
if(l.flag != r.flag) return false; if(l.flag != r.flag) return false;
if(l.syncAge != r.syncAge) return false; if(l.createdSince != r.createdSince) return false;
if(l.transactionNumber != r.transactionNumber) return false; if(l.transactionNumber != r.transactionNumber) return false;
return true; return true;
@ -130,7 +130,7 @@ bool operator==(const RsNxsSyncMsg& l, const RsNxsSyncMsg& r)
{ {
if(l.flag != r.flag) return false; if(l.flag != r.flag) return false;
if(l.syncAge != r.syncAge) return false; if(l.createdSince != r.createdSince) return false;
if(l.syncHash != r.syncHash) return false; if(l.syncHash != r.syncHash) return false;
if(l.grpId != r.grpId) return false; if(l.grpId != r.grpId) return false;
if(l.transactionNumber != r.transactionNumber) return false; if(l.transactionNumber != r.transactionNumber) return false;

View file

@ -65,6 +65,7 @@ template<class Key, class Value> class RsMemCache
bool fetch(const Key &key, Value &data); bool fetch(const Key &key, Value &data);
Value &ref(const Key &key); // like map[] installs empty one if non-existent. Value &ref(const Key &key); // like map[] installs empty one if non-existent.
bool store(const Key &key, const Value &data); bool store(const Key &key, const Value &data);
bool erase(const Key &key); // clean up cache.
bool resize(); // should be called periodically to cleanup old entries. bool resize(); // should be called periodically to cleanup old entries.
@ -169,6 +170,48 @@ template<class Key, class Value> bool RsMemCache<Key, Value>::fetch(const Key &k
} }
template<class Key, class Value> bool RsMemCache<Key, Value>::erase(const Key &key)
{
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase()";
std::cerr << std::endl;
printStats(std::cerr);
#endif // DEBUG_RSMEMCACHE
typename std::map<Key, cache_data>::iterator it;
it = mDataMap.find(key);
if (it == mDataMap.end())
{
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase(" << key << ") false";
std::cerr << std::endl;
#endif // DEBUG_RSMEMCACHE
mStats_accessmiss++;
return false;
}
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase(" << key << ") OK";
std::cerr << std::endl;
#endif // DEBUG_RSMEMCACHE
/* get timestamps */
time_t old_ts = it->second.ts;
time_t new_ts = 0;
// remove from lru.
mDataMap.erase(it);
update_lrumap(key, old_ts, new_ts);
mDataCount--;
mStats_access++;
return true;
}
template<class Key, class Value> Value &RsMemCache<Key, Value>::ref(const Key &key) template<class Key, class Value> Value &RsMemCache<Key, Value>::ref(const Key &key)
{ {
#ifdef DEBUG_RSMEMCACHE #ifdef DEBUG_RSMEMCACHE
@ -320,6 +363,12 @@ template<class Key, class Value> bool RsMemCache<Key, Value>::resize()
// ERROR. // ERROR.
std::cerr << "RsMemCache::resize() CONSISTENCY ERROR"; std::cerr << "RsMemCache::resize() CONSISTENCY ERROR";
std::cerr << std::endl; std::cerr << std::endl;
std::cerr << "\tmDataMap.size() = " << mDataMap.size();
std::cerr << std::endl;
std::cerr << "\tmLruMap.size() = " << mLruMap.size();
std::cerr << std::endl;
std::cerr << "\tmDataCount = " << mDataCount;
std::cerr << std::endl;
} }
if (mDataCount > mMaxSize) if (mDataCount > mMaxSize)

View file

@ -0,0 +1,640 @@
/*
* libretroshare/src/util: rsrecogn.cc
*
* RetroShare Utilities
*
* Copyright 2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include "pqi/pqi_base.h"
#include "util/rsrecogn.h"
#include "util/radix64.h"
#include "util/rsstring.h"
#include "gxs/gxssecurity.h"
/***
* #define DEBUG_RECOGN 1
***/
#define DEBUG_RECOGN 1
static std::string RecognKey = "MIICCgKCAgEA4/i2fy+zR27/H8fzphM8mR/Nz+yXjMJTtqKlCvEMQlyk7lKzDbKifNjGSiAXjSv3b9TRgMtje7hfEhs3//Oeu4KsCf6sz17aj2StBF579IdJTSUPDwq6jCsZ6NDEYpG8xz3FVV+Ac8q5Vpr/+jdg23ta09zq4aV8VIdIsroVOmZQqjwPcmQK57iWHd538i/XBtc2rnzbYq5bprnmtAKdx55gXVXDfALa0s6yR0HYvCaWguMEJhMIKWfi/9PEgLgwF9OmRwywc2TU/EdvYJo8fYHLfGk0PnYBuL1oSnn3cwAAef02W2JyCzQ84g30tLSUk+hC1LLi+iYj3x7IRR4q7Rlf/FYv/Q5fvjRtPT9eqM6fKyJ9ZO4NjlrSPFGydNbgABzP6WMhBzFjUkEKS27bGmr8Qxdj3Zp0TvR2IkyM6oM+6YknuM4RndUEgC1ZxtoIhugMjm6HdMQmoaHNK3kXewgQB90HHqzKA/J1gok3NcqL8Yls5g0LHepVHsU4cuaIqQr5yr665ZTLU2oqn1HIdkgydBYYUt6G3eWJKXYRbDhWPthGo/HK+W+iw6cTGWxzlCZS40EU9efxz4mDuhow67jOe704lBP3kiYXu05Y5uspaYnuvrvIwaRWBYapyR9UmKktnY8xJYrZvrcZgCovAbiodTzWeYg37xjFfGgYNI8CAwEAAQ==";
#define NUM_RECOGN_SIGN_KEYS 3
static std::string RecognSigningKeys[NUM_RECOGN_SIGN_KEYS] =
{
"AvMxAwAAA5YQMAAAABAANAAAAAoAAAABEEAAAAFMAKQAAAAmYjI2ZTUyNGFlZjczYmY3Y2MyMzUwNTc0ZTMyMjcxZWEAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQCyblJK73O/fMI1BXTjInHqIWma62Z2r3K7/giT6Xm3k+lyNokvpR+I45XdEvPRmFVZmTU7XT2n3YiPDLe7y2r9fnYiLvBCdu+FBaVv5UQG8nvFGMLKbhdyRpOSBgDc+Y+8plMPn8jqgfNhLROMowmvDJQkJQjlm80d/9wj+VZ+tLiPPo8uOlghqNhdXDGK7HnfeLrJyD8kLEW7+4huaxR8IsLgjzuK8rovGLYCBcnx4TXvtbEeafJBBBt8S/GPeUaB1rxWpVV6fi+oBU6cvjbEqPzSalIrwNPyqlj+1SbL1jGEGEr1XIMzDa96SVsJ0F93lS3H9c8HdvByAifgzbPZAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBp1w449QGjchVotgHvGWRh18zpsDUHRv8PlRX1vXy8FMstTrnRjaDofFitmpJm8K6F1t/9jviCdB+BCvRzAS4SxER49YCBp04xZfX7c03xdq/e27jYRds2w6YHTiEgNi5v1cyWhrwDcCdefXRnHTH1UOw3jOoWnlnmM6jEsL39XI5fvsog9z8GxcG54APKA7JgiqhgMcrKRwNk74XJAzcjB6FS8xaV2gzpZZLNZ1TU+tJoLSiRqTU8UiAGbAR85lYLT5Ozdd2C+bTQ9f6vltz8bpzicJzxGCIsYtSL44InQsO/Oar9IgZu8QE4pTuunGJhVqEZru7ZN+oV+wXt51n+24SS0sNgNKVUFS74RfvsFi67CrXSWTOI8bVS0Lvv3EMWMdSF9dHGbdCFnp2/wqbW/4Qz7XYF4lcu9gLe4UtIrZ6TkAvBtnSfvTTdXj7kD6oHDjrUCjHPxdhz3BLRbj1wENZsoS3QDl22Ts7dbO8wHjutsS3/zx4DLlADoFlU8p7HJaCdrsq20P4WCeQJb6JbbLpGRAccKAidAPHMxQ4fr3b+GtjxpLJtXaytr4CPSXsCt4TloE9g5yCE6n/2UxQACp8Guh9l2MXmrD7qEGexhYqFB/OG84u3vL+gskmsKXTEqi2SiSmhvzta2p2hGCLCKRQeYbn+4TsIQfgWtYNQvC",
"AvMxAwAAA5YQMAAAABAANAAAAAoAAAACEEAAAAFMAKQAAAAmYjY0OTJkODMzNTI5ZjMxMGM1MmRjMDc3ZjBmZDgyMjcAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQC2SS2DNSnzEMUtwHfw/YInm/XLXEUMktyZTmyMWACBbEfmU6aztT3vxz6UHoCBYtKkzKrfDZLvXe0a5TRLMmK+yfl5IzIVUPdqTg6FF3Bx/GXdj4v/ZP6lAuqY5YeI4wPcKldrrIJ9DTUdhZhgdtgDtxGvrXZ8eFjcl9zM+QEykYKMwfnTCixzVOPCCo3q1lJO13NmlhVQDO+f9vvTZsYDCcZHMqlKZWcCEyY1ZpQiCqlsL8wN6tKxMuSQO8EGdH/tNzsGHwCoZq6EEL7SX/pmc2ABjpDQTLixgXwJtCpw8Fwj1xiavsFFbqSLu3SjUCcrMz9f8U5p2ROyv//lWxsXAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBksDPQ93PdZBGCEnKXcQsdB4yBA9NpImVR81JZdPmWlTwZGAXGJwt4EkBcz+xdey84JDujVtHJUzIL9Ws/Jq5MuXHr0tP5ebah1GCQF2/Ov7sctUk3UPBxeroon7gZQhuzaIJVhl0rzwWriFUbTu7H7g9eaTHMvyfUg+S0Z2p+e0+PdL5rfGOJJZ6+NJCXxxbQ//cF4s0PAzkjAuwDmC+OiUiU5V6fY4XtRMCEI7w+UCj+wQn2Wu1Wc7xVM9uow13rGaLPYkWZ/9v+wNhg0KCsVfKGhkAGGzGyKI9LAppFVTu52pBlRu9Ung7VkhF0JC2aadYKKFl99wCbsGqUYN/gtfgHYCV24LNVah2dAy8CI9UmHdWk1kIwWazbPTYKLfpYCTFxqEqXqo3ijLf0YPsfhIvCQpc5VHAvLJlDm0RFKwzK6N9Zu9s9IvJHzIpaAAHCQJPtYxPwWMdt83njGo9wu1+aVkl5Sb5X8N16AybbnQ7fCBqJruGBM0LHtWVbHEiEygD7OStzyhT5rXKZSQYMA9I2CvK1t7qfDXDM40k8SVQ5CrS9R8x1wqQbe+DqNJ9tMfbUmN0xrO/w2pTl/4edKW30TShW/fr3vCWpVq8gcm3CVFSZUaC4T9wqH96K6KgIPbmg1Hk158pxXYXopEv6ZxR7UTPxKB0O22aIHB6UQ5",
"AvMxAwAAA5YQMAAAABAANAAAAAoAAAABEEAAAAFMAKQAAAAmOTdhNTJkMThjMDBjYWE3YmZlYmQ4NTg0MDJkMzBhY2QAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQCXpS0YwAyqe/69hYQC0wrNz7eUHAmJfR5EV7NVFQeOxtTlFwbdvRMK8ZpfqEoRhIPXAYCc9Dv3F7WcmcFer8d50EWhlK7rCQScaRdwL1UmF1dUY8bR8QxhJOUgwmrlzeKOHi2DJ3/9AXm7NJR8XMJgHEQQwi3z/aQsWrwCUA0mk68C8a3vjLtcMj5XBuNXRtGZ9zFjiI9Xt19y0iIKdYpfzOnJTKVETcjH7XPBBbJETWkrEyToHXPjcfhESAbJDOoyfQQbxHMQNE7no7owN08LoWX2kOSGtl2m6JbE2OEdJig83a6U3PDYfYM5LCfsAJEIroYhB3qZJDE98zGC8jihAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBiwl7oRPJzLlwDd8AzVolFQH1ZS+MWLA4B1eHCjCXSMn+zS0Su6CrpC6/vLwECaKSfNZ8y7T2fNDPJHMLmc1F6jJkdNZq3TZGNRgJx24OF3G5MU6mAH7DBsz7muFto+URTJl9CdJviIyQAn5E+R4Gp531RJdKlbqJl/gWuQMVem+eo3elpVEn8Ckg0yvFaFdhGFTOPyrXOZ6fI0pdCX0SH2q/vAIxGDRzaSYmsR0Y+oYZs0AeRnZD9iEh1v17xnVEdSoLZmZbjlLXXgqhbdXGik6ZoXQg3bTfl5D1j8Tk/d/CXqf0SUKBnIafaNgUeQSMY95M3k3vjPQN7vHdXmg19GnqQmBnGq45qdKI7+0Erfhl4po1z6yVvx9JfIMIDOsKwO3U/As5zbO2BYso0pUP4+gndissfDfqlPRni3orA0tlV6NuLmXi1wkHCu8HQ8WOqEUlWDJNLNpHW5OmgjMFqlIPt7hX5jlc9eXd4oMyaqXm1Tg8Cgbh5DYaT9A7He47+QhqYlPygqK9Fm0ZnH3Yz51cm3p2tRB1JU7qH9h5UqLLKJMBuIx7e9L5ieTfzKmTw6tqpIpHpiR/8bSQlKkw2LxikFy3OXL5obY1t9sWk35BNZQqcqflI6mkPrvGQKwN+co8GjUon5/Y1HSM6ursaJtkD8dz+oXVyWAokkuD7QZ",
};
EVP_PKEY *RsRecogn::loadMasterKey()
{
/* load master signing key */
size_t keylen;
char *keyptr;
Radix64::decode(RecognKey, keyptr, keylen);
const unsigned char *keyptr2 = (const unsigned char *) keyptr;
long keylen2 = keylen;
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr2), keylen2);
delete []keyptr;
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadMasterKeys() failed rsakey load";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return NULL;
}
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
return signKey;
}
bool RsRecogn::loadSigningKeys(std::map<std::string, RsGxsRecognSignerItem *> &signMap)
{
EVP_PKEY *signKey = loadMasterKey();
RsGxsRecognSerialiser recognSerialiser;
if (!signKey)
{
std::cerr << "RsRecogn::loadSigningKeys() missing Master Key";
return false;
}
time_t now = time(NULL);
for(int i = 0; i < NUM_RECOGN_SIGN_KEYS; i++)
{
char *signerbuf;
size_t len;
Radix64::decode(RecognSigningKeys[i], signerbuf, len);
uint32_t pktsize = len;
RsItem *pktitem = recognSerialiser.deserialise(signerbuf, &pktsize);
RsGxsRecognSignerItem *item = dynamic_cast<RsGxsRecognSignerItem *>(pktitem);
delete []signerbuf;
if (!item)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() failed to deserialise SignerItem";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
continue;
}
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() SignerItem: ";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
/* check dates */
if ((item->key.startTS > (unsigned) now) || (item->key.endTS < (unsigned) now))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() failed timestamp";
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() key.startTS: " << item->key.startTS;
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() now: " << now;
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() key.endTS: " << item->key.endTS;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
delete item;
continue;
}
/* check signature */
RsTlvKeySignature signature = item->sign;
item->sign.TlvShallowClear();
unsigned int siglen = signature.signData.bin_len;
unsigned char *sigbuf = (unsigned char *) signature.signData.bin_data;
/* store in */
uint32_t datalen = recognSerialiser.size(item);
uint8_t *data = (uint8_t *) malloc(datalen);
uint32_t pktlen = datalen;
int signOk = 0;
if (recognSerialiser.serialise(item, data, &pktlen))
{
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, data, pktlen);
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
EVP_MD_CTX_destroy(mdctx);
item->sign = signature;
signature.TlvShallowClear();
if (signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() signature ok";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
std::string signerId = item->key.keyId;
signMap[signerId] = item;
}
}
if (!signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() signature failed";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
delete item;
}
free(data);
}
/* clean up */
EVP_PKEY_free(signKey);
return true;
}
bool RsRecogn::validateTagSignature(RsGxsRecognSignerItem *signer, RsGxsRecognTagItem *item)
{
if (item->sign.keyId != signer->key.keyId)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() keyId mismatch";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
const unsigned char *keyptr = (const unsigned char *) signer->key.keyData.bin_data;
long keylen = signer->key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() failed extract signkey";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
/* check signature */
RsTlvKeySignature signature = item->sign;
item->sign.TlvShallowClear();
unsigned int siglen = signature.signData.bin_len;
unsigned char *sigbuf = (unsigned char *) signature.signData.bin_data;
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
/* store in */
RsGxsRecognSerialiser serialiser;
uint32_t datalen = serialiser.size(item);
uint8_t *data = (uint8_t *) malloc(datalen);
int signOk = 0;
uint32_t pktlen = datalen;
if (serialiser.serialise(item, data, &pktlen))
{
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, data, pktlen);
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() sign_result: " << signOk;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
}
else
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() failed to serialise";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
}
// Clean up.
item->sign = signature;
signature.TlvShallowClear();
EVP_MD_CTX_destroy(mdctx);
EVP_PKEY_free(signKey);
free(data);
return (signOk == 1);
}
bool rsa_sanity_check(RSA *rsa)
{
std::cerr << "rsa_sanity_check()";
std::cerr << std::endl;
if (!rsa)
{
std::cerr << "rsa_sanity_check() RSA == NULL";
std::cerr << std::endl;
return false;
}
RSA *pubkey = RSAPublicKey_dup(rsa);
std::string signId = RsRecogn::getRsaKeyId(rsa);
std::string signId2 = RsRecogn::getRsaKeyId(pubkey);
bool ok = true;
if (signId != signId2)
{
std::cerr << "rsa_sanity_check() ERROR SignId Failure";
std::cerr << std::endl;
ok = false;
}
if (1 != RSA_check_key(rsa))
{
std::cerr << "rsa_sanity_check() ERROR RSA key is not private";
std::cerr << std::endl;
ok = false;
}
#if 0
if (1 == RSA_check_key(pubkey))
{
std::cerr << "rsa_sanity_check() ERROR RSA dup key is private";
std::cerr << std::endl;
ok = false;
}
#endif
RSA_free(pubkey);
if (!ok)
{
exit(1);
}
return true;
}
bool RsRecogn::signTag(EVP_PKEY *signKey, RsGxsRecognTagItem *item)
{
RsGxsRecognSerialiser serialiser;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signTag() Failed serialise TagItem:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::signSigner(EVP_PKEY *signKey, RsGxsRecognSignerItem *item)
{
std::cerr << "RsRecogn::signSigner()";
std::cerr << std::endl;
RsGxsRecognSerialiser serialiser;
std::cerr << "RsRecogn::signSigner() Checking Key";
std::cerr << std::endl;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
std::cerr << "RsRecogn::signSigner() Key Okay";
std::cerr << std::endl;
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signSigner() Failed serialise SignerItem:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::signTagRequest(EVP_PKEY *signKey, RsGxsRecognReqItem *item)
{
std::cerr << "RsRecogn::signTagRequest()";
std::cerr << std::endl;
RsGxsRecognSerialiser serialiser;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signTagRequest() Failed serialise Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::itemToRadix64(RsItem *item, std::string &radstr)
{
RsGxsRecognSerialiser serialiser;
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
return false;
}
radstr.clear();
Radix64::encode(buf, len, radstr);
return true;
}
std::string RsRecogn::getRsaKeyId(RSA *pubkey)
{
int len = BN_num_bytes(pubkey -> n);
unsigned char tmp[len];
BN_bn2bin(pubkey -> n, tmp);
// copy first CERTSIGNLEN bytes...
if (len > CERTSIGNLEN)
{
len = CERTSIGNLEN;
}
std::string id;
for(uint32_t i = 0; i < CERTSIGNLEN; i++)
{
rs_sprintf_append(id, "%02x", (uint16_t) (((uint8_t *) (tmp))[i]));
}
return id;
}
RsGxsRecognTagItem *RsRecogn::extractTag(const std::string &encoded)
{
// Decode from Radix64 encoded Packet.
size_t buflen;
char *buffer;
uint32_t pktsize;
Radix64::decode(encoded, buffer, buflen);
pktsize = buflen;
RsGxsRecognSerialiser serialiser;
RsItem *item = serialiser.deserialise(buffer, &pktsize);
delete []buffer;
if (!item)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::extractTag() ERROR Deserialise failed";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return NULL;
}
RsGxsRecognTagItem *tagitem = dynamic_cast<RsGxsRecognTagItem *>(item);
if (!tagitem)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::extractTag() ERROR Not TagItem, is: ";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete item;
}
return tagitem;
}
bool RsRecogn::createTagRequest(const RsTlvSecurityKey &key, const std::string &id, const std::string &nickname, uint16_t tag_class, uint16_t tag_type, const std::string &comment, std::string &tag)
{
RsGxsRecognReqItem *item = new RsGxsRecognReqItem();
EVP_PKEY *signKey = EVP_PKEY_new();
RSA *rsakey = GxsSecurity::extractPrivateKey(key);
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to extract key";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
if (!EVP_PKEY_assign_RSA(signKey, rsakey))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to assign key";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
item->issued_at = time(NULL);
item->period = 365 * 24 * 3600;
item->tag_class = tag_class;
item->tag_type = tag_type;
item->nickname = nickname;
item->identity = id;
item->comment = comment;
bool signOk = RsRecogn::signTagRequest(signKey,item);
EVP_PKEY_free(signKey);
if (!signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to sign Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete item;
return false;
}
/* write out the item for signing */
RsGxsRecognSerialiser serialiser;
uint32_t len = serialiser.size(item);
char *buf = new char[len];
bool serOk = serialiser.serialise(item, buf, &len);
delete item;
if (serOk)
{
Radix64::encode(buf, len, tag);
}
delete []buf;
if (!serOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed serialise Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
return false;
}
return serOk;
}

View file

@ -0,0 +1,61 @@
/*
* libretroshare/src/util: rsrecogn.h
*
* RetroShare Utilities
*
* Copyright 2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef RSUTIL_RECOGN_H
#define RSUTIL_RECOGN_H
#include <inttypes.h>
#include <string>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include "serialiser/rsgxsrecognitems.h"
namespace RsRecogn {
EVP_PKEY * loadMasterKey();
bool loadSigningKeys(std::map<std::string, RsGxsRecognSignerItem *> &signMap);
bool validateTagSignature(RsGxsRecognSignerItem *signer, RsGxsRecognTagItem *item);
bool signTag(EVP_PKEY *signKey, RsGxsRecognTagItem *item);
bool signSigner(EVP_PKEY *signKey, RsGxsRecognSignerItem *item);
bool signTagRequest(EVP_PKEY *signKey, RsGxsRecognReqItem *item);
bool itemToRadix64(RsItem *item, std::string &radstr);
std::string getRsaKeyId(RSA *pubkey);
RsGxsRecognTagItem *extractTag(const std::string &encoded);
bool createTagRequest(const RsTlvSecurityKey &key,
const std::string &id, const std::string &nickname,
uint16_t tag_class, uint16_t tag_type,
const std::string &comment, std::string &tag);
}
#endif

View file

@ -80,6 +80,7 @@ void RsTickEvent::tick_events()
mEvents.erase(it); mEvents.erase(it);
count_adjust_locked(event_type, -1); count_adjust_locked(event_type, -1);
note_event_locked(event_type);
} }
} }

View file

@ -473,8 +473,7 @@ void IdDialog::insertIdDetails(uint32_t token)
mStateHelper->setWidgetEnabled(ui.pushButton_Reputation, false); mStateHelper->setWidgetEnabled(ui.pushButton_Reputation, false);
// No Delete Ids yet! // No Delete Ids yet!
mStateHelper->setWidgetEnabled(ui.pushButton_Delete, /*true*/ false); mStateHelper->setWidgetEnabled(ui.pushButton_Delete, /*true*/ false);
// No Editing Ids yet! mStateHelper->setWidgetEnabled(ui.pushButton_EditId, true);
mStateHelper->setWidgetEnabled(ui.pushButton_EditId, /*true*/ false);
} }
else else
{ {

View file

@ -61,10 +61,19 @@ IdEditDialog::IdEditDialog(QWidget *parent)
/* Connect signals */ /* Connect signals */
connect(ui.radioButton_GpgId, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool))); connect(ui.radioButton_GpgId, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool)));
connect(ui.radioButton_Pseudo, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool))); connect(ui.radioButton_Pseudo, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool)));
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateId())); connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(submit()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
connect(ui.plainTextEdit_Tag, SIGNAL(textChanged()), this, SLOT(checkNewTag()));
connect(ui.pushButton_Tag, SIGNAL(clicked(bool)), this, SLOT(addRecognTag()));
connect(ui.toolButton_Tag1, SIGNAL(clicked(bool)), this, SLOT(rmTag1()));
connect(ui.toolButton_Tag2, SIGNAL(clicked(bool)), this, SLOT(rmTag2()));
connect(ui.toolButton_Tag3, SIGNAL(clicked(bool)), this, SLOT(rmTag3()));
connect(ui.toolButton_Tag4, SIGNAL(clicked(bool)), this, SLOT(rmTag4()));
connect(ui.toolButton_Tag5, SIGNAL(clicked(bool)), this, SLOT(rmTag5()));
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this); mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
ui.pushButton_Tag->setEnabled(false);
} }
void IdEditDialog::setupNewId(bool pseudo) void IdEditDialog::setupNewId(bool pseudo)
@ -89,6 +98,10 @@ void IdEditDialog::setupNewId(bool pseudo)
// force - incase it wasn't triggered. // force - incase it wasn't triggered.
idTypeToggled(true); idTypeToggled(true);
ui.frame_Tags->setHidden(true);
ui.radioButton_GpgId->setEnabled(true);
ui.radioButton_Pseudo->setEnabled(true);
} }
void IdEditDialog::idTypeToggled(bool checked) void IdEditDialog::idTypeToggled(bool checked)
@ -144,7 +157,6 @@ void IdEditDialog::loadExistingId(uint32_t token)
mStateHelper->setLoading(IDEDITDIALOG_LOADID, false); mStateHelper->setLoading(IDEDITDIALOG_LOADID, false);
/* get details from libretroshare */ /* get details from libretroshare */
RsGxsIdGroup data;
std::vector<RsGxsIdGroup> datavector; std::vector<RsGxsIdGroup> datavector;
if (!rsIdentity->getGroupData(token, datavector)) if (!rsIdentity->getGroupData(token, datavector))
{ {
@ -166,9 +178,9 @@ void IdEditDialog::loadExistingId(uint32_t token)
return; return;
} }
data = datavector[0]; mEditGroup = datavector[0];
bool realid = (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID); bool realid = (mEditGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
if (realid) if (realid)
{ {
@ -178,25 +190,28 @@ void IdEditDialog::loadExistingId(uint32_t token)
{ {
ui.radioButton_Pseudo->setChecked(true); ui.radioButton_Pseudo->setChecked(true);
} }
// these are not editable for existing Id.
ui.radioButton_GpgId->setEnabled(false);
ui.radioButton_Pseudo->setEnabled(false);
// DOES THIS TRIGGER ALREADY??? // DOES THIS TRIGGER ALREADY???
// force - incase it wasn't triggered. // force - incase it wasn't triggered.
idTypeToggled(true); idTypeToggled(true);
ui.lineEdit_Nickname->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str())); ui.lineEdit_Nickname->setText(QString::fromUtf8(mEditGroup.mMeta.mGroupName.c_str()));
ui.lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId)); ui.lineEdit_KeyId->setText(QString::fromStdString(mEditGroup.mMeta.mGroupId));
if (realid) if (realid)
{ {
ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash)); ui.lineEdit_GpgHash->setText(QString::fromStdString(mEditGroup.mPgpIdHash));
if (data.mPgpKnown) if (mEditGroup.mPgpKnown)
{ {
RsPeerDetails details; RsPeerDetails details;
rsPeers->getGPGDetails(data.mPgpId, details); rsPeers->getGPGDetails(mEditGroup.mPgpId, details);
ui.lineEdit_GpgName->setText(QString::fromUtf8(details.name.c_str())); ui.lineEdit_GpgName->setText(QString::fromUtf8(details.name.c_str()));
ui.lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId)); ui.lineEdit_GpgId->setText(QString::fromStdString(mEditGroup.mPgpId));
} }
else else
{ {
@ -210,53 +225,216 @@ void IdEditDialog::loadExistingId(uint32_t token)
ui.lineEdit_GpgId->setText(tr("N/A")); ui.lineEdit_GpgId->setText(tr("N/A"));
ui.lineEdit_GpgName->setText(tr("N/A")); ui.lineEdit_GpgName->setText(tr("N/A"));
} }
// RecognTags.
ui.frame_Tags->setHidden(false);
loadRecognTags();
} }
void IdEditDialog::updateId() #define MAX_RECOGN_TAGS 5
void IdEditDialog::checkNewTag()
{ {
RsGxsIdGroup rid; std::string tag = ui.plainTextEdit_Tag->toPlainText().toStdString();
// Must set, Nickname, KeyId(if existing), mIdType, GpgId. std::string id = ui.lineEdit_KeyId->text().toStdString();
std::string name = ui.lineEdit_Nickname->text().toUtf8().data();
rid.mMeta.mGroupName = ui.lineEdit_Nickname->text().toUtf8().constData(); QString desc;
bool ok = tagDetails(id, name, tag, desc);
ui.label_TagCheck->setText(desc);
if (rid.mMeta.mGroupName.size() < 2) // hack to allow add invalid tags (for testing).
if (!tag.empty())
{ {
std::cerr << "IdEditDialog::updateId() Nickname too short"; ok = true;
}
if (mEditGroup.mRecognTags.size() >= MAX_RECOGN_TAGS)
{
ok = false;
}
ui.pushButton_Tag->setEnabled(ok);
}
void IdEditDialog::addRecognTag()
{
std::string tag = ui.plainTextEdit_Tag->toPlainText().toStdString();
if (mEditGroup.mRecognTags.size() >= MAX_RECOGN_TAGS)
{
std::cerr << "IdEditDialog::addRecognTag() Too many Tags, delete one first";
std::cerr << std::endl;
}
mEditGroup.mRecognTags.push_back(tag);
loadRecognTags();
}
void IdEditDialog::rmTag1()
{
rmTag(0);
}
void IdEditDialog::rmTag2()
{
rmTag(1);
}
void IdEditDialog::rmTag3()
{
rmTag(2);
}
void IdEditDialog::rmTag4()
{
rmTag(3);
}
void IdEditDialog::rmTag5()
{
rmTag(4);
}
void IdEditDialog::rmTag(int idx)
{
std::list<std::string>::iterator it;
int i = 0;
for(it = mEditGroup.mRecognTags.begin(); it != mEditGroup.mRecognTags.end() && (idx < i); it++, i++) ;
if (it != mEditGroup.mRecognTags.end())
{
mEditGroup.mRecognTags.erase(it);
}
loadRecognTags();
}
bool IdEditDialog::tagDetails(const std::string &id, const std::string &name, const std::string &tag, QString &desc)
{
if (tag.empty())
{
desc += "Empty Tag";
return false;
}
/* extract details for each tag */
RsRecognTagDetails tagDetails;
bool ok = false;
if (rsIdentity->parseRecognTag(id, name, tag, tagDetails))
{
desc += QString::number(tagDetails.tag_class);
desc += ":";
desc += QString::number(tagDetails.tag_type);
if (tagDetails.is_valid)
{
ok = true;
desc += " Valid";
}
else
{
desc += " Invalid";
}
if (tagDetails.is_pending)
{
ok = true;
desc += " Pending";
}
}
else
{
desc += "Unparseable";
}
return ok;
}
void IdEditDialog::loadRecognTags()
{
std::cerr << "IdEditDialog::loadRecognTags()";
std::cerr << std::endl;
// delete existing items.
ui.label_Tag1->setHidden(true);
ui.label_Tag2->setHidden(true);
ui.label_Tag3->setHidden(true);
ui.label_Tag4->setHidden(true);
ui.label_Tag5->setHidden(true);
ui.toolButton_Tag1->setHidden(true);
ui.toolButton_Tag2->setHidden(true);
ui.toolButton_Tag3->setHidden(true);
ui.toolButton_Tag4->setHidden(true);
ui.toolButton_Tag5->setHidden(true);
ui.plainTextEdit_Tag->setPlainText("");
int i = 0;
std::list<std::string>::const_iterator it;
for(it = mEditGroup.mRecognTags.begin(); it != mEditGroup.mRecognTags.end(); it++, i++)
{
QString recognTag;
tagDetails(mEditGroup.mMeta.mGroupId, mEditGroup.mMeta.mGroupName, *it, recognTag);
switch(i)
{
default:
case 0:
ui.label_Tag1->setText(recognTag);
ui.label_Tag1->setHidden(false);
ui.toolButton_Tag1->setHidden(false);
break;
case 1:
ui.label_Tag2->setText(recognTag);
ui.label_Tag2->setHidden(false);
ui.toolButton_Tag2->setHidden(false);
break;
case 2:
ui.label_Tag3->setText(recognTag);
ui.label_Tag3->setHidden(false);
ui.toolButton_Tag3->setHidden(false);
break;
case 3:
ui.label_Tag4->setText(recognTag);
ui.label_Tag4->setHidden(false);
ui.toolButton_Tag4->setHidden(false);
break;
case 4:
ui.label_Tag5->setText(recognTag);
ui.label_Tag5->setHidden(false);
ui.toolButton_Tag5->setHidden(false);
break;
}
}
}
void IdEditDialog::submit()
{
if (mIsNew)
{
createId();
}
else
{
updateId();
}
}
void IdEditDialog::createId()
{
std::string groupname = ui.lineEdit_Nickname->text().toUtf8().constData();
if (groupname.size() < 2)
{
std::cerr << "IdEditDialog::createId() Nickname too short";
std::cerr << std::endl; std::cerr << std::endl;
return; return;
} }
//rid.mIdType = RSID_RELATION_YOURSELF;
if (mIsNew)
{
rid.mMeta.mGroupId = "";
}
else
{
rid.mMeta.mGroupId = ui.lineEdit_KeyId->text().toStdString();
}
if (ui.radioButton_GpgId->isChecked())
{
//rid.mIdType |= RSID_TYPE_REALID;
//rid.mGpgId = ui.lineEdit_GpgId->text().toStdString();
rid.mPgpIdHash = ui.lineEdit_GpgHash->text().toStdString();
//rid.mGpgName = ui.lineEdit_GpgName->text().toUtf8().constData();
}
else
{
//rid.mIdType |= RSID_TYPE_PSEUDONYM;
//rid.mGpgId = "";
rid.mPgpIdHash = "";
//rid.mGpgName = "";
//rid.mGpgEmail = "";
}
// Can only create Identities for the moment!
RsIdentityParameters params; RsIdentityParameters params;
params.nickname = rid.mMeta.mGroupName; params.nickname = groupname;
params.isPgpLinked = (ui.radioButton_GpgId->isChecked()); params.isPgpLinked = (ui.radioButton_GpgId->isChecked());
uint32_t dummyToken = 0; uint32_t dummyToken = 0;
@ -265,6 +443,30 @@ void IdEditDialog::updateId()
close(); close();
} }
void IdEditDialog::updateId()
{
/* submit updated details */
std::string groupname = ui.lineEdit_Nickname->text().toUtf8().constData();
if (groupname.size() < 2)
{
std::cerr << "IdEditDialog::updateId() Nickname too short";
std::cerr << std::endl;
return;
}
mEditGroup.mMeta.mGroupName = groupname;
uint32_t dummyToken = 0;
rsIdentity->updateIdentity(dummyToken, mEditGroup);
close();
}
void IdEditDialog::loadRequest(const TokenQueue */*queue*/, const TokenRequest &req) void IdEditDialog::loadRequest(const TokenQueue */*queue*/, const TokenRequest &req)
{ {
std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType; std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType;

View file

@ -29,6 +29,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "util/TokenQueue.h" #include "util/TokenQueue.h"
#include <retroshare/rsidentity.h>
class UIStateHelper; class UIStateHelper;
@ -46,17 +47,34 @@ public:
private slots: private slots:
void idTypeToggled(bool checked); void idTypeToggled(bool checked);
void updateId(); void submit();
void addRecognTag();
void checkNewTag();
void rmTag1();
void rmTag2();
void rmTag3();
void rmTag4();
void rmTag5();
private: private:
void createId();
void updateId();
void updateIdType(bool pseudo); void updateIdType(bool pseudo);
void loadExistingId(uint32_t token); void loadExistingId(uint32_t token);
void loadRecognTags();
// extract details.
bool tagDetails(const std::string &id, const std::string &name, const std::string &tag, QString &desc);
void rmTag(int idx);
protected: protected:
Ui::IdEditDialog ui; Ui::IdEditDialog ui;
bool mIsNew; bool mIsNew;
UIStateHelper *mStateHelper; UIStateHelper *mStateHelper;
RsGxsIdGroup mEditGroup;
TokenQueue *mIdQueue; TokenQueue *mIdQueue;
}; };

View file

@ -6,147 +6,233 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>557</width> <width>510</width>
<height>179</height> <height>595</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item row="0" column="0"> <item>
<layout class="QFormLayout" name="formLayout"> <widget class="QFrame" name="frame">
<property name="fieldGrowthPolicy"> <property name="frameShape">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<item row="0" column="0"> <property name="frameShadow">
<widget class="QLabel" name="label"> <enum>QFrame::Raised</enum>
<property name="text"> </property>
<string>Nickname</string> <layout class="QGridLayout" name="gridLayout">
</property> <item row="0" column="0" colspan="2">
</widget> <layout class="QHBoxLayout" name="horizontalLayout">
</item> <item>
<item row="0" column="1"> <widget class="QRadioButton" name="radioButton_GpgId">
<widget class="QLineEdit" name="lineEdit_Nickname"/> <property name="text">
</item> <string>PGP Associated ID</string>
<item row="1" column="0"> </property>
<widget class="QLabel" name="label_4"> </widget>
<property name="text"> </item>
<string>Key ID</string> <item>
</property> <widget class="QRadioButton" name="radioButton_Pseudo">
</widget> <property name="text">
</item> <string>Pseudonym</string>
<item row="1" column="1"> </property>
<widget class="QLineEdit" name="lineEdit_KeyId"> </widget>
<property name="readOnly"> </item>
<bool>true</bool> </layout>
</property> </item>
</widget> <item row="1" column="0">
</item> <widget class="QLabel" name="label">
<item row="2" column="0"> <property name="text">
<widget class="QLabel" name="label_2"> <string>Nickname</string>
<property name="text"> </property>
<string>PGP Hash</string> </widget>
</property> </item>
</widget> <item row="1" column="1">
</item> <widget class="QLineEdit" name="lineEdit_Nickname"/>
<item row="2" column="1"> </item>
<widget class="QLineEdit" name="lineEdit_GpgHash"> <item row="2" column="0">
<property name="readOnly"> <widget class="QLabel" name="label_4">
<bool>true</bool> <property name="text">
</property> <string>Key ID</string>
</widget> </property>
</item> </widget>
<item row="3" column="0"> </item>
<widget class="QLabel" name="label_6"> <item row="2" column="1">
<property name="text"> <widget class="QLineEdit" name="lineEdit_KeyId">
<string>PGP Id</string> <property name="readOnly">
</property> <bool>true</bool>
</widget> </property>
</item> </widget>
<item row="3" column="1"> </item>
<widget class="QLineEdit" name="lineEdit_GpgId"> <item row="3" column="0">
<property name="readOnly"> <widget class="QLabel" name="label_2">
<bool>true</bool> <property name="text">
</property> <string>PGP Hash</string>
</widget> </property>
</item> </widget>
<item row="4" column="0"> </item>
<widget class="QLabel" name="label_3"> <item row="3" column="1">
<property name="text"> <widget class="QLineEdit" name="lineEdit_GpgHash">
<string>PGP Name</string> <property name="readOnly">
</property> <bool>true</bool>
</widget> </property>
</item> </widget>
<item row="4" column="1"> </item>
<widget class="QLineEdit" name="lineEdit_GpgName"> <item row="4" column="0">
<property name="readOnly"> <widget class="QLabel" name="label_6">
<bool>true</bool> <property name="text">
</property> <string>PGP Id</string>
</widget> </property>
</item> </widget>
<item row="5" column="1"> </item>
<spacer name="verticalSpacer_2"> <item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>PGP Name</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_Tags">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_Tag1">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="toolButton_Tag1">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_Tag2">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="toolButton_Tag2">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_Tag3">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QToolButton" name="toolButton_Tag3">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_Tag4">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QToolButton" name="toolButton_Tag4">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_Tag5">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QToolButton" name="toolButton_Tag5">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QPlainTextEdit" name="plainTextEdit_Tag"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_TagCheck">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="pushButton_Tag">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>328</width>
<height>40</height> <height>20</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <widget class="QDialogButtonBox" name="buttonBox">
<item> <property name="standardButtons">
<widget class="QRadioButton" name="radioButton_GpgId"> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<property name="text"> </property>
<string>PGP Associated ID</string> </widget>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_Pseudo">
<property name="text">
<string>Pseudonym</string>
</property>
</widget>
</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>
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<tabstops> <tabstops>
<tabstop>lineEdit_Nickname</tabstop>
<tabstop>lineEdit_KeyId</tabstop>
<tabstop>lineEdit_GpgHash</tabstop>
<tabstop>lineEdit_GpgId</tabstop>
<tabstop>lineEdit_GpgName</tabstop>
<tabstop>radioButton_GpgId</tabstop> <tabstop>radioButton_GpgId</tabstop>
<tabstop>radioButton_Pseudo</tabstop> <tabstop>radioButton_Pseudo</tabstop>
<tabstop>buttonBox</tabstop> <tabstop>buttonBox</tabstop>

View file

@ -148,13 +148,13 @@ void GxsGroupDialog::initMode()
{ {
ui.buttonBox->setStandardButtons(QDialogButtonBox::Close); ui.buttonBox->setStandardButtons(QDialogButtonBox::Close);
} }
break; break;
//TODO case MODE_EDIT:
// case MODE_EDIT: {
// { ui.buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
// ui.createButton->setText(tr("Submit Changes")); ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Submit Group Changes"));
// } }
// break; break;
} }
} }
@ -320,14 +320,42 @@ void GxsGroupDialog::submitGroup()
break; break;
case MODE_EDIT: case MODE_EDIT:
{ {
/* TEMP: just close if down */
cancelDialog(); editGroup();
} }
break; break;
} }
} }
void GxsGroupDialog::editGroup()
{
std::cerr << "GxsGroupDialog::editGroup()" << std::endl;
QString name = misc::removeNewLine(ui.groupName->text());
uint32_t flags = GXS_SERV::FLAG_PRIVACY_PUBLIC;
if(name.isEmpty())
{
/* error message */
QMessageBox::warning(this, "RetroShare", tr("Please add a Name"), QMessageBox::Ok, QMessageBox::Ok);
return; //Don't add a empty name!!
}
uint32_t token;
RsGxsGroupUpdateMeta updateMeta(mGrpMeta.mGroupId);
updateMeta.setMetaUpdate(RsGxsGroupUpdateMeta::NAME, std::string(name.toUtf8()));
if (service_EditGroup(token, updateMeta))
{
// get the Queue to handle response.
if(mTokenQueue != NULL)
mTokenQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, GXSGROUP_NEWGROUPID);
}
close();
}
void GxsGroupDialog::createGroup() void GxsGroupDialog::createGroup()
{ {
std::cerr << "GxsGroupDialog::createGroup()"; std::cerr << "GxsGroupDialog::createGroup()";

View file

@ -163,13 +163,21 @@ protected:
void setUiText(UiType uiType, const QString &text); void setUiText(UiType uiType, const QString &text);
/*! /*!
* Main purpose is to help tansfer meta data to service * It is up to the service to do the actual group creation
* * Service can also modify initial meta going into group
* @param token This should be set to the token retrieved * @param token This should be set to the token retrieved
* @param meta The deriving GXS service should set their grp meta to this value * @param meta The deriving GXS service should set their grp meta to this value
*/ */
virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) = 0; virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) = 0;
/*!
* It is up to the service to do the actual group editing
* TODO: make pure virtual
* @param token This should be set to the token retrieved
* @param meta The deriving GXS service should set their grp meta to this value
*/
virtual bool service_EditGroup(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta) {}
/*! /*!
* This returns a group logo from the ui \n * This returns a group logo from the ui \n
* Should be calleld by deriving service * Should be calleld by deriving service
@ -202,6 +210,7 @@ private:
void setupVisibility(); void setupVisibility();
void clearForm(); void clearForm();
void createGroup(); void createGroup();
void editGroup();
void sendShareList(std::string forumId); void sendShareList(std::string forumId);
void loadNewGroupId(const uint32_t &token); void loadNewGroupId(const uint32_t &token);
@ -215,6 +224,8 @@ private:
uint32_t mReadonlyFlags; uint32_t mReadonlyFlags;
uint32_t mDefaultsFlags; uint32_t mDefaultsFlags;
protected:
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::GxsGroupDialog ui; Ui::GxsGroupDialog ui;
}; };

View file

@ -67,6 +67,17 @@ bool GxsIdChooser::MakeIdDesc(const RsGxsId &id, QString &desc)
if (found) if (found)
{ {
desc = QString::fromUtf8(details.mNickname.c_str()); desc = QString::fromUtf8(details.mNickname.c_str());
std::list<RsRecognTag>::iterator it;
for(it = details.mRecognTags.begin(); it != details.mRecognTags.end(); it++)
{
desc += " (";
desc += QString::number(it->tag_class);
desc += ":";
desc += QString::number(it->tag_type);
desc += ")";
}
if (details.mPgpLinked) if (details.mPgpLinked)
{ {
desc += " (PGP) ["; desc += " (PGP) [";

View file

@ -71,6 +71,16 @@ static bool MakeIdDesc(const RsGxsId &id, QString &str)
str = QString::fromUtf8(details.mNickname.c_str()); str = QString::fromUtf8(details.mNickname.c_str());
std::list<RsRecognTag>::iterator it;
for(it = details.mRecognTags.begin(); it != details.mRecognTags.end(); it++)
{
str += " (";
str += QString::number(it->tag_class);
str += ":";
str += QString::number(it->tag_type);
str += ")";
}
bool addCode = true; bool addCode = true;
if (details.mPgpLinked) if (details.mPgpLinked)
{ {

View file

@ -45,6 +45,17 @@ static bool MakeIdDesc(const RsGxsId &id, QString &str)
str = QString::fromUtf8(details.mNickname.c_str()); str = QString::fromUtf8(details.mNickname.c_str());
std::list<RsRecognTag>::iterator it;
for(it = details.mRecognTags.begin(); it != details.mRecognTags.end(); it++)
{
str += " (";
str += QString::number(it->tag_class);
str += ":";
str += QString::number(it->tag_type);
str += ")";
}
bool addCode = true; bool addCode = true;
if (details.mPgpLinked) if (details.mPgpLinked)
{ {

View file

@ -52,6 +52,13 @@ const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC
GXS_GROUP_DEFAULTS_COMMENTS_NO | GXS_GROUP_DEFAULTS_COMMENTS_NO |
0); 0);
const uint32_t ForumEditEnabledFlags = ( GXS_GROUP_FLAGS_ICON |
GXS_GROUP_FLAGS_DESCRIPTION |
0);
const uint32_t ForumEditDefaultsFlags = 0;
GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent) GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent)
:GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent) :GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent)
{ {
@ -88,8 +95,17 @@ bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMeta
// Specific Function. // Specific Function.
RsGxsForumGroup grp; RsGxsForumGroup grp;
grp.mMeta = meta; grp.mMeta = meta;
//grp.mDescription = std::string(desc.toUtf8()); grp.mDescription = std::string(ui.groupDesc->toPlainText().toUtf8());
rsGxsForums->createGroup(token, grp); rsGxsForums->createGroup(token, grp);
return true; return true;
} }
bool GxsForumGroupDialog::service_EditGroup(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta)
{
RsGxsForumGroup grp;
grp.mDescription = std::string(ui.groupDesc->toPlainText().toUtf8());
rsGxsForums->updateGroup(token, updateMeta, grp);
return true;
}

View file

@ -37,6 +37,7 @@ protected:
virtual void initUi(); virtual void initUi();
virtual QPixmap serviceImage(); virtual QPixmap serviceImage();
virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta);
virtual bool service_EditGroup(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta);
}; };
#endif #endif

View file

@ -193,8 +193,10 @@ macx {
gxs { gxs {
LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a
LIBS += ../../../lib/libsqlcipher.a LIBS += ../../../lib/libsqlcipher.a
#LIBS += -lsqlite3 #LIBS += -lsqlite3
} }