From a6851b63dccc735d7c271d7ca89357f1a1af9f8c Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 23 Oct 2015 22:53:00 -0400 Subject: [PATCH 01/19] renamed old flags into indices in rsgenexchange.cc. Fixed up duplicate constants between GxsGroupDialog and rsgxsflags.h --- libretroshare/src/gxs/rsgenexchange.cc | 82 +++++++++++------- libretroshare/src/gxs/rsgenexchange.h | 5 +- libretroshare/src/gxs/rsgxsdata.h | 2 +- libretroshare/src/retroshare/rsgxsflags.h | 83 +++++++------------ retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 64 +++++++------- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 10 +-- .../src/gui/gxsforums/GxsForumGroupDialog.cpp | 4 +- 7 files changed, 129 insertions(+), 121 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index e7ae496f9..4ed5ed154 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -49,9 +49,15 @@ #define PRIV_GRP_OFFSET 16 #define GRP_OPTIONS_OFFSET 24 +/** authentication key indices. Used to store them in a map **/ + +static const uint32_t INDEX_AUTHEN_IDENTITY = 0x00000010; // identity +static const uint32_t INDEX_AUTHEN_PUBLISH = 0x00000020; // publish key +static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key + #define GXS_MASK "GXS_MASK_HACK" -//#define GEN_EXCH_DEBUG 1 +#define GEN_EXCH_DEBUG 1 #define MSG_CLEANUP_PERIOD 60*5 // 5 minutes #define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes @@ -416,7 +422,7 @@ uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKe bool ok = GxsSecurity::getSignature(allGrpData, allGrpDataLen, privAdminKey, adminSign); // add admin sign to grpMeta - meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign; + meta->signSet.keySignSet[INDEX_AUTHEN_ADMIN] = adminSign; RsTlvBinaryData grpData(mServType); grpData.setBinData(allGrpData, allGrpDataLen); @@ -494,7 +500,7 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin id_ret = SIGN_FAIL; } - signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign; + signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; } else { @@ -609,12 +615,12 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar // private publish key publishKey = &(mit->second); - RsTlvKeySignature publishSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + RsTlvKeySignature publishSign = signSet.keySignSet[INDEX_AUTHEN_PUBLISH]; publishSignSuccess = GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, *publishKey, publishSign); //place signature in msg meta - signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = publishSign; + signSet.keySignSet[INDEX_AUTHEN_PUBLISH] = publishSign; }else { std::cerr << "RsGenExchange::createMsgSignatures()"; @@ -653,7 +659,7 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar id_ret = SIGN_FAIL; } - signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign; + signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; } else { @@ -763,7 +769,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg) } } -int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet) +int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uint32_t& signFlag, RsTlvSecurityKeySet& grpKeySet) { bool needIdentitySign = false; bool needPublishSign = false; @@ -796,12 +802,16 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu if ((checkAuthenFlag(pos, author_flag)) || (!msg->metaData->mAuthorId.isNull())) needIdentitySign = true; +#ifdef GEN_EXCH_DEBUG + std::cerr << "Validate message: msgId=" << msg->msgId << ", grpId=" << msg->grpId << " grpFlags=" << std::hex << grpFlag << std::dec + << ". Need publish=" << needPublishSign << ", needIdentitySign=" << needIdentitySign ; +#endif RsGxsMsgMetaData& metaData = *(msg->metaData); if(needPublishSign) { - RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_PUBLISH]; std::map& keys = grpKeySet.keys; std::map::iterator mit = keys.begin(); @@ -849,31 +859,36 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu bool haveKey = mGixs->haveKey(metaData.mAuthorId); if(haveKey) - { + { - RsTlvSecurityKey authorKey; - bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ; + RsTlvSecurityKey authorKey; + bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ; - if (auth_key_fetched) - { + if (auth_key_fetched) + { + RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY]; + idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); + mGixs->timeStampKey(metaData.mAuthorId) ; + } + else + { + std::cerr << "RsGenExchange::validateMsg()"; + std::cerr << " ERROR Cannot Retrieve AUTHOR KEY for Message Validation"; + std::cerr << std::endl; + idValidate = false; + } - RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY]; - idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); - mGixs->timeStampKey(metaData.mAuthorId) ; - } - else - { - std::cerr << "RsGenExchange::validateMsg()"; - std::cerr << " ERROR Cannot Retrieve AUTHOR KEY for Message Validation"; - std::cerr << std::endl; - idValidate = false; - } - - }else +// if(signFlag & GXS_SERV:: + } + else { std::list peers; peers.push_back(msg->PeerId()); mGixs->requestKey(metaData.mAuthorId, peers); + +#ifdef GEN_EXCH_DEBUG + std::cerr << ", Key missing. Retry later." << std::endl; +#endif return VALIDATE_FAIL_TRY_LATER; } } @@ -890,6 +905,10 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu idValidate = true; } +#ifdef GEN_EXCH_DEBUG + std::cerr << ", publish val=" << publishValidate << ", idValidate=" << idValidate << ". Result=" << (publishValidate && idValidate) << std::endl; +#endif + if(publishValidate && idValidate) return VALIDATE_SUCCESS; else @@ -930,7 +949,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp) if (auth_key_fetched) { - RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY]; + RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY]; idValidate = GxsSecurity::validateNxsGrp(*grp, sign, authorKey); mGixs->timeStampKey(metaData.mAuthorId) ; @@ -2530,9 +2549,12 @@ void RsGenExchange::processRecvdMessages() if(mit != grpMetas.end()) { RsGxsGrpMetaData* grpMeta = mit->second; - validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys); + validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, grpMeta->keys); + #ifdef GEN_EXCH_DEBUG - std::cerr << " message validation result: " << validateReturn << std::endl; + std::cerr << " grpMeta.mSignFlags: " << std::hex << grpMeta->mSignFlags << std::dec << std::endl; + std::cerr << " grpMeta.mAuthFlags: " << std::hex << grpMeta->mAuthenFlags << std::dec << std::endl; + std::cerr << " message validation result: " << (int)validateReturn << std::endl; #endif } @@ -2821,7 +2843,7 @@ void RsGenExchange::performUpdateValidation() bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const { std::map& signSet = newGrp.metaData->signSet.keySignSet; - std::map::iterator mit = signSet.find(GXS_SERV::FLAG_AUTHEN_ADMIN); + std::map::iterator mit = signSet.find(INDEX_AUTHEN_ADMIN); if(mit == signSet.end()) { diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index ba59dcaac..3266a348e 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -739,12 +739,13 @@ private: /*! * Attempts to validate msg signatures * @param msg message to be validated - * @param grpFlag the flag for the group the message belongs to + * @param grpFlag the distribution flag for the group the message belongs to + * @param grpFlag the signature flag for the group the message belongs to * @param grpKeySet the key set user has for the message's group * @return VALIDATE_SUCCESS for success, VALIDATE_FAIL for fail, * VALIDATE_ID_SIGN_NOT_AVAIL for Id sign key not avail (but requested) */ - int validateMsg(RsNxsMsg* msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet); + int validateMsg(RsNxsMsg* msg, const uint32_t& grpFlag, const uint32_t &signFlag, RsTlvSecurityKeySet& grpKeySet); /*! * Attempts to validate group signatures diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 9829b8bd6..2bc2bd1bc 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -52,7 +52,7 @@ public: RsGxsGroupId mGroupId; RsGxsGroupId mOrigGrpId; std::string mGroupName; - uint32_t mGroupFlags; + uint32_t mGroupFlags; // GXS_SERV::FLAG_PRIVACY_RESTRICTED | GXS_SERV::FLAG_PRIVACY_PRIVATE | GXS_SERV::FLAG_PRIVACY_PUBLIC uint32_t mPublishTs; uint32_t mSignFlags; RsGxsId mAuthorId; diff --git a/libretroshare/src/retroshare/rsgxsflags.h b/libretroshare/src/retroshare/rsgxsflags.h index a7cc27ee4..7b3bc6a9d 100644 --- a/libretroshare/src/retroshare/rsgxsflags.h +++ b/libretroshare/src/retroshare/rsgxsflags.h @@ -18,48 +18,35 @@ namespace GXS_SERV { /** START privacy **/ - static const uint32_t FLAG_PRIVACY_MASK = 0x0000000f; - - // pub key encrypted - static const uint32_t FLAG_PRIVACY_PRIVATE = 0x00000001; - - // publish private key needed to publish - static const uint32_t FLAG_PRIVACY_RESTRICTED = 0x00000002; - - // anyone can publish, publish key pair not needed - static const uint32_t FLAG_PRIVACY_PUBLIC = 0x00000004; + static const uint32_t FLAG_PRIVACY_MASK = 0x0000000f; + static const uint32_t FLAG_PRIVACY_PRIVATE = 0x00000001; // pub key encrypted + static const uint32_t FLAG_PRIVACY_RESTRICTED = 0x00000002; // publish private key needed to publish + static const uint32_t FLAG_PRIVACY_PUBLIC = 0x00000004; // anyone can publish, publish key pair not needed /** END privacy **/ - /** START authentication **/ - - static const uint32_t FLAG_AUTHEN_MASK = 0x000000f0; - - // identity - static const uint32_t FLAG_AUTHEN_IDENTITY = 0x000000010; - - // publish key - static const uint32_t FLAG_AUTHEN_PUBLISH = 0x000000020; - - // admin key - static const uint32_t FLAG_AUTHEN_ADMIN = 0x00000040; - - // pgp sign identity - static const uint32_t FLAG_AUTHEN_PGP_IDENTITY = 0x00000080; - /** END authentication **/ + + /** START author authentication flags **/ + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_MASK = 0x0000ff00; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_NONE = 0x00000000; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG = 0x00000100; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_MASK = 0x000000ff; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED = 0x00000001; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED = 0x00000002; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_THREADHEAD = 0x00000004; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_NONEREQ = 0x00000008; + /** START msg authentication flags **/ - static const uint8_t MSG_AUTHEN_MASK = 0x0f; - - static const uint8_t MSG_AUTHEN_ROOT_PUBLISH_SIGN = 0x01; - + static const uint8_t MSG_AUTHEN_MASK = 0x0f; + static const uint8_t MSG_AUTHEN_ROOT_PUBLISH_SIGN = 0x01; static const uint8_t MSG_AUTHEN_CHILD_PUBLISH_SIGN = 0x02; - - static const uint8_t MSG_AUTHEN_ROOT_AUTHOR_SIGN = 0x04; - - static const uint8_t MSG_AUTHEN_CHILD_AUTHOR_SIGN = 0x08; + static const uint8_t MSG_AUTHEN_ROOT_AUTHOR_SIGN = 0x04; + static const uint8_t MSG_AUTHEN_CHILD_AUTHOR_SIGN = 0x08; /** END msg authentication flags **/ @@ -71,12 +58,9 @@ namespace GXS_SERV { /** START Subscription Flags. (LOCAL) **/ - static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x01; - - static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x02; - - static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x04; - + static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x01; + static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x02; + static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x04; static const uint32_t GROUP_SUBSCRIBE_NOT_SUBSCRIBED = 0x08; /*! @@ -95,17 +79,12 @@ namespace GXS_SERV { * * NOTE: RsGxsCommentService uses 0x000f0000. */ - static const uint32_t GXS_MSG_STATUS_GEN_MASK = 0x0000ffff; - + static const uint32_t GXS_MSG_STATUS_GEN_MASK = 0x0000ffff; static const uint32_t GXS_MSG_STATUS_UNPROCESSED = 0x00000001; - - static const uint32_t GXS_MSG_STATUS_GUI_UNREAD = 0x00000002; - - static const uint32_t GXS_MSG_STATUS_GUI_NEW = 0x00000004; - - static const uint32_t GXS_MSG_STATUS_KEEP = 0x00000008; - - static const uint32_t GXS_MSG_STATUS_DELETE = 0x000000020; + static const uint32_t GXS_MSG_STATUS_GUI_UNREAD = 0x00000002; + static const uint32_t GXS_MSG_STATUS_GUI_NEW = 0x00000004; + static const uint32_t GXS_MSG_STATUS_KEEP = 0x00000008; + static const uint32_t GXS_MSG_STATUS_DELETE = 0x00000020; /** END GXS Msg status flags **/ @@ -124,9 +103,9 @@ namespace GXS_SERV { #define IS_MSG_UNREAD(status) (status & GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD) #define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) -#define IS_GROUP_PUBLISHER(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) +#define IS_GROUP_PUBLISHER(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) #define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) -#define IS_GROUP_NOT_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED) +#define IS_GROUP_NOT_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED) #define IS_MSG_UNPROCESSED(status) (status & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 19b315164..955020117 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -37,18 +37,24 @@ #include // Control of Publish Signatures. -#define RSGXS_GROUP_SIGN_PUBLISH_MASK 0x000000ff -#define RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED 0x00000001 -#define RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED 0x00000002 -#define RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD 0x00000004 -#define RSGXS_GROUP_SIGN_PUBLISH_NONEREQ 0x00000008 +// +// These are now defined in rsgxsflags.h +// +// #define FLAG_GROUP_SIGN_PUBLISH_MASK 0x000000ff +// #define FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED 0x00000001 +// #define FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED 0x00000002 +// #define FLAG_GROUP_SIGN_PUBLISH_THREADHEAD 0x00000004 +// #define FLAG_GROUP_SIGN_PUBLISH_NONEREQ 0x00000008 -// Author Signature. -#define RSGXS_GROUP_SIGN_AUTHOR_MASK 0x0000ff00 -#define RSGXS_GROUP_SIGN_AUTHOR_GPG 0x00000100 -#define RSGXS_GROUP_SIGN_AUTHOR_REQUIRED 0x00000200 -#define RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN 0x00000400 -#define RSGXS_GROUP_SIGN_AUTHOR_NONE 0x00000800 +// // Author Signature. +// +// These are now defined in rsgxsflags.h +// +// #define FLAG_AUTHOR_AUTHENTICATION_MASK 0x0000ff00 +// #define FLAG_AUTHOR_AUTHENTICATION_NONE 0x00000000 +// #define FLAG_AUTHOR_AUTHENTICATION_GPG 0x00000100 +// #define FLAG_AUTHOR_AUTHENTICATION_REQUIRED 0x00000200 +// #define FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN 0x00000400 #define GXSGROUP_NEWGROUPID 1 #define GXSGROUP_LOADGROUP 2 @@ -576,54 +582,54 @@ uint32_t GxsGroupDialog::getGroupSignFlags() /* grab from the ui options -> */ uint32_t signFlags = 0; if (ui.publish_encrypt->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED; + signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED; } else if (ui.publish_required->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED; + signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED; } else if (ui.publish_threads->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD; + signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD; } else { // publish_open (default). - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_NONEREQ; + signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ; } // Author Signature. if (ui.personal_pgp->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_GPG; + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG; } else if (ui.personal_required->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_REQUIRED; + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; } else if (ui.personal_ifnopub->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN; + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN; } else { // shouldn't allow this one. - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_NONE; + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_NONE; } return signFlags; } void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) { - if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED) { + if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED) { ui.publish_encrypt->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED) { + } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED) { ui.publish_required->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) { + } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) { ui.publish_threads->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_NONEREQ) { + } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ) { ui.publish_open->setChecked(true); } - if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_GPG) { + if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) { ui.personal_pgp->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_REQUIRED) { + } else if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED) { ui.personal_required->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN) { + } else if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN) { ui.personal_ifnopub->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_NONE) { + } else if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_NONE) { // Its the same... but not quite. //ui.personal_noifpub->setChecked(); } /* guess at comments */ - if ((signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) && - (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN)) + if ((signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) && + (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN)) { ui.comments_allowed->setChecked(true); ui.comments_allowed_3->setChecked(true); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index ab93a2038..1029ccedd 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -69,8 +69,8 @@ public: /*** Default flags are used to determine privacy of group, signatures required *** *** whether publish or id and whether comments are allowed or not ***/ -#define GXS_GROUP_DEFAULTS_DISTRIB_MASK 0x0000000f -#define GXS_GROUP_DEFAULTS_PUBLISH_MASK 0x000000f0 +#define GXS_GROUP_DEFAULTS_DISTRIB_MASK 0x0000000f +#define GXS_GROUP_DEFAULTS_PUBLISH_MASK 0x000000f0 #define GXS_GROUP_DEFAULTS_PERSONAL_MASK 0x00000f00 #define GXS_GROUP_DEFAULTS_COMMENTS_MASK 0x0000f000 @@ -78,16 +78,16 @@ public: #define GXS_GROUP_DEFAULTS_DISTRIB_GROUP 0x00000002 #define GXS_GROUP_DEFAULTS_DISTRIB_LOCAL 0x00000004 -#define GXS_GROUP_DEFAULTS_PUBLISH_OPEN 0x00000010 +#define GXS_GROUP_DEFAULTS_PUBLISH_OPEN 0x00000010 #define GXS_GROUP_DEFAULTS_PUBLISH_THREADS 0x00000020 #define GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED 0x00000040 #define GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED 0x00000080 -#define GXS_GROUP_DEFAULTS_PERSONAL_PGP 0x00000100 +#define GXS_GROUP_DEFAULTS_PERSONAL_PGP 0x00000100 #define GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED 0x00000200 #define GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB 0x00000400 -#define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000 +#define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000 #define GXS_GROUP_DEFAULTS_COMMENTS_NO 0x00002000 /*! diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp index 41f138e20..88a2c93e5 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp @@ -33,7 +33,7 @@ const uint32_t ForumCreateEnabledFlags = ( GXS_GROUP_FLAGS_DISTRIBUTION | // GXS_GROUP_FLAGS_PUBLISHSIGN | GXS_GROUP_FLAGS_SHAREKEYS | - // GXS_GROUP_FLAGS_PERSONALSIGN | + GXS_GROUP_FLAGS_PERSONALSIGN | // GXS_GROUP_FLAGS_COMMENTS | 0); @@ -46,7 +46,7 @@ const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | - //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + //GXS_GROUP_DEFAULTS_PERSONAL_PGP | GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | From febd348d243f7abc104dd55649ac8d681212644a Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 24 Oct 2015 00:22:55 -0400 Subject: [PATCH 02/19] added GUI support for non anon forums. Changed serialisation of GxsGroupMetaData so that mSignFlags is serialised in place of mAuthenFlag, which is not used anyway --- libretroshare/src/gxs/rsgenexchange.cc | 4 ++- libretroshare/src/gxs/rsgxsdata.cc | 4 +-- libretroshare/src/retroshare/rsgxsflags.h | 2 ++ retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 30 ++++++++++-------- .../gui/gxsforums/GxsForumThreadWidget.cpp | 5 +++ .../src/gui/gxsforums/GxsForumThreadWidget.h | 1 + .../src/gui/gxsforums/GxsForumsDialog.cpp | 7 ++-- retroshare-gui/src/gui/images.qrc | 1 + .../src/gui/images/konv_message3.png | Bin 0 -> 1658 bytes 9 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 retroshare-gui/src/gui/images/konv_message3.png diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 4ed5ed154..a52cc17a0 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -49,7 +49,9 @@ #define PRIV_GRP_OFFSET 16 #define GRP_OPTIONS_OFFSET 24 -/** authentication key indices. Used to store them in a map **/ +// Authentication key indices. Used to store them in a map +// these where originally flags, but used as indexes. Still, we need +// to keep their old values to ensure backward compatibility. static const uint32_t INDEX_AUTHEN_IDENTITY = 0x00000010; // identity static const uint32_t INDEX_AUTHEN_PUBLISH = 0x00000020; // publish key diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index 36ae1f155..763a61957 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -122,7 +122,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) ok &= setRawUInt32(data, tlvsize, &offset, mGroupFlags); ok &= setRawUInt32(data, tlvsize, &offset, mPublishTs); ok &= setRawUInt32(data, tlvsize, &offset, mCircleType); - ok &= setRawUInt32(data, tlvsize, &offset, mAuthenFlags); + ok &= setRawUInt32(data, tlvsize, &offset, mSignFlags); ok &= mAuthorId.serialise(data, tlvsize, offset); ok &= SetTlvString(data, tlvsize, &offset, 0, mServiceString); ok &= mCircleId.serialise(data, tlvsize, offset); @@ -153,7 +153,7 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize) ok &= getRawUInt32(data, pktsize, &offset, &mGroupFlags); ok &= getRawUInt32(data, pktsize, &offset, &mPublishTs); ok &= getRawUInt32(data, pktsize, &offset, &mCircleType); - ok &= getRawUInt32(data, pktsize, &offset, &mAuthenFlags); + ok &= getRawUInt32(data, pktsize, &offset, &mSignFlags); ok &= mAuthorId.deserialise(data, pktsize, offset); ok &= GetTlvString(data, pktsize, &offset, 0, mServiceString); ok &= mCircleId.deserialise(data, pktsize, offset); diff --git a/libretroshare/src/retroshare/rsgxsflags.h b/libretroshare/src/retroshare/rsgxsflags.h index 7b3bc6a9d..d330a1199 100644 --- a/libretroshare/src/retroshare/rsgxsflags.h +++ b/libretroshare/src/retroshare/rsgxsflags.h @@ -102,6 +102,8 @@ namespace GXS_SERV { #define IS_MSG_NEW(status) (status & GXS_SERV::GXS_MSG_STATUS_GUI_NEW) #define IS_MSG_UNREAD(status) (status & GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD) +#define IS_GROUP_PGP_AUTHED(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) + #define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) #define IS_GROUP_PUBLISHER(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) #define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 955020117..2fac8685f 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -129,6 +129,10 @@ void GxsGroupDialog::init() ui.groupDesc->setPlaceholderText(tr("Set a descriptive description here")); + ui.personal_ifnopub->hide() ; + ui.personal_required->hide() ; + ui.personal_required->setChecked(true) ; // this is always true + initMode(); } @@ -592,15 +596,15 @@ uint32_t GxsGroupDialog::getGroupSignFlags() } // Author Signature. - if (ui.personal_pgp->isChecked()) { + if (ui.personal_pgp->isChecked()) signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG; - } else if (ui.personal_required->isChecked()) { + + if (ui.personal_required->isChecked()) signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; - } else if (ui.personal_ifnopub->isChecked()) { + + if (ui.personal_ifnopub->isChecked()) signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN; - } else { // shouldn't allow this one. - signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_NONE; - } + return signFlags; } @@ -616,17 +620,15 @@ void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) ui.publish_open->setChecked(true); } - if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) { + if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) ui.personal_pgp->setChecked(true); - } else if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED) { + + if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED) ui.personal_required->setChecked(true); - } else if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN) { + + if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN) ui.personal_ifnopub->setChecked(true); - } else if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_NONE) { - // Its the same... but not quite. - //ui.personal_noifpub->setChecked(); - } - + /* guess at comments */ if ((signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) && (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN)) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index e51527860..1b6ee480f 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -733,12 +733,16 @@ void GxsForumThreadWidget::insertGroupData() const RsGxsForumGroup& group = tw->mForumGroup; tw->mSubscribeFlags = group.mMeta.mSubscribeFlags; + tw->mSignFlags = group.mMeta.mSignFlags; tw->ui->forumName->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str())); + QString anon_allowed_str = (IS_GROUP_PGP_AUTHED(tw->mSignFlags))?tr("No"):tr("Yes") ; + tw->mForumDescription = QString("%1: \t%2
").arg(tr("Forum name"), QString::fromUtf8( group.mMeta.mGroupName.c_str())); tw->mForumDescription += QString("%1: \t%2
").arg(tr("Subscribers")).arg(group.mMeta.mPop); tw->mForumDescription += QString("%1: \t%2
").arg(tr("Posts (at neighbor nodes)")).arg(group.mMeta.mVisibleMsgCount); tw->mForumDescription += QString("%1: \t%2
").arg(tr("Author"), author); + tw->mForumDescription += QString("%1: \t%2
").arg(tr("Anonymous post allowed")).arg(anon_allowed_str); tw->mForumDescription += QString("%1:

%2").arg(tr("Description"), QString::fromUtf8(group.mDescription.c_str())); tw->ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(tw->mSubscribeFlags)); @@ -1800,6 +1804,7 @@ bool GxsForumThreadWidget::filterItem(QTreeWidgetItem *item, const QString &text void GxsForumThreadWidget::requestGroupData() { mSubscribeFlags = 0; + mSignFlags = 0; mForumDescription.clear(); mTokenQueue->cancelActiveRequestTokens(mTokenTypeGroupData); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 311024f07..374e0aa5d 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -147,6 +147,7 @@ private: RsGxsForumGroup mForumGroup; QString mForumDescription; int mSubscribeFlags; + int mSignFlags; bool mInProcessSettings; bool mInMsgAsReadUnread; int mLastViewType; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 6fefb0c34..26e4bf4b1 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -178,8 +178,9 @@ void GxsForumsDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, groupItemInfo.description = descriptionIt.value(); } - if (IS_GROUP_ADMIN(groupInfo.mSubscribeFlags)) { - groupItemInfo.icon = QIcon(":images/konv_message2.png"); - } + if (IS_GROUP_ADMIN(groupInfo.mSubscribeFlags)) + groupItemInfo.icon = QIcon(":images/konv_message2.png"); + else if (IS_GROUP_PGP_AUTHED(groupInfo.mSignFlags)) + groupItemInfo.icon = QIcon(":images/konv_message3.png"); } diff --git a/retroshare-gui/src/gui/images.qrc b/retroshare-gui/src/gui/images.qrc index de22823e7..2d26956be 100644 --- a/retroshare-gui/src/gui/images.qrc +++ b/retroshare-gui/src/gui/images.qrc @@ -316,6 +316,7 @@ images/konversation16.png images/konversation128.png images/konv_message2.png + images/konv_message3.png images/konv_message64.png images/konversation64.png images/forums_new.png diff --git a/retroshare-gui/src/gui/images/konv_message3.png b/retroshare-gui/src/gui/images/konv_message3.png new file mode 100644 index 0000000000000000000000000000000000000000..40280bb50856b55f31559824309ef32e612cde8c GIT binary patch literal 1658 zcmV-=28H>FP)0b000McNliru-wGH52rLNZJ2?OV1_wz* zK~z}7#g}bt97h?)e>1bUzW6n9Qye=EcA7MHI+H7{U5i3fCr(0~vwgOA_jY!M z4`(|*+ee(bD37$-o!w`j|9_r&US@=~mTM`_2l*+HNwokU1J(cHe!C zkjSLg08j0%Pkv^9%Y($F%VgwXty!RJSlosyT_PKCWaQQG;Ke^a20WQdrp*-zBr>Tj zz@I+f{LtE48+I_Erxpb;M3o#{Hj2wQ*+Pz=4gcydz`k5EeW@aWL?+dOk%4?()Tv*-PKjsNod2X1SruR9m>=2pBgr<-oRP^Jl>7E zOv|%VJpKLwV};$5OQv6*TL-?-6l>hIsrE)D^yDJubp>Ea(GSq4e7dgh*eLt`!5;zJoH?`qR!_rijD@31Uh6_OPiOT8I$E}|<-WwC-kQ=L zQpz&#ZLD2SzdyJ&kx8}Ac;NneS=ZL+u3{?kF1zde6dhx2)W&N8fka}3W%SZ0>zmuz zzUOA*@p#2}kW%6W0n!!oa({N*J44`8t??Gd!qM5ltNEA9{Vlz8CA$_F?(grXv$Jza z0Xb1D;5u&E`*B@ZK%hri$&?9Z-So-&BwaUkEvwOlk;a_#@ON8;5S%Ms;5~1Mi+W^6 zWtWr4qy(^ORFC7$ala69`JGNGzINAFc=(O4Gu)gf5Fwbdcyb&-meRw=H^F80Vevz0 zwbzfbZ%caggC;*>8`>yfu1&?wZ`39&q%{KN9}Q5e(NYV z{B<44hL7{$oewPNioWk-jF?vqB}&?J($NQJ2pj|Qz$$>q8boA?#5Aah(9Aq*3W0|| z8N*<)ZHDZ+K~4s5^UDLj;gG zbQDThl#nP@#XYA|JoeBx`Svr9^IA_9P#9ArvIdMo8%<;lMn}lgmX3ToL-BJIIxc6H z5(?LGk%)JVZ??R#>xeg(fS8Vj-ZCc&fs_(kFx2J-9)wO~wi#bA_39LK?N z9Hf-K(dO37&4>FI+Yej^^Z~8QO+g_f5-|%bl)#aWE*8CqGh1JLw&IQ`d1CLEs)YNK zd^CF1fWm@M0wokmDO5}$ltd{7#s=P`_rS^RFTPN5PngK0>h5Sr4Zar)HNE5ivn*w# zln5aZR$zrKTOy@Y>6?<^Op{Owp-S%}Pyf4+AK#ZtrceFPgUQyKt^=2fqfLX}yC9}> zRVkEEv#}tAKnMX6tY8|XG{!02MNHsG2V+c8PlP|7$QQmbe>Xf!AdyKqYh%ry-BH*5 zxG|<97raeO#ZbZ$Q!7wHVhD+>2$50DaoiG^1gp3V?h2%?ew|sQL;wH) literal 0 HcmV?d00001 From e0db78f71a08157e3433d135aa6860f0b49cf3f5 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 24 Oct 2015 10:41:31 -0400 Subject: [PATCH 03/19] reject messages signed by non PGP-signed IDs from non anonymous forums --- libretroshare/src/gxs/rsgenexchange.cc | 23 ++++++++++++++++++++++- libretroshare/src/gxs/rsgixs.h | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index a52cc17a0..a568d2bdb 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -880,7 +880,28 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin idValidate = false; } -// if(signFlag & GXS_SERV:: + if(idValidate && (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)) + { + // get key data and check that the key is actually PGP-linked. If not, reject the post. + + RsIdentityDetails details ; + + if(!mGixs->getIdDetails(metaData.mAuthorId,details)) + { + // the key cannot ke reached, although it's in cache. Weird situation. + idValidate = false; + std::cerr << "RsGenExchange::validateMsg(): cannot get key data for ID=" << metaData.mAuthorId << ", although it's supposed to be already in cache. Cannot validate." << std::endl; + idValidate = false ; + } + + if(!details.mPgpLinked) + { +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because key is not PGP linked and the group requires it." << std::endl; +#endif + idValidate = false ; + } + } } else { diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index 19590baa9..cf13a77d3 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -166,6 +166,7 @@ public: */ virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages. + virtual bool getIdDetails(const RsGxsId& id, RsIdentityDetails& details) = 0 ; // Proxy function so that we get p3Identity info from Gxs #ifdef SUSPENDED #endif From 8ea97711e8d440e667c341ed6a1e7227c3abb9dc Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 24 Oct 2015 12:48:17 -0400 Subject: [PATCH 04/19] added new flag to GxsIdChooser to force non anonymous ids. Disabled by default --- .../src/gui/Identity/IdEditDialog.cpp | 14 ++++++-- .../src/gui/Identity/IdEditDialog.h | 2 +- retroshare-gui/src/gui/gxs/GxsIdChooser.cpp | 34 +++++++++++++++++-- retroshare-gui/src/gui/gxs/GxsIdChooser.h | 7 ++-- .../src/gui/gxsforums/CreateGxsForumMsg.cpp | 14 +++++++- 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index e4bbc7662..9cd8c60e9 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -113,10 +113,16 @@ void IdEditDialog::changeAvatar() } } -void IdEditDialog::setupNewId(bool pseudo) +void IdEditDialog::setupNewId(bool pseudo,bool enable_anon) { setWindowTitle(tr("New identity")); + if(pseudo && !enable_anon) + { + std::cerr << "IdEditDialog::setupNewId: Error. Cannot init with pseudo-anonymous id when anon ids are disabled." << std::endl; + pseudo = false ; + } + mIsNew = true; mGroupId.clear(); @@ -139,7 +145,11 @@ void IdEditDialog::setupNewId(bool pseudo) ui->frame_Tags->setHidden(true); ui->radioButton_GpgId->setEnabled(true); - ui->radioButton_Pseudo->setEnabled(true); + + if(enable_anon) + ui->radioButton_Pseudo->setEnabled(true); + else + ui->radioButton_Pseudo->setEnabled(false); setAvatar(QPixmap()); diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.h b/retroshare-gui/src/gui/Identity/IdEditDialog.h index d46cd7de3..d97aee090 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.h +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.h @@ -45,7 +45,7 @@ public: IdEditDialog(QWidget *parent = 0); ~IdEditDialog(); - void setupNewId(bool pseudo); + void setupNewId(bool pseudo, bool enable_anon = true); void setupExistingId(const RsGxsGroupId &keyId); void enforceNoAnonIds() ; diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp index 7fb83f131..526c7fe43 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp @@ -27,6 +27,7 @@ #include "gui/Identity/IdEditDialog.h" #include +#include #include #include @@ -138,7 +139,6 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail switch (type) { case GXS_ID_DETAILS_TYPE_EMPTY: case GXS_ID_DETAILS_TYPE_FAILED: -// icons = ; break; case GXS_ID_DETAILS_TYPE_LOADING: @@ -154,11 +154,39 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail chooser->setItemData(index, (type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE); chooser->setItemIcon(index, icons.empty() ? QIcon() : icons[0]); + std::cerr << "ID=" << details.mId << ", chooser->flags()=" << chooser->flags() << ", pgpLinked=" << details.mPgpLinked ; + + if((chooser->flags() & IDCHOOSER_NON_ANONYMOUS) && !(details.mPgpLinked)) + { + std::cerr << " - disabling ID - entry = " << index << std::endl; + chooser->setEntryEnabled(index,false) ; + } + std::cerr << std::endl; + chooser->model()->sort(0); chooser->blockSignals(false) ; } +void GxsIdChooser::setEntryEnabled(int indx,bool enabled) +{ + bool disable = !enabled ; + + QSortFilterProxyModel* model = qobject_cast(QComboBox::model()); + //QStandardItem* item = model->item(index); + + QModelIndex ii = model->index(indx,0); + + // visually disable by greying out - works only if combobox has been painted already and palette returns the wanted color + //model->setFlags(ii,disable ? (model->flags(ii) & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled)) : (Qt::ItemIsSelectable|Qt::ItemIsEnabled)); + + uint32_t v = enabled?(1|32):(0); + + // clear item data in order to use default color + //model->setData(ii,disable ? (QComboBox::palette().color(QPalette::Disabled, QPalette::Text)) : QVariant(), Qt::TextColorRole); + model->setData(ii,QVariant(v),Qt::UserRole-1) ; +} + void GxsIdChooser::loadPrivateIds() { if (mFirstLoad) { @@ -217,6 +245,8 @@ void GxsIdChooser::loadPrivateIds() addItem(QIcon(":/images/identity/identity_create_32.png"), str, id); setItemData(count() - 1, QString("%1_%2").arg(TYPE_CREATE_ID).arg(str), ROLE_SORT); setItemData(count() - 1, TYPE_CREATE_ID, ROLE_TYPE); + + } setDefaultItem(); emit idsLoaded(); @@ -299,7 +329,7 @@ void GxsIdChooser::indexActivated(int index) int type = itemData(index, ROLE_TYPE).toInt(); if (type == TYPE_CREATE_ID) { IdEditDialog dlg(this); - dlg.setupNewId(false); + dlg.setupNewId(false, !(mFlags & IDCHOOSER_NON_ANONYMOUS)); if (dlg.exec() == QDialog::Accepted) { setDefaultId(RsGxsId(dlg.groupId())); } diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.h b/retroshare-gui/src/gui/gxs/GxsIdChooser.h index e785fb227..98c33a052 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.h +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.h @@ -37,6 +37,7 @@ class RsGxsUpdateBroadcastBase; #define IDCHOOSER_ID_REQUIRED 0x0001 #define IDCHOOSER_ANON_DEFAULT 0x0002 #define IDCHOOSER_NO_CREATE 0x0004 +#define IDCHOOSER_NON_ANONYMOUS 0x0008 class GxsIdChooser : public QComboBox { @@ -48,6 +49,7 @@ public: virtual ~GxsIdChooser(); void setFlags(uint32_t flags) ; + uint32_t flags() const { return mFlags ; } enum ChosenId_Ret {None, KnowId, UnKnowId, NoId} ; void loadIds(uint32_t chooserFlags, const RsGxsId &defId); @@ -56,6 +58,7 @@ public: bool setChosenId(const RsGxsId &gxsId); ChosenId_Ret getChosenId(RsGxsId &gxsId); + void setEntryEnabled(int index, bool enabled); signals: // emitted after first load of own ids void idsLoaded(); @@ -71,13 +74,13 @@ private slots: private: void loadPrivateIds(); - void setDefaultItem(); + void setDefaultItem(); uint32_t mFlags; RsGxsId mDefaultId; bool mFirstLoad; - RsGxsUpdateBroadcastBase *mBase; + RsGxsUpdateBroadcastBase *mBase; }; #endif diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index d9e83111a..bacf1349f 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -121,7 +121,12 @@ void CreateGxsForumMsg::newMsg() mForumMetaLoaded = false; /* fill in the available OwnIds for signing */ - ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); + std::cerr << "Initing ID chooser. Sign flags = " << std::hex << mForumMeta.mSignFlags << std::dec << std::endl; + + if(mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) + ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS, RsGxsId()); + else + ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); if (mForumId.isNull()) { mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false); @@ -203,6 +208,13 @@ void CreateGxsForumMsg::loadFormInformation() std::cerr << "CreateGxsForumMsg::loadMsgInformation() Data Available!"; std::cerr << std::endl; + std::cerr << "CreateGxsForumMsg::loadMsgInformation() using signFlags=" << std::hex << mForumMeta.mSignFlags << std::dec << std::endl; + + if(mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) + ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS) ; + else + ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED) ; + QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str()); QString subj; if (!mParentId.isNull()) From 7db3bb1c9b07ae88e50b99e463b1a62fb775e32d Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 24 Oct 2015 12:55:49 -0400 Subject: [PATCH 05/19] disabled debug info in GenExchange --- libretroshare/src/gxs/rsgenexchange.cc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index a568d2bdb..775e6c309 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -59,7 +59,7 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key #define GXS_MASK "GXS_MASK_HACK" -#define GEN_EXCH_DEBUG 1 +//#define GEN_EXCH_DEBUG 1 #define MSG_CLEANUP_PERIOD 60*5 // 5 minutes #define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes @@ -470,8 +470,10 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin if ((!grpMeta.mAuthorId.isNull()) || checkAuthenFlag(pos, author_flag)) { needIdentitySign = true; +#ifdef GEN_EXCH_DEBUG std::cerr << "Needs Identity sign! (Service Flags)"; std::cerr << std::endl; +#endif } if (needIdentitySign) @@ -508,19 +510,23 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin { mGixs->requestPrivateKey(grpMeta.mAuthorId); +#ifdef GEN_EXCH_DEBUG std::cerr << "RsGenExchange::createGroupSignatures(): "; std::cerr << " ERROR AUTHOR KEY: " << grpMeta.mAuthorId << " is not Cached / available for Message Signing\n"; std::cerr << "RsGenExchange::createGroupSignatures(): Requestiong AUTHOR KEY"; std::cerr << std::endl; +#endif id_ret = SIGN_FAIL_TRY_LATER; } } else { +#ifdef GEN_EXCH_DEBUG std::cerr << "RsGenExchange::createGroupSignatures()"; std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl; +#endif id_ret = SIGN_FAIL; } } @@ -540,8 +546,10 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar bool publishSignSuccess = false; +#ifdef GEN_EXCH_DEBUG std::cerr << "RsGenExchange::createMsgSignatures() for Msg.mMsgName: " << msgMeta.mMsgName; std::cerr << std::endl; +#endif // publish signature is determined by whether group is public or not @@ -576,23 +584,29 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar if (checkAuthenFlag(pos, publish_flag)) { needPublishSign = true; +#ifdef GEN_EXCH_DEBUG std::cerr << "Needs Publish sign! (Service Flags)"; std::cerr << std::endl; +#endif } // Check required permissions, and allow them to sign it - if they want too - as well! if (checkAuthenFlag(pos, author_flag)) { needIdentitySign = true; +#ifdef GEN_EXCH_DEBUG std::cerr << "Needs Identity sign! (Service Flags)"; std::cerr << std::endl; +#endif } if (!msgMeta.mAuthorId.isNull()) { needIdentitySign = true; +#ifdef GEN_EXCH_DEBUG std::cerr << "Needs Identity sign! (AuthorId Exists)"; std::cerr << std::endl; +#endif } if(needPublishSign) @@ -667,19 +681,23 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar { mGixs->requestPrivateKey(msgMeta.mAuthorId); +#ifdef GEN_EXCH_DEBUG std::cerr << "RsGenExchange::createMsgSignatures(): "; std::cerr << " ERROR AUTHOR KEY: " << msgMeta.mAuthorId << " is not Cached / available for Message Signing\n"; std::cerr << "RsGenExchange::createMsgSignatures(): Requestiong AUTHOR KEY"; std::cerr << std::endl; +#endif id_ret = SIGN_FAIL_TRY_LATER; } } else { +#ifdef GEN_EXCH_DEBUG std::cerr << "RsGenExchange::createMsgSignatures()"; std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl; +#endif id_ret = SIGN_FAIL; } } @@ -953,8 +971,10 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp) if ((!metaData.mAuthorId.isNull()) || checkAuthenFlag(pos, author_flag)) { needIdentitySign = true; +#ifdef GEN_EXCH_DEBUG std::cerr << "Needs Identity sign! (Service Flags)"; std::cerr << std::endl; +#endif } if(needIdentitySign) @@ -1805,8 +1825,10 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC grpMeta = mit->second; if (!grpMeta) { +#ifdef GEN_EXCH_DEBUG std::cerr << "RsGenExchange::processGrpMask() Ignore update for not existing grp id " << grpId.toStdString(); std::cerr << std::endl; +#endif return false; } ok = true; @@ -2945,7 +2967,9 @@ void RsGenExchange::removeDeleteExistingMessages( RsGeneralDataService::MsgStore { const RsGxsMessageId::std_vector& msgIds = msgIdReq[cit2->second->mGroupId]; +#ifdef GEN_EXCH_DEBUG std::cerr << " grpid=" << cit2->second->mGroupId << ", msgid=" << cit2->second->mMsgId ; +#endif // Avoid storing messages that are already in the database, as well as messages that are too old (or generally do not pass the database storage test) // From 47dd70fbe88ed0ef70b374e2957b44a115fe92c5 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 25 Oct 2015 17:16:16 -0400 Subject: [PATCH 06/19] added non selective tracking for GXS messages --- libretroshare/src/grouter/groutermatrix.cc | 45 +++++++- libretroshare/src/grouter/groutermatrix.h | 15 ++- libretroshare/src/grouter/groutertypes.h | 9 +- libretroshare/src/grouter/p3grouter.cc | 9 ++ libretroshare/src/grouter/p3grouter.h | 2 +- libretroshare/src/gxs/rsdataservice.cc | 100 +++++++++--------- libretroshare/src/gxs/rsgenexchange.cc | 54 ++++++---- libretroshare/src/gxs/rsgenexchange.h | 2 +- libretroshare/src/gxs/rsgxsdata.h | 1 - libretroshare/src/retroshare/rsgrouter.h | 1 + .../src/retroshare/rsgxsifacetypes.h | 1 + libretroshare/src/serialiser/rsgxsitems.cc | 1 - .../gui/gxsforums/GxsForumThreadWidget.cpp | 3 + 13 files changed, 160 insertions(+), 83 deletions(-) diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index 1401f6a6c..df8f18315 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -27,13 +27,56 @@ #include "groutermatrix.h" #include "grouteritems.h" -//#define ROUTING_MATRIX_DEBUG +#define ROUTING_MATRIX_DEBUG GRouterMatrix::GRouterMatrix() { _proba_need_updating = true ; } +bool GRouterMatrix::addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& source_friend) +{ + time_t now = time(NULL) ; + uint32_t fid = getFriendId(source_friend) ; + + RoutingTrackEntry rte ; + + rte.friend_id = fid ; + rte.time_stamp = now ; + + _tracking_clues[mid] = rte ; +#ifdef ROUTING_MATRIX_DEBUG + std::cerr << "GRouterMatrix::addTrackingInfo(): Added clue mid=" << mid << ", from " << source_friend << " ID=" << fid << std::endl; +#endif + return true ; +} + +bool GRouterMatrix::cleanUp() +{ + // remove all tracking entries that have become too old. + +#ifdef ROUTING_MATRIX_DEBUG + std::cerr << "GRouterMatrix::cleanup()" << std::endl; +#endif + time_t now = time(NULL) ; + + for(std::map::iterator it(_tracking_clues.begin());it!=_tracking_clues.end();) + if(it->second.time_stamp + RS_GROUTER_MAX_KEEP_TRACKING_CLUES < now) + { +#ifdef ROUTING_MATRIX_DEBUG + std::cerr << " removing old entry msgId=" << it->first << ", from id " << it->second.friend_id << ", obtained " << (now - it->second.time_stamp) << " secs ago." << std::endl; +#endif + std::map::iterator tmp(it) ; + ++tmp ; + _tracking_clues.erase(it) ; + it=tmp ; + } + else + ++it ; + + return true ; +} + bool GRouterMatrix::addRoutingClue(const GRouterKeyId& key_id,const RsPeerId& source_friend,float weight) { // 1 - get the friend index. diff --git a/libretroshare/src/grouter/groutermatrix.h b/libretroshare/src/grouter/groutermatrix.h index 4c9ddee95..755c5333f 100644 --- a/libretroshare/src/grouter/groutermatrix.h +++ b/libretroshare/src/grouter/groutermatrix.h @@ -42,6 +42,12 @@ struct RoutingMatrixHitEntry time_t time_stamp ; }; +struct RoutingTrackEntry +{ + uint32_t friend_id ; // not the full key. Gets too big otherwise! + time_t time_stamp ; +}; + class GRouterMatrix { public: @@ -61,10 +67,13 @@ class GRouterMatrix // Record one routing clue. The events can possibly be merged in time buckets. // bool addRoutingClue(const GRouterKeyId& id,const RsPeerId& source_friend,float weight) ; + bool addTrackingInfo(const RsGxsMessageId& id,const RsPeerId& source_friend) ; bool saveList(std::list& items) ; bool loadList(std::list& items) ; + bool cleanUp() ; + // Dump info in terminal. // void debugDump() const ; @@ -81,8 +90,9 @@ class GRouterMatrix // List of events received and computed routing probabilities // - std::map > _routing_clues ; // received routing clues. Should be saved. - std::map > _time_combined_hits ; // hit matrix after time-convolution filter + std::map > _routing_clues ; // received routing clues. Should be saved. + std::map > _time_combined_hits ; // hit matrix after time-convolution filter + std::map _tracking_clues ; // who provided the most recent messages // This is used to avoid re-computing probas when new events have been received. // @@ -93,6 +103,5 @@ class GRouterMatrix // std::map _friend_indices ; // index for each friend to lookup in the routing matrix Not saved. std::vector _reverse_friend_indices ;// SSLid corresponding to each friend index. Saved. - }; diff --git a/libretroshare/src/grouter/groutertypes.h b/libretroshare/src/grouter/groutertypes.h index 0a3900421..756c75783 100644 --- a/libretroshare/src/grouter/groutertypes.h +++ b/libretroshare/src/grouter/groutertypes.h @@ -37,9 +37,10 @@ class RsGRouterSignedReceiptItem ; static const uint16_t GROUTER_CLIENT_ID_MESSAGES = 0x1001 ; -static const uint32_t RS_GROUTER_MATRIX_MAX_HIT_ENTRIES = 10 ; // max number of clues to store -static const uint32_t RS_GROUTER_MATRIX_MIN_TIME_BETWEEN_HITS = 60 ; // can be set to up to half the publish time interval. Prevents flooding routes. -static const uint32_t RS_GROUTER_MIN_CONFIG_SAVE_PERIOD = 5 ; // at most save config every 5 seconds +static const uint32_t RS_GROUTER_MATRIX_MAX_HIT_ENTRIES = 10 ; // max number of clues to store +static const uint32_t RS_GROUTER_MATRIX_MIN_TIME_BETWEEN_HITS = 60 ; // can be set to up to half the publish time interval. Prevents flooding routes. +static const uint32_t RS_GROUTER_MIN_CONFIG_SAVE_PERIOD = 5 ; // at most save config every 5 seconds +static const uint32_t RS_GROUTER_MAX_KEEP_TRACKING_CLUES = 86400*10 ; // max time for which we keep record of tracking info: 10 days. static const float RS_GROUTER_BASE_WEIGHT_ROUTED_MSG = 1.0f ; // base contribution of routed message clue to routing matrix static const float RS_GROUTER_BASE_WEIGHT_GXS_PACKET = 0.1f ; // base contribution of GXS message to routing matrix @@ -56,7 +57,7 @@ static const uint32_t MAX_INACTIVE_DATA_PIPE_DELAY = 300 ; // cl static const time_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 10 ; // Output everything static const time_t RS_GROUTER_AUTOWASH_PERIOD = 10 ; // Autowash every minute. Not a costly operation. -static const time_t RS_GROUTER_MATRIX_UPDATE_PERIOD = 1 *10 ; // Check for key advertising every 10 minutes +static const time_t RS_GROUTER_MATRIX_UPDATE_PERIOD = 60*10 ; // Check for key advertising every 10 minutes static const uint32_t GROUTER_ITEM_MAX_CACHE_KEEP_TIME = 2*86400 ; // Cached items are kept for 48 hours at most. static const uint32_t RS_GROUTER_DATA_STATUS_UNKNOWN = 0x0000 ; // unknown. Unused. diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index 421d2c97c..d14460bb4 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -252,6 +252,7 @@ int p3GRouter::tick() _last_matrix_update_time = now ; _routing_matrix.updateRoutingProbabilities() ; // This should be locked. + _routing_matrix.cleanUp() ; // This should be locked. } #ifdef GROUTER_DEBUG @@ -1698,6 +1699,14 @@ bool p3GRouter::locked_getClientAndServiceId(const TurtleFileHash& hash, const R return true ; } +void p3GRouter::addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& peer_id) +{ + RS_STACK_MUTEX(grMtx) ; +#ifdef GROUTER_DEBUG + grouter_debug() << "Received new routing clue for key " << id << " from peer " << peer_id << std::endl; +#endif + _routing_matrix.addTrackingInfo(mid,peer_id) ; +} void p3GRouter::addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id) { RS_STACK_MUTEX(grMtx) ; diff --git a/libretroshare/src/grouter/p3grouter.h b/libretroshare/src/grouter/p3grouter.h index 2d8f744cd..900e4fe68 100644 --- a/libretroshare/src/grouter/p3grouter.h +++ b/libretroshare/src/grouter/p3grouter.h @@ -130,6 +130,7 @@ public: //===================================================// virtual void addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id) ; + virtual void addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& peer_id) ; //===================================================// // Client/server request services // @@ -300,7 +301,6 @@ private: // GRouterMatrix _routing_matrix ; - // Stores the keys which identify the router's node. For each key, a structure holds: // - the client service // - flags diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 01af6efd3..26c7a205d 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -49,19 +49,19 @@ #define MSG_INDEX_GRPID std::string("INDEX_MESSAGES_GRPID") // generic -#define KEY_NXS_DATA std::string("nxsData") -#define KEY_NXS_DATA_LEN std::string("nxsDataLen") -#define KEY_NXS_IDENTITY std::string("identity") -#define KEY_GRP_ID std::string("grpId") -#define KEY_ORIG_GRP_ID std::string("origGrpId") -#define KEY_PARENT_GRP_ID std::string("parentGrpId") -#define KEY_SIGN_SET std::string("signSet") -#define KEY_TIME_STAMP std::string("timeStamp") -#define KEY_NXS_FLAGS std::string("flags") -#define KEY_NXS_META std::string("meta") +#define KEY_NXS_DATA std::string("nxsData") +#define KEY_NXS_DATA_LEN std::string("nxsDataLen") +#define KEY_NXS_IDENTITY std::string("identity") +#define KEY_GRP_ID std::string("grpId") +#define KEY_ORIG_GRP_ID std::string("origGrpId") +#define KEY_PARENT_GRP_ID std::string("parentGrpId") +#define KEY_SIGN_SET std::string("signSet") +#define KEY_TIME_STAMP std::string("timeStamp") +#define KEY_NXS_FLAGS std::string("flags") +#define KEY_NXS_META std::string("meta") #define KEY_NXS_SERV_STRING std::string("serv_str") -#define KEY_NXS_HASH std::string("hash") -#define KEY_RECV_TS std::string("recv_time_stamp") +#define KEY_NXS_HASH std::string("hash") +#define KEY_RECV_TS std::string("recv_time_stamp") // remove later #define KEY_NXS_FILE_OLD std::string("nxsFile") @@ -94,8 +94,8 @@ #define KEY_MSG_NAME std::string("msgName") // msg local -#define KEY_MSG_STATUS std::string("msgStatus") -#define KEY_CHILD_TS std::string("childTs") +#define KEY_MSG_STATUS std::string("msgStatus") +#define KEY_CHILD_TS std::string("childTs") // database release columns #define KEY_DATABASE_RELEASE_ID std::string("id") @@ -129,22 +129,22 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d initialise(isNewDatabase); // for retrieving msg meta - mColMsgMeta_GrpId = addColumn(mMsgMetaColumns, KEY_GRP_ID); - mColMsgMeta_TimeStamp = addColumn(mMsgMetaColumns, KEY_TIME_STAMP); - mColMsgMeta_NxsFlags = addColumn(mMsgMetaColumns, KEY_NXS_FLAGS); - mColMsgMeta_SignSet = addColumn(mMsgMetaColumns, KEY_SIGN_SET); - mColMsgMeta_NxsIdentity = addColumn(mMsgMetaColumns, KEY_NXS_IDENTITY); - mColMsgMeta_NxsHash = addColumn(mMsgMetaColumns, KEY_NXS_HASH); - mColMsgMeta_MsgId = addColumn(mMsgMetaColumns, KEY_MSG_ID); - mColMsgMeta_OrigMsgId = addColumn(mMsgMetaColumns, KEY_ORIG_MSG_ID); - mColMsgMeta_MsgStatus = addColumn(mMsgMetaColumns, KEY_MSG_STATUS); - mColMsgMeta_ChildTs = addColumn(mMsgMetaColumns, KEY_CHILD_TS); - mColMsgMeta_MsgParentId = addColumn(mMsgMetaColumns, KEY_MSG_PARENT_ID); - mColMsgMeta_MsgThreadId = addColumn(mMsgMetaColumns, KEY_MSG_THREAD_ID); - mColMsgMeta_Name = addColumn(mMsgMetaColumns, KEY_MSG_NAME); + mColMsgMeta_GrpId = addColumn(mMsgMetaColumns, KEY_GRP_ID); + mColMsgMeta_TimeStamp = addColumn(mMsgMetaColumns, KEY_TIME_STAMP); + mColMsgMeta_NxsFlags = addColumn(mMsgMetaColumns, KEY_NXS_FLAGS); + mColMsgMeta_SignSet = addColumn(mMsgMetaColumns, KEY_SIGN_SET); + mColMsgMeta_NxsIdentity = addColumn(mMsgMetaColumns, KEY_NXS_IDENTITY); + mColMsgMeta_NxsHash = addColumn(mMsgMetaColumns, KEY_NXS_HASH); + mColMsgMeta_MsgId = addColumn(mMsgMetaColumns, KEY_MSG_ID); + mColMsgMeta_OrigMsgId = addColumn(mMsgMetaColumns, KEY_ORIG_MSG_ID); + mColMsgMeta_MsgStatus = addColumn(mMsgMetaColumns, KEY_MSG_STATUS); + mColMsgMeta_ChildTs = addColumn(mMsgMetaColumns, KEY_CHILD_TS); + mColMsgMeta_MsgParentId = addColumn(mMsgMetaColumns, KEY_MSG_PARENT_ID); + mColMsgMeta_MsgThreadId = addColumn(mMsgMetaColumns, KEY_MSG_THREAD_ID); + mColMsgMeta_Name = addColumn(mMsgMetaColumns, KEY_MSG_NAME); mColMsgMeta_NxsServString = addColumn(mMsgMetaColumns, KEY_NXS_SERV_STRING); - mColMsgMeta_RecvTs = addColumn(mMsgMetaColumns, KEY_RECV_TS); - mColMsgMeta_NxsDataLen = addColumn(mMsgMetaColumns, KEY_NXS_DATA_LEN); + mColMsgMeta_RecvTs = addColumn(mMsgMetaColumns, KEY_RECV_TS); + mColMsgMeta_NxsDataLen = addColumn(mMsgMetaColumns, KEY_NXS_DATA_LEN); // for retrieving actual data mColMsg_GrpId = addColumn(mMsgColumns, KEY_GRP_ID); @@ -153,31 +153,31 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d mColMsg_MsgId = addColumn(mMsgColumns, KEY_MSG_ID); // for retrieving grp meta data - mColGrpMeta_GrpId = addColumn(mGrpMetaColumns, KEY_GRP_ID); - mColGrpMeta_TimeStamp = addColumn(mGrpMetaColumns, KEY_TIME_STAMP); - mColGrpMeta_NxsFlags = addColumn(mGrpMetaColumns, KEY_NXS_FLAGS); + mColGrpMeta_GrpId = addColumn(mGrpMetaColumns, KEY_GRP_ID); + mColGrpMeta_TimeStamp = addColumn(mGrpMetaColumns, KEY_TIME_STAMP); + mColGrpMeta_NxsFlags = addColumn(mGrpMetaColumns, KEY_NXS_FLAGS); // mColGrpMeta_SignSet = addColumn(mGrpMetaColumns, KEY_SIGN_SET); mColGrpMeta_NxsIdentity = addColumn(mGrpMetaColumns, KEY_NXS_IDENTITY); - mColGrpMeta_NxsHash = addColumn(mGrpMetaColumns, KEY_NXS_HASH); - mColGrpMeta_KeySet = addColumn(mGrpMetaColumns, KEY_KEY_SET); - mColGrpMeta_SubscrFlag = addColumn(mGrpMetaColumns, KEY_GRP_SUBCR_FLAG); - mColGrpMeta_Pop = addColumn(mGrpMetaColumns, KEY_GRP_POP); - mColGrpMeta_MsgCount = addColumn(mGrpMetaColumns, KEY_MSG_COUNT); - mColGrpMeta_Status = addColumn(mGrpMetaColumns, KEY_GRP_STATUS); - mColGrpMeta_Name = addColumn(mGrpMetaColumns, KEY_GRP_NAME); - mColGrpMeta_LastPost = addColumn(mGrpMetaColumns, KEY_GRP_LAST_POST); - mColGrpMeta_OrigGrpId = addColumn(mGrpMetaColumns, KEY_ORIG_GRP_ID); - mColGrpMeta_ServString = addColumn(mGrpMetaColumns, KEY_NXS_SERV_STRING); - mColGrpMeta_SignFlags = addColumn(mGrpMetaColumns, KEY_GRP_SIGN_FLAGS); - mColGrpMeta_CircleId = addColumn(mGrpMetaColumns, KEY_GRP_CIRCLE_ID); - mColGrpMeta_CircleType = addColumn(mGrpMetaColumns, KEY_GRP_CIRCLE_TYPE); + mColGrpMeta_NxsHash = addColumn(mGrpMetaColumns, KEY_NXS_HASH); + mColGrpMeta_KeySet = addColumn(mGrpMetaColumns, KEY_KEY_SET); + mColGrpMeta_SubscrFlag = addColumn(mGrpMetaColumns, KEY_GRP_SUBCR_FLAG); + mColGrpMeta_Pop = addColumn(mGrpMetaColumns, KEY_GRP_POP); + mColGrpMeta_MsgCount = addColumn(mGrpMetaColumns, KEY_MSG_COUNT); + mColGrpMeta_Status = addColumn(mGrpMetaColumns, KEY_GRP_STATUS); + mColGrpMeta_Name = addColumn(mGrpMetaColumns, KEY_GRP_NAME); + mColGrpMeta_LastPost = addColumn(mGrpMetaColumns, KEY_GRP_LAST_POST); + mColGrpMeta_OrigGrpId = addColumn(mGrpMetaColumns, KEY_ORIG_GRP_ID); + mColGrpMeta_ServString = addColumn(mGrpMetaColumns, KEY_NXS_SERV_STRING); + mColGrpMeta_SignFlags = addColumn(mGrpMetaColumns, KEY_GRP_SIGN_FLAGS); + mColGrpMeta_CircleId = addColumn(mGrpMetaColumns, KEY_GRP_CIRCLE_ID); + mColGrpMeta_CircleType = addColumn(mGrpMetaColumns, KEY_GRP_CIRCLE_TYPE); mColGrpMeta_InternCircle = addColumn(mGrpMetaColumns, KEY_GRP_INTERNAL_CIRCLE); - mColGrpMeta_Originator = addColumn(mGrpMetaColumns, KEY_GRP_ORIGINATOR); + mColGrpMeta_Originator = addColumn(mGrpMetaColumns, KEY_GRP_ORIGINATOR); mColGrpMeta_AuthenFlags = addColumn(mGrpMetaColumns, KEY_GRP_AUTHEN_FLAGS); mColGrpMeta_ParentGrpId = addColumn(mGrpMetaColumns, KEY_PARENT_GRP_ID); - mColGrpMeta_RecvTs = addColumn(mGrpMetaColumns, KEY_RECV_TS); - mColGrpMeta_RepCutoff = addColumn(mGrpMetaColumns, KEY_GRP_REP_CUTOFF); - mColGrpMeta_NxsDataLen = addColumn(mGrpMetaColumns, KEY_NXS_DATA_LEN); + mColGrpMeta_RecvTs = addColumn(mGrpMetaColumns, KEY_RECV_TS); + mColGrpMeta_RepCutoff = addColumn(mGrpMetaColumns, KEY_GRP_REP_CUTOFF); + mColGrpMeta_NxsDataLen = addColumn(mGrpMetaColumns, KEY_NXS_DATA_LEN); // for retrieving actual grp data mColGrp_GrpId = addColumn(mGrpColumns, KEY_GRP_ID); @@ -620,7 +620,7 @@ RsGxsMsgMetaData* RsDataService::locked_getMsgMeta(RetroCursor &c) c.getString(mColMsgMeta_NxsHash, temp); msgMeta->mHash = RsFileHash(temp); msgMeta->recvTS = c.getInt32(mColMsgMeta_RecvTs); - + offset = 0; data = (char*)c.getData(mColMsgMeta_SignSet, data_len); msgMeta->signSet.GetTlv(data, data_len, &offset); diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 775e6c309..cef8ccd72 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -33,6 +33,7 @@ #include "retroshare/rsgxsflags.h" #include "retroshare/rsgxscircles.h" #include "retroshare/rsgrouter.h" +#include "retroshare/rspeers.h" #include "rsgixs.h" #include "rsgxsutil.h" #include "rsserver/p3face.h" @@ -2001,6 +2002,10 @@ void RsGenExchange::publishMsgs() msgId = msg->msgId; grpId = msg->grpId; msg->metaData->recvTS = time(NULL); + + mRoutingClues[msg->metaData->mAuthorId].insert(rsPeers->getOwnId()) ; + mTrackingClues.push_back(std::make_pair(msg->msgId,rsPeers->getOwnId())) ; + computeHash(msg->msg, msg->metaData->mHash); mDataAccess->addMsgData(msg); msgChangeMap[grpId].push_back(msgId); @@ -2134,13 +2139,18 @@ void RsGenExchange::processGroupUpdatePublish() void RsGenExchange::processRoutingClues() { - RS_STACK_MUTEX(mGenMtx) ; + RS_STACK_MUTEX(mGenMtx) ; for(std::map >::const_iterator it = mRoutingClues.begin();it!=mRoutingClues.end();++it) for(std::set::const_iterator it2(it->second.begin());it2!=it->second.end();++it2) - rsGRouter->addRoutingClue(GRouterKeyId(it->first),(*it2)) ; + rsGRouter->addRoutingClue(GRouterKeyId(it->first),(*it2) ) ; mRoutingClues.clear() ; + + for(std::list >::const_iterator it = mTrackingClues.begin();it!=mTrackingClues.end();++it) + rsGRouter->addTrackingInfo((*it).first,(*it).second) ; + + mTrackingClues.clear() ; } void RsGenExchange::processGroupDelete() { @@ -2604,32 +2614,34 @@ void RsGenExchange::processRecvdMessages() } if(validateReturn == VALIDATE_SUCCESS) - { - meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - msgs.insert(std::make_pair(msg, meta)); + { + meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; + msgs.insert(std::make_pair(msg, meta)); - std::vector &msgv = msgIds[msg->grpId]; - if (std::find(msgv.begin(), msgv.end(), msg->msgId) == msgv.end()) - { - msgv.push_back(msg->msgId); - } + std::vector &msgv = msgIds[msg->grpId]; + if (std::find(msgv.begin(), msgv.end(), msg->msgId) == msgv.end()) + { + msgv.push_back(msg->msgId); + } - NxsMsgPendingVect::iterator validated_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), - getMsgIdPair(*msg)); + NxsMsgPendingVect::iterator validated_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), + getMsgIdPair(*msg)); - if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry); + if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry); - computeHash(msg->msg, meta->mHash); - meta->recvTS = time(NULL); + computeHash(msg->msg, meta->mHash); + meta->recvTS = time(NULL); #ifdef GEN_EXCH_DEBUG - std::cerr << " new status flags: " << meta->mMsgStatus << std::endl; - std::cerr << " computed hash: " << meta->mHash << std::endl; - std::cerr << "Message received. Identity=" << msg->metaData->mAuthorId << ", from peer " << msg->PeerId() << std::endl; + std::cerr << " new status flags: " << meta->mMsgStatus << std::endl; + std::cerr << " computed hash: " << meta->mHash << std::endl; + std::cerr << "Message received. Identity=" << msg->metaData->mAuthorId << ", from peer " << msg->PeerId() << std::endl; #endif - if(!msg->metaData->mAuthorId.isNull()) - mRoutingClues[msg->metaData->mAuthorId].insert(msg->PeerId()) ; - } + if(!msg->metaData->mAuthorId.isNull()) + mRoutingClues[msg->metaData->mAuthorId].insert(msg->PeerId()) ; + + mTrackingClues.push_back(std::make_pair(msg->msgId,msg->PeerId())) ; + } } else { diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 3266a348e..1462b0285 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -863,7 +863,7 @@ private: std::vector mGroupDeletePublish; std::map > mRoutingClues ; - + std::list > mTrackingClues ; }; #endif // RSGENEXCHANGE_H diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 2bc2bd1bc..f80dbb862 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -123,7 +123,6 @@ public: uint32_t recvTS; RsFileHash mHash; bool validated; - }; diff --git a/libretroshare/src/retroshare/rsgrouter.h b/libretroshare/src/retroshare/rsgrouter.h index 8db40b194..7cb3d6a82 100644 --- a/libretroshare/src/retroshare/rsgrouter.h +++ b/libretroshare/src/retroshare/rsgrouter.h @@ -102,6 +102,7 @@ public: //===================================================// virtual void addRoutingClue(const GRouterKeyId& destination, const RsPeerId& source) =0; + virtual void addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& peer_id) =0; }; // To access the GRouter from anywhere diff --git a/libretroshare/src/retroshare/rsgxsifacetypes.h b/libretroshare/src/retroshare/rsgxsifacetypes.h index e4c5e6048..a8c794536 100644 --- a/libretroshare/src/retroshare/rsgxsifacetypes.h +++ b/libretroshare/src/retroshare/rsgxsifacetypes.h @@ -127,6 +127,7 @@ public: /// the first 16 bits for service, last 16 for GXS uint32_t mMsgStatus; + RsPeerId mProviderId ; time_t mChildTs; std::string mServiceString; // Service Specific Free-Form extra storage. diff --git a/libretroshare/src/serialiser/rsgxsitems.cc b/libretroshare/src/serialiser/rsgxsitems.cc index 2fc738cab..9971514ec 100644 --- a/libretroshare/src/serialiser/rsgxsitems.cc +++ b/libretroshare/src/serialiser/rsgxsitems.cc @@ -24,7 +24,6 @@ this->mPublishTs = rGxsMeta.mPublishTs; this->mThreadId = rGxsMeta.mThreadId; this->mServiceString = rGxsMeta.mServiceString; - } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 1b6ee480f..436e971c6 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -920,6 +920,9 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum // Set later with GxsIdRSTreeWidgetItem::setId item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_AUTHOR, QString::fromStdString(msg.mMeta.mAuthorId.toStdString())); + + // Show info about who passed on this message. + item->setToolTip(COLUMN_THREAD_TITLE,tr("This message was obtained from %1").arg(QString::fromStdString(msg.mMeta.mProviderId.toStdString()))); //#TODO #if 0 text = QString::fromUtf8(authorName.c_str()); From 3de29c589c120e4a25bc792067a10ae05cecbb94 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 25 Oct 2015 18:07:17 -0400 Subject: [PATCH 07/19] added load/save of message tracking info --- libretroshare/src/grouter/grouteritems.cc | 84 ++++++++++++++++++--- libretroshare/src/grouter/grouteritems.h | 46 ++++++++---- libretroshare/src/grouter/groutermatrix.cc | 85 ++++++++++++++-------- 3 files changed, 160 insertions(+), 55 deletions(-) diff --git a/libretroshare/src/grouter/grouteritems.cc b/libretroshare/src/grouter/grouteritems.cc index 14c3164c5..f7f01285f 100644 --- a/libretroshare/src/grouter/grouteritems.cc +++ b/libretroshare/src/grouter/grouteritems.cc @@ -45,17 +45,18 @@ RsItem *RsGRouterSerialiser::deserialise(void *data, uint32_t *pktsize) switch(getRsItemSubType(rstype)) { - case RS_PKT_SUBTYPE_GROUTER_DATA: return deserialise_RsGRouterGenericDataItem (data, *pktsize); - case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK: return deserialise_RsGRouterTransactionChunkItem(data, *pktsize); - case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN: return deserialise_RsGRouterTransactionAcknItem (data, *pktsize); - case RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT: return deserialise_RsGRouterSignedReceiptItem (data, *pktsize); - case RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES: return deserialise_RsGRouterMatrixCluesItem (data, *pktsize); - case RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST: return deserialise_RsGRouterMatrixFriendListItem(data, *pktsize); - case RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO: return deserialise_RsGRouterRoutingInfoItem (data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_DATA: return deserialise_RsGRouterGenericDataItem (data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK: return deserialise_RsGRouterTransactionChunkItem(data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN: return deserialise_RsGRouterTransactionAcknItem (data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT: return deserialise_RsGRouterSignedReceiptItem (data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES: return deserialise_RsGRouterMatrixCluesItem (data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK: return deserialise_RsGRouterMatrixTrackItem (data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST: return deserialise_RsGRouterMatrixFriendListItem(data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO: return deserialise_RsGRouterRoutingInfoItem (data, *pktsize); - default: - std::cerr << "RsGRouterSerialiser::deserialise(): Could not de-serialise item. SubPacket id = " << std::hex << getRsItemSubType(rstype) << " id = " << rstype << std::dec << std::endl; - return NULL; + default: + std::cerr << "RsGRouterSerialiser::deserialise(): Could not de-serialise item. SubPacket id = " << std::hex << getRsItemSubType(rstype) << " id = " << rstype << std::dec << std::endl; + return NULL; } return NULL; } @@ -269,6 +270,28 @@ RsGRouterMatrixFriendListItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixF return item; } + +RsGRouterMatrixTrackItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixTrackItem(void *data, uint32_t pktsize) const +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGRouterMatrixTrackItem *item = new RsGRouterMatrixTrackItem() ; + + ok &= getRawUInt32(data, pktsize, &offset, &item->provider_id) ; + ok &= item->message_id.deserialise(data,pktsize,offset) ; + ok &= getRawTimeT(data, pktsize, &offset, item->time_stamp) ; + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} RsGRouterMatrixCluesItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixCluesItem(void *data, uint32_t pktsize) const { uint32_t offset = 8; // skip the header @@ -559,6 +582,17 @@ uint32_t RsGRouterMatrixFriendListItem::serial_size() const return s ; } + +uint32_t RsGRouterMatrixTrackItem::serial_size() const +{ + uint32_t s = 8 ; // header + s += 8 ; // time_stamp + s += RsPeerId::SIZE_IN_BYTES; // provider_id + s += RsMessageId::SIZE_IN_BYTES; // message_id + + return s ; +} + uint32_t RsGRouterRoutingInfoItem::serial_size() const { uint32_t s = 8 ; // header @@ -637,6 +671,26 @@ bool RsGRouterMatrixCluesItem::serialise(void *data,uint32_t& size) const return ok; } +bool RsGRouterMatrixTrackItem::serialise(void *data,uint32_t& size) const +{ + uint32_t tlvsize,offset=0; + bool ok = true; + + if(!serialise_header(data,size,tlvsize,offset)) + return false ; + + ok &= setRawUInt32(data, tlvsize, &offset, provider_id) ; + ok &= message_id.serialise(data,tlvsize,offset) ; + ok &= setRawTimeT(data, tlvsize, &offset, time_stamp) ; + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsGRouterMatrixTrackItem::serialisedata() size error! " << std::endl; + } + + return ok; +} bool FriendTrialRecord::deserialise(void *data,uint32_t& offset,uint32_t size) { bool ok = true ; @@ -701,6 +755,7 @@ bool RsGRouterRoutingInfoItem::serialise(void *data,uint32_t& size) const // ------------------------------------- IO --------------------------------------- // // -----------------------------------------------------------------------------------// // + std::ostream& RsGRouterSignedReceiptItem::print(std::ostream& o, uint16_t) { o << "RsGRouterReceiptItem:" << std::endl ; @@ -746,6 +801,15 @@ std::ostream& RsGRouterRoutingInfoItem::print(std::ostream& o, uint16_t) return o ; } +std::ostream& RsGRouterMatrixTrackItem::print(std::ostream& o, uint16_t) +{ + o << "RsGRouterMatrixTrackItem:" << std::endl ; + o << " provider_id: " << provider_id << std::endl; + o << " message_id: " << message_id << std::endl; + o << " time_stamp: " << time_stamp << std::endl; + + return o ; +} std::ostream& RsGRouterMatrixCluesItem::print(std::ostream& o, uint16_t) { o << "RsGRouterMatrixCluesItem:" << std::endl ; diff --git a/libretroshare/src/grouter/grouteritems.h b/libretroshare/src/grouter/grouteritems.h index ea42eea61..9c3a2041b 100644 --- a/libretroshare/src/grouter/grouteritems.h +++ b/libretroshare/src/grouter/grouteritems.h @@ -33,20 +33,19 @@ #include "retroshare/rsgrouter.h" #include "groutermatrix.h" -const uint8_t RS_PKT_SUBTYPE_GROUTER_PUBLISH_KEY = 0x01 ; // used to publish a key -const uint8_t RS_PKT_SUBTYPE_GROUTER_ACK_deprecated = 0x03 ; // don't use! -const uint8_t RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT_deprecated = 0x04 ; // don't use! -const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA_deprecated = 0x05 ; // don't use! -const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA_deprecated2 = 0x06 ; // don't use! -const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA = 0x07 ; // used to send data to a destination (Signed by source) -const uint8_t RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT = 0x08 ; // long-distance acknowledgement of data received - -const uint8_t RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK = 0x10 ; // chunk of data. Used internally. -const uint8_t RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN = 0x11 ; // acknowledge for finished transaction. Not necessary, but increases fiability. - -const uint8_t RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES = 0x80 ; // item to save matrix clues -const uint8_t RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST = 0x82 ; // item to save friend lists -const uint8_t RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO = 0x93 ; // +const uint8_t RS_PKT_SUBTYPE_GROUTER_PUBLISH_KEY = 0x01 ; // used to publish a key +const uint8_t RS_PKT_SUBTYPE_GROUTER_ACK_deprecated = 0x03 ; // don't use! +const uint8_t RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT_deprecated = 0x04 ; // don't use! +const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA_deprecated = 0x05 ; // don't use! +const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA_deprecated2 = 0x06 ; // don't use! +const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA = 0x07 ; // used to send data to a destination (Signed by source) +const uint8_t RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT = 0x08 ; // long-distance acknowledgement of data received +const uint8_t RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK = 0x10 ; // chunk of data. Used internally. +const uint8_t RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN = 0x11 ; // acknowledge for finished transaction. Not necessary, but increases fiability. +const uint8_t RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES = 0x80 ; // item to save matrix clues +const uint8_t RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST = 0x82 ; // item to save friend lists +const uint8_t RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO = 0x93 ; // +const uint8_t RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK = 0x94 ; // item to save matrix track info const uint8_t QOS_PRIORITY_RS_GROUTER = 4 ; // relevant for items that travel through friends @@ -243,6 +242,24 @@ class RsGRouterMatrixCluesItem: public RsGRouterItem std::list clues ; }; +class RsGRouterMatrixTrackItem: public RsGRouterItem +{ + public: + RsGRouterMatrixTrackItem() : RsGRouterItem(RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK) + { setPriorityLevel(0) ; } // this item is never sent through the network + + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; + + virtual void clear() {} + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) ; + + // packet data + // + RsGxsMessageId message_id ; + uint32_t provider_id ; + time_t time_stamp ; +}; class RsGRouterMatrixFriendListItem: public RsGRouterItem { public: @@ -317,6 +334,7 @@ private: RsGRouterTransactionAcknItem *deserialise_RsGRouterTransactionAcknItem(void *data,uint32_t size) const ; RsGRouterSignedReceiptItem *deserialise_RsGRouterSignedReceiptItem(void *data,uint32_t size) const ; RsGRouterMatrixCluesItem *deserialise_RsGRouterMatrixCluesItem(void *data,uint32_t size) const ; + RsGRouterMatrixTrackItem *deserialise_RsGRouterMatrixTrackItem(void *data,uint32_t size) const ; RsGRouterMatrixFriendListItem *deserialise_RsGRouterMatrixFriendListItem(void *data,uint32_t size) const ; RsGRouterRoutingInfoItem *deserialise_RsGRouterRoutingInfoItem(void *data,uint32_t size) const ; }; diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index df8f18315..f92da9bc0 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -284,55 +284,78 @@ bool GRouterMatrix::saveList(std::list& items) std::cerr << " GRoutingMatrix::saveList()" << std::endl; #endif - RsGRouterMatrixFriendListItem *item = new RsGRouterMatrixFriendListItem ; + RsGRouterMatrixFriendListItem *item = new RsGRouterMatrixFriendListItem ; - item->reverse_friend_indices = _reverse_friend_indices ; - items.push_back(item) ; + item->reverse_friend_indices = _reverse_friend_indices ; + items.push_back(item) ; - for(std::map >::const_iterator it(_routing_clues.begin());it!=_routing_clues.end();++it) - { - RsGRouterMatrixCluesItem *item = new RsGRouterMatrixCluesItem ; + for(std::map >::const_iterator it(_routing_clues.begin());it!=_routing_clues.end();++it) + { + RsGRouterMatrixCluesItem *item = new RsGRouterMatrixCluesItem ; - item->destination_key = it->first ; - item->clues = it->second ; + item->destination_key = it->first ; + item->clues = it->second ; - items.push_back(item) ; - } + items.push_back(item) ; + } - return true ; + for(std::map::const_iterator it(_tracking_clues.begin());it!=_tracking_clues.end();++it) + { + RsGRouterMatrixTrackItem *item = new RsGRouterMatrixTrackItem ; + + item->provider_id = it->second.friend_id ; + item->time_stamp = it->second.time_stamp ; + item->message_id = it->first ; + + items.push_back(item) ; + } + + return true ; } bool GRouterMatrix::loadList(std::list& items) { - RsGRouterMatrixFriendListItem *itm1 = NULL ; - RsGRouterMatrixCluesItem *itm2 = NULL ; + RsGRouterMatrixFriendListItem *itm1 = NULL ; + RsGRouterMatrixCluesItem *itm2 = NULL ; + RsGRouterMatrixTrackItem *itm3 = NULL ; #ifdef ROUTING_MATRIX_DEBUG std::cerr << " GRoutingMatrix::loadList()" << std::endl; #endif - for(std::list::const_iterator it(items.begin());it!=items.end();++it) - { - if(NULL != (itm2 = dynamic_cast(*it))) - { + for(std::list::const_iterator it(items.begin());it!=items.end();++it) + { + if(NULL != (itm3 = dynamic_cast(*it))) + { #ifdef ROUTING_MATRIX_DEBUG - std::cerr << " initing routing clues." << std::endl; + std::cerr << " initing tracking clues." << std::endl; +#endif + RoutingTrackEntry rte ; + rte.friend_id = itm3->provider_id ; + rte.time_stamp = itm3->time_stamp ; + + _tracking_clues[itm3->message_id] = rte; + } + if(NULL != (itm2 = dynamic_cast(*it))) + { +#ifdef ROUTING_MATRIX_DEBUG + std::cerr << " initing routing clues." << std::endl; #endif - _routing_clues[itm2->destination_key] = itm2->clues ; - _proba_need_updating = true ; // notifies to re-compute all the info. - } - if(NULL != (itm1 = dynamic_cast(*it))) - { - _reverse_friend_indices = itm1->reverse_friend_indices ; - _friend_indices.clear() ; + _routing_clues[itm2->destination_key] = itm2->clues ; + _proba_need_updating = true ; // notifies to re-compute all the info. + } + if(NULL != (itm1 = dynamic_cast(*it))) + { + _reverse_friend_indices = itm1->reverse_friend_indices ; + _friend_indices.clear() ; - for(uint32_t i=0;i<_reverse_friend_indices.size();++i) - _friend_indices[_reverse_friend_indices[i]] = i ; + for(uint32_t i=0;i<_reverse_friend_indices.size();++i) + _friend_indices[_reverse_friend_indices[i]] = i ; - _proba_need_updating = true ; // notifies to re-compute all the info. - } - } + _proba_need_updating = true ; // notifies to re-compute all the info. + } + } - return true ; + return true ; } From 207e84d7193a4665eb0c752f6fab4947f0a77a77 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 25 Oct 2015 18:27:15 -0400 Subject: [PATCH 08/19] added new flag for msg tracking --- libretroshare/src/gxs/rsgenexchange.cc | 284 +++++++++++----------- libretroshare/src/retroshare/rsgxsflags.h | 11 +- 2 files changed, 149 insertions(+), 146 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index cef8ccd72..c3a455fe7 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -2517,206 +2517,208 @@ void RsGenExchange::computeHash(const RsTlvBinaryData& data, RsFileHash& hash) void RsGenExchange::processRecvdMessages() { - RS_STACK_MUTEX(mGenMtx) ; + RS_STACK_MUTEX(mGenMtx) ; #ifdef GEN_EXCH_DEBUG - if(!mMsgPendingValidate.empty()) - std::cerr << "processing received messages" << std::endl; + if(!mMsgPendingValidate.empty()) + std::cerr << "processing received messages" << std::endl; #endif - NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin(); + NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin(); #ifdef GEN_EXCH_DEBUG - if(!mMsgPendingValidate.empty()) - std::cerr << " pending validation" << std::endl; + if(!mMsgPendingValidate.empty()) + std::cerr << " pending validation" << std::endl; #endif - for(; pend_it != mMsgPendingValidate.end();) - { - GxsPendingItem& gpsi = *pend_it; + for(; pend_it != mMsgPendingValidate.end();) + { + GxsPendingItem& gpsi = *pend_it; #ifdef GEN_EXCH_DEBUG - std::cerr << " grp=" << gpsi.mId.first << ", msg=" << gpsi.mId.second << ", attempts=" << gpsi.mAttempts ; + std::cerr << " grp=" << gpsi.mId.first << ", msg=" << gpsi.mId.second << ", attempts=" << gpsi.mAttempts ; #endif - if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS) - { + if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS) + { #ifdef GEN_EXCH_DEBUG std::cerr << " = max! deleting." << std::endl; #endif - delete gpsi.mItem; - pend_it = mMsgPendingValidate.erase(pend_it); - } - else - { + delete gpsi.mItem; + pend_it = mMsgPendingValidate.erase(pend_it); + } + else + { #ifdef GEN_EXCH_DEBUG std::cerr << " movign to recvd." << std::endl; #endif - mReceivedMsgs.push_back(gpsi.mItem); - ++pend_it; - } - } + mReceivedMsgs.push_back(gpsi.mItem); + ++pend_it; + } + } - if(mReceivedMsgs.empty()) - return; + if(mReceivedMsgs.empty()) + return; - std::vector::iterator vit = mReceivedMsgs.begin(); - GxsMsgReq msgIds; - std::map msgs; + std::vector::iterator vit = mReceivedMsgs.begin(); + GxsMsgReq msgIds; + std::map msgs; - std::map grpMetas; + std::map grpMetas; - // coalesce group meta retrieval for performance - for(; vit != mReceivedMsgs.end(); ++vit) - { - RsNxsMsg* msg = *vit; - grpMetas.insert(std::make_pair(msg->grpId, (RsGxsGrpMetaData*)NULL)); - } + // coalesce group meta retrieval for performance + for(; vit != mReceivedMsgs.end(); ++vit) + { + RsNxsMsg* msg = *vit; + grpMetas.insert(std::make_pair(msg->grpId, (RsGxsGrpMetaData*)NULL)); + } - mDataStore->retrieveGxsGrpMetaData(grpMetas); + mDataStore->retrieveGxsGrpMetaData(grpMetas); #ifdef GEN_EXCH_DEBUG - std::cerr << " updating received messages:" << std::endl; + std::cerr << " updating received messages:" << std::endl; #endif - for(vit = mReceivedMsgs.begin(); vit != mReceivedMsgs.end(); ++vit) - { - RsNxsMsg* msg = *vit; - RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); + for(vit = mReceivedMsgs.begin(); vit != mReceivedMsgs.end(); ++vit) + { + RsNxsMsg* msg = *vit; + RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); - bool ok = false; + bool ok = false; - if(msg->meta.bin_len != 0) - ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len)); + if(msg->meta.bin_len != 0) + ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len)); - msg->metaData = meta; + msg->metaData = meta; #ifdef GEN_EXCH_DEBUG - std::cerr << " deserialised info: grp id=" << meta->mGroupId << ", msg id=" << meta->mMsgId ; + std::cerr << " deserialised info: grp id=" << meta->mGroupId << ", msg id=" << meta->mMsgId ; #endif - uint8_t validateReturn = VALIDATE_FAIL; + uint8_t validateReturn = VALIDATE_FAIL; - if(ok) - { - std::map::iterator mit = grpMetas.find(msg->grpId); + if(ok) + { + std::map::iterator mit = grpMetas.find(msg->grpId); #ifdef GEN_EXCH_DEBUG - std::cerr << " msg info : grp id=" << msg->grpId << ", msg id=" << msg->msgId << std::endl; + std::cerr << " msg info : grp id=" << msg->grpId << ", msg id=" << msg->msgId << std::endl; #endif + RsGxsGrpMetaData* grpMeta = NULL ; - // validate msg - if(mit != grpMetas.end()) - { - RsGxsGrpMetaData* grpMeta = mit->second; - validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, grpMeta->keys); - -#ifdef GEN_EXCH_DEBUG - std::cerr << " grpMeta.mSignFlags: " << std::hex << grpMeta->mSignFlags << std::dec << std::endl; - std::cerr << " grpMeta.mAuthFlags: " << std::hex << grpMeta->mAuthenFlags << std::dec << std::endl; - std::cerr << " message validation result: " << (int)validateReturn << std::endl; -#endif - } - - if(validateReturn == VALIDATE_SUCCESS) - { - meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - msgs.insert(std::make_pair(msg, meta)); - - std::vector &msgv = msgIds[msg->grpId]; - if (std::find(msgv.begin(), msgv.end(), msg->msgId) == msgv.end()) - { - msgv.push_back(msg->msgId); - } - - NxsMsgPendingVect::iterator validated_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), - getMsgIdPair(*msg)); - - if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry); - - computeHash(msg->msg, meta->mHash); - meta->recvTS = time(NULL); -#ifdef GEN_EXCH_DEBUG - std::cerr << " new status flags: " << meta->mMsgStatus << std::endl; - std::cerr << " computed hash: " << meta->mHash << std::endl; - std::cerr << "Message received. Identity=" << msg->metaData->mAuthorId << ", from peer " << msg->PeerId() << std::endl; -#endif - - if(!msg->metaData->mAuthorId.isNull()) - mRoutingClues[msg->metaData->mAuthorId].insert(msg->PeerId()) ; - - mTrackingClues.push_back(std::make_pair(msg->msgId,msg->PeerId())) ; - } - } - else - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " deserialisation failed!" <second; + validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, grpMeta->keys); #ifdef GEN_EXCH_DEBUG - std::cerr << "failed to deserialise incoming meta, msgId: " - << "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; + std::cerr << " grpMeta.mSignFlags: " << std::hex << grpMeta->mSignFlags << std::dec << std::endl; + std::cerr << " grpMeta.mAuthFlags: " << std::hex << grpMeta->mAuthenFlags << std::dec << std::endl; + std::cerr << " message validation result: " << (int)validateReturn << std::endl; +#endif + } + + if(validateReturn == VALIDATE_SUCCESS) + { + meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; + msgs.insert(std::make_pair(msg, meta)); + + std::vector &msgv = msgIds[msg->grpId]; + if (std::find(msgv.begin(), msgv.end(), msg->msgId) == msgv.end()) + { + msgv.push_back(msg->msgId); + } + + NxsMsgPendingVect::iterator validated_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), + getMsgIdPair(*msg)); + + if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry); + + computeHash(msg->msg, meta->mHash); + meta->recvTS = time(NULL); +#ifdef GEN_EXCH_DEBUG + std::cerr << " new status flags: " << meta->mMsgStatus << std::endl; + std::cerr << " computed hash: " << meta->mHash << std::endl; + std::cerr << "Message received. Identity=" << msg->metaData->mAuthorId << ", from peer " << msg->PeerId() << std::endl; #endif - NxsMsgPendingVect::iterator failed_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), - getMsgIdPair(*msg)); + if(!msg->metaData->mAuthorId.isNull()) + mRoutingClues[msg->metaData->mAuthorId].insert(msg->PeerId()) ; - if(failed_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(failed_entry); + if(grpMeta->mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) + mTrackingClues.push_back(std::make_pair(msg->msgId,msg->PeerId())) ; + } + } + else + { +#ifdef GEN_EXCH_DEBUG + std::cerr << " deserialisation failed!" <grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; +#endif + + NxsMsgPendingVect::iterator failed_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), + getMsgIdPair(*msg)); + + if(failed_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(failed_entry); delete msg; - } - else if(validateReturn == VALIDATE_FAIL_TRY_LATER) - { + } + else if(validateReturn == VALIDATE_FAIL_TRY_LATER) + { #ifdef GEN_EXCH_DEBUG - std::cerr << "failed to validate msg, trying again: " - << "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; + std::cerr << "failed to validate msg, trying again: " + << "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; #endif - RsGxsGrpMsgIdPair id; - id.first = msg->grpId; - id.second = msg->msgId; + RsGxsGrpMsgIdPair id; + id.first = msg->grpId; + id.second = msg->msgId; - // first check you haven't made too many attempts + // first check you haven't made too many attempts - NxsMsgPendingVect::iterator vit = std::find( - mMsgPendingValidate.begin(), mMsgPendingValidate.end(), id); + NxsMsgPendingVect::iterator vit = std::find( + mMsgPendingValidate.begin(), mMsgPendingValidate.end(), id); - if(vit == mMsgPendingValidate.end()) - { - GxsPendingItem item(msg, id); - mMsgPendingValidate.push_back(item); - }else - { + if(vit == mMsgPendingValidate.end()) + { + GxsPendingItem item(msg, id); + mMsgPendingValidate.push_back(item); + }else + { vit->mAttempts++; - } - } - } + } + } + } - // clean up resources from group meta retrieval - freeAndClearContainerResource, - RsGxsGrpMetaData*>(grpMetas); + // clean up resources from group meta retrieval + freeAndClearContainerResource, + RsGxsGrpMetaData*>(grpMetas); - if(!msgIds.empty()) - { + if(!msgIds.empty()) + { #ifdef GEN_EXCH_DEBUG - std::cerr << " removing existing and old messages from incoming list." << std::endl; + std::cerr << " removing existing and old messages from incoming list." << std::endl; #endif - removeDeleteExistingMessages(msgs, msgIds); + removeDeleteExistingMessages(msgs, msgIds); #ifdef GEN_EXCH_DEBUG - std::cerr << " storing remaining messages" << std::endl; + std::cerr << " storing remaining messages" << std::endl; #endif - mDataStore->storeMessage(msgs); + mDataStore->storeMessage(msgs); - RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVE, false); - c->msgChangeMap = msgIds; - mNotifications.push_back(c); - } + RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVE, false); + c->msgChangeMap = msgIds; + mNotifications.push_back(c); + } - mReceivedMsgs.clear(); + mReceivedMsgs.clear(); } void RsGenExchange::processRecvdGroups() diff --git a/libretroshare/src/retroshare/rsgxsflags.h b/libretroshare/src/retroshare/rsgxsflags.h index d330a1199..fc8b0836b 100644 --- a/libretroshare/src/retroshare/rsgxsflags.h +++ b/libretroshare/src/retroshare/rsgxsflags.h @@ -28,11 +28,12 @@ namespace GXS_SERV { /** END authentication **/ /** START author authentication flags **/ - static const uint32_t FLAG_AUTHOR_AUTHENTICATION_MASK = 0x0000ff00; - static const uint32_t FLAG_AUTHOR_AUTHENTICATION_NONE = 0x00000000; - static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG = 0x00000100; - static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200; - static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_MASK = 0x0000ff00; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_NONE = 0x00000000; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG = 0x00000100; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES = 0x00000800; static const uint32_t FLAG_GROUP_SIGN_PUBLISH_MASK = 0x000000ff; static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED = 0x00000001; From fee449bca450aa24fb6ea4d0570c37635afdb693 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 25 Oct 2015 19:28:13 -0400 Subject: [PATCH 09/19] added proper UI for setting anti-spam flags in GroupCreationDialog --- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 22 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 5 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 655 +++++++++--------- .../src/gui/gxsforums/GxsForumGroupDialog.cpp | 1 + .../gui/gxsforums/GxsForumThreadWidget.cpp | 3 +- 5 files changed, 338 insertions(+), 348 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 2fac8685f..32e9ce763 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -298,7 +298,10 @@ void GxsGroupDialog::setupDefaults() ui.comments_no->setChecked(true); ui.comments_no_3->setChecked(true); } - } + } + ui.antispam_keepTrackOfPosts->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_TRACK)); + ui.antispam_favorSignedIds->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP)); + #ifndef RS_USE_CIRCLES ui.typeGroup->setEnabled(false); ui.typeLocal->setEnabled(false); @@ -595,16 +598,19 @@ uint32_t GxsGroupDialog::getGroupSignFlags() signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ; } - // Author Signature. - if (ui.personal_pgp->isChecked()) - signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG; - if (ui.personal_required->isChecked()) signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; if (ui.personal_ifnopub->isChecked()) signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN; + // Author Signature. + if (ui.antispam_favorSignedIds->isChecked()) + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG; + + if (ui.antispam_keepTrackOfPosts->isChecked()) + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES; + return signFlags; } @@ -620,15 +626,15 @@ void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) ui.publish_open->setChecked(true); } - if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) - ui.personal_pgp->setChecked(true); - if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED) ui.personal_required->setChecked(true); if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN) ui.personal_ifnopub->setChecked(true); + ui.antispam_keepTrackOfPosts->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) ); + ui.antispam_favorSignedIds ->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) ); + /* guess at comments */ if ((signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) && (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN)) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index 1029ccedd..7f94c32db 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -63,8 +63,8 @@ public: #define GXS_GROUP_FLAGS_SHAREKEYS 0x00000020 #define GXS_GROUP_FLAGS_PERSONALSIGN 0x00000040 #define GXS_GROUP_FLAGS_COMMENTS 0x00000080 - #define GXS_GROUP_FLAGS_EXTRA 0x00000100 +#define GXS_GROUP_FLAGS_ANTI_SPAM 0x00000200 /*** Default flags are used to determine privacy of group, signatures required *** *** whether publish or id and whether comments are allowed or not ***/ @@ -90,6 +90,9 @@ public: #define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000 #define GXS_GROUP_DEFAULTS_COMMENTS_NO 0x00002000 +#define GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP 0x00100000 +#define GXS_GROUP_DEFAULTS_ANTISPAM_TRACK 0x00200000 + /*! * The aim of this dialog is to be convenient to encapsulate group * creation code for several GXS services such forums, channels diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index c8fdc33d9..593978414 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -6,32 +6,23 @@ 0 0 - 685 - 517 + 928 + 914 Create New - - 0 - - - 0 - - - 0 - - - 0 - 6 0 + + 0 + @@ -44,20 +35,98 @@ QFrame::Raised - 1 + 0 - - - 9 - - - 6 - - - 0 - - + + + + + true + + + + 0 + 0 + + + + + 300 + 524287 + + + + + 220 + 0 + + + + + 0 + 0 + + + + check peers you would like to share private publish key with + + + false + + + QDockWidget::NoDockWidgetFeatures + + + Share Key With + + + + + 0 + + + 0 + + + + + + 0 + 4 + + + + + 20 + 0 + + + + + 300 + 16777215 + + + + + 220 + 0 + + + + + 200 + 0 + + + + + + + + + @@ -66,16 +135,7 @@ 0 - - 4 - - - 4 - - - 4 - - + 4 @@ -139,16 +199,7 @@ 9 - - 3 - - - 3 - - - 3 - - + 3 @@ -205,191 +256,19 @@ - - + + - Publish Signatures + Description - - - 6 - - - 9 - - - 4 - - - 9 - - - 4 - + - - - Open - - - - - - - New Thread - - - - - - - Required - - - - - - - Encrypted Msgs - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - + - - - - Personal Signatures - - - - 6 - - - 9 - - - 4 - - - 9 - - - 4 - - - - - PGP Required - - - - - - - Signature Required - - - - - - - If No Publish Signature - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Comments - - - - 6 - - - 9 - - - 4 - - - 9 - - - 4 - - - - - Allow Comments - - - - - - - No Comments - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - + @@ -490,112 +369,230 @@ - - + + - Description + Publish Signatures - + + + 6 + + + 9 + + + 4 + + + 9 + + + 4 + - + + + Open + + + + + + + New Thread + + + + + + + Required + + + + + + + Encrypted Msgs + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + - - - - true + + + + Personal Signatures - - - 0 - 0 - + + + + + PGP Required + + + + + + + Signature Required + + + + + + + If No Publish Signature + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Comments - - - 300 - 524287 - + + + 6 + + + 9 + + + 4 + + + 9 + + + 4 + + + + + Allow Comments + + + + + + + No Comments + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Spam-protection - - - 220 - 0 - + + + 6 + + + 9 + + + 4 + + + 9 + + + 4 + + + + + <html><head/><body><p>This makes the media increase the reputaiton threshold to 0.2,</p><p>allowing PGP-linked ids to pass through. Anonymous ids however</p><p>can also post, if their local reputation score is above that threshold. </p></body></html> + + + Favor PGP-signed ids + + + + + + + <html><head/><body><p align="justify">This feature allows Retroshare to locally keep a record of who</p><p align="justify">forwarded each message to you, for 10 days. Although useless (and already</p><p align="justify">available whatsoever) this information can be used by a group</p><p align="justify">of collaborative friends to locate the source of spams. To be used with care,</p><p align="justify">since it significantly decreases the anonymity of message posts.</p></body></html> + + + Keep track of posts + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + QFrame::StyledPanel - - - 0 - 0 - + + QFrame::Raised - - check peers you would like to share private publish key with - - - false - - - QDockWidget::NoDockWidgetFeatures - - - Share Key With - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 4 - - - - - 20 - 0 - - - - - 300 - 16777215 - - - - - 220 - 0 - - - - - 200 - 0 - - - - - - @@ -620,16 +617,7 @@ - - 6 - - - 6 - - - 6 - - + 6 @@ -726,16 +714,7 @@ 6 - - 6 - - - 6 - - - 6 - - + 6 diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp index 88a2c93e5..596110237 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp @@ -33,6 +33,7 @@ const uint32_t ForumCreateEnabledFlags = ( GXS_GROUP_FLAGS_DISTRIBUTION | // GXS_GROUP_FLAGS_PUBLISHSIGN | GXS_GROUP_FLAGS_SHAREKEYS | + GXS_GROUP_FLAGS_ANTI_SPAM | GXS_GROUP_FLAGS_PERSONALSIGN | // GXS_GROUP_FLAGS_COMMENTS | 0); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 436e971c6..c744fa239 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -922,7 +922,8 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_AUTHOR, QString::fromStdString(msg.mMeta.mAuthorId.toStdString())); // Show info about who passed on this message. - item->setToolTip(COLUMN_THREAD_TITLE,tr("This message was obtained from %1").arg(QString::fromStdString(msg.mMeta.mProviderId.toStdString()))); + if( (mForumGroup.mMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) && !msg.mMeta.mProviderId.isNull() ) + item->setToolTip(COLUMN_THREAD_TITLE,tr("This message was obtained from %1").arg(QString::fromStdString(msg.mMeta.mProviderId.toStdString()))); //#TODO #if 0 text = QString::fromUtf8(authorName.c_str()); From e60ac999942a1a45f33a4a02e95e00ec4b37f514 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 25 Oct 2015 22:54:56 -0400 Subject: [PATCH 10/19] added bias to reputation score for known and signed ids. Changed computation formula to an exp --- .../src/serialiser/rsgxsreputationitems.cc | 54 +++++++++++++- .../src/serialiser/rsgxsreputationitems.h | 19 +++-- libretroshare/src/services/p3gxsreputation.cc | 73 +++++++++++++++++-- libretroshare/src/services/p3gxsreputation.h | 11 ++- 4 files changed, 137 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/serialiser/rsgxsreputationitems.cc b/libretroshare/src/serialiser/rsgxsreputationitems.cc index cdd82f733..9a291e9a5 100644 --- a/libretroshare/src/serialiser/rsgxsreputationitems.cc +++ b/libretroshare/src/serialiser/rsgxsreputationitems.cc @@ -34,6 +34,9 @@ #include +// re-defined here, in order to avoid cross-includes +#define REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE 0x0100 + /*************************************************************************/ bool RsReputationItem::serialise_header(void *data,uint32_t& pktsize,uint32_t& tlvsize, uint32_t& offset) const @@ -201,6 +204,7 @@ bool RsGxsReputationConfigItem::serialise(void *data, uint32_t& pktsize) const return ok; } + bool RsGxsReputationSetItem::serialise(void *data, uint32_t& pktsize) const { uint32_t tlvsize ; @@ -214,6 +218,7 @@ bool RsGxsReputationSetItem::serialise(void *data, uint32_t& pktsize) const ok &= mGxsId.serialise(data,tlvsize,offset) ; ok &= setRawUInt32(data, tlvsize, &offset, mOwnOpinion); ok &= setRawUInt32(data, tlvsize, &offset, mOwnOpinionTS); + ok &= setRawUInt32(data, tlvsize, &offset, mIdentityFlags) ; ok &= setRawUInt32(data, tlvsize, &offset, mOpinions.size()); for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) @@ -303,6 +308,45 @@ RsGxsReputationConfigItem *RsGxsReputationSerialiser::deserialiseReputationConfi return item; } +RsGxsReputationSetItem *RsGxsReputationSerialiser::deserialiseReputationSetItem_deprecated(void *data,uint32_t tlvsize) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGxsReputationSetItem *item = new RsGxsReputationSetItem() ; + + /* add mandatory parts first */ + ok &= item->mGxsId.deserialise(data, tlvsize, offset) ; + ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinion); + ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinionTS); + + item->mIdentityFlags = REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE; // special value that means please update me. + + uint32_t S ; + ok &= getRawUInt32(data, tlvsize, &offset, &S); + + for(int i=0;ok && imOpinions[pid] = op ; + } + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} RsGxsReputationSetItem *RsGxsReputationSerialiser::deserialiseReputationSetItem(void *data,uint32_t tlvsize) { uint32_t offset = 8; // skip the header @@ -315,6 +359,7 @@ RsGxsReputationSetItem *RsGxsReputationSerialiser::deserialiseReputationSetItem( ok &= item->mGxsId.deserialise(data, tlvsize, offset) ; ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinion); ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinionTS); + ok &= getRawUInt32(data, tlvsize, &offset, &item->mIdentityFlags); uint32_t S ; ok &= getRawUInt32(data, tlvsize, &offset, &S); @@ -413,10 +458,11 @@ RsItem *RsGxsReputationSerialiser::deserialise(void *data, uint32_t *pktsize) switch(getRsItemSubType(rstype)) { - case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM : return deserialiseReputationSetItem (data, *pktsize); - case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM : return deserialiseReputationUpdateItem (data, *pktsize); - case RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM: return deserialiseReputationRequestItem(data, *pktsize); - case RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM : return deserialiseReputationConfigItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM : return deserialiseReputationSetItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM_deprecated: return deserialiseReputationSetItem_deprecated(data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM : return deserialiseReputationUpdateItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM : return deserialiseReputationRequestItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM : return deserialiseReputationConfigItem (data, *pktsize); default: std::cerr << "RsGxsReputationSerialiser::deserialise(): unknown item subtype " << std::hex<< rstype << std::dec << std::endl; diff --git a/libretroshare/src/serialiser/rsgxsreputationitems.h b/libretroshare/src/serialiser/rsgxsreputationitems.h index 16b90847c..84dcecdc9 100644 --- a/libretroshare/src/serialiser/rsgxsreputationitems.h +++ b/libretroshare/src/serialiser/rsgxsreputationitems.h @@ -32,10 +32,11 @@ #include "serialiser/rsserial.h" #include "retroshare/rsgxsifacetypes.h" -#define RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM 0x01 -#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM 0x02 -#define RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM 0x03 -#define RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM 0x04 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM 0x01 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM_deprecated 0x02 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM 0x03 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM 0x04 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM 0x05 /**************************************************************************/ class RsReputationItem: public RsItem @@ -90,6 +91,7 @@ public: RsGxsId mGxsId; uint32_t mOwnOpinion; uint32_t mOwnOpinionTS; + uint32_t mIdentityFlags ; std::map mOpinions; // RsPeerId -> Opinion. }; @@ -143,10 +145,11 @@ public: virtual RsItem * deserialise(void *data, uint32_t *size); private: - static RsGxsReputationConfigItem *deserialiseReputationConfigItem (void *data, uint32_t size); - static RsGxsReputationSetItem *deserialiseReputationSetItem (void *data, uint32_t size); - static RsGxsReputationUpdateItem *deserialiseReputationUpdateItem (void *data, uint32_t size); - static RsGxsReputationRequestItem *deserialiseReputationRequestItem(void *data, uint32_t size); + static RsGxsReputationConfigItem *deserialiseReputationConfigItem (void *data, uint32_t size); + static RsGxsReputationSetItem *deserialiseReputationSetItem (void *data, uint32_t size); + static RsGxsReputationSetItem *deserialiseReputationSetItem_deprecated (void *data, uint32_t size); + static RsGxsReputationUpdateItem *deserialiseReputationUpdateItem (void *data, uint32_t size); + static RsGxsReputationRequestItem *deserialiseReputationRequestItem (void *data, uint32_t size); }; /**************************************************************************/ diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index e84500280..6b0e37eac 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -23,6 +23,7 @@ * */ +#include #include "pqi/p3linkmgr.h" #include "retroshare/rspeers.h" @@ -37,6 +38,7 @@ /**** * #define DEBUG_REPUTATION 1 ****/ +#define DEBUG_REPUTATION 1 /************ IMPLEMENTATION NOTES ********************************* * @@ -126,7 +128,6 @@ static const uint32_t LOWER_LIMIT = 0; // used to filter valid Opinion values from serialized data static const uint32_t UPPER_LIMIT = 2; // used to filter valid Opinion values from serialized data -static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed static const int kMaximumPeerAge = 180; // half a year. static const int kMaximumSetSize = 100; // max set of updates to send at once. static const int ACTIVE_FRIENDS_UPDATE_PERIOD = 600 ; // 10 minutes @@ -134,6 +135,10 @@ static const int ACTIVE_FRIENDS_ONLINE_DELAY = 86400*7 ; // 1 week. static const int kReputationRequestPeriod = 600; // 10 mins static const int kReputationStoreWait = 180; // 3 minutes. +static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed +static const float REPUTATION_PGP_LINKED_ID_BIAS = 0.2f ; +static const float REPUTATION_PGP_KNOWN_ID_BIAS = 0.3f ; // so known pgp-linked ids go up to +0.5f +static const float REPUTATION_FRIEND_VARIANCE = 2.0f ; p3GxsReputation::p3GxsReputation(p3LinkMgr *lm) @@ -180,6 +185,17 @@ int p3GxsReputation::tick() mLastActiveFriendsUpdate = now ; } + static time_t last_identity_flags_update = 0 ; + + // no more than once per 5 second chunk. + + if(now > 5+last_identity_flags_update) + { + last_identity_flags_update = now ; + + updateIdentityFlags() ; + } + #ifdef DEBUG_REPUTATION static time_t last_debug_print = time(NULL) ; @@ -197,6 +213,33 @@ int p3GxsReputation::status() return 1; } +void p3GxsReputation::updateIdentityFlags() +{ + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + + std::cerr << "Updating reputation identity flags" << std::endl; + + for( std::map::iterator rit = mReputations.begin();rit!=mReputations.end();++rit) + if(rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) + { + RsIdentityDetails details; + + if(!rsIdentity->getIdDetails(rit->first,details)) + { + std::cerr << " cannot obtain info for " << rit->first << ". Will do it later." << std::endl; + continue ; + } + + rit->second.mIdentityFlags = 0 ; + + if(details.mPgpLinked) rit->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_LINKED ; + if(details.mPgpKnown ) rit->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_KNOWN ; + + std::cerr << " updated flags for " << rit->first << " to " << std::hex << rit->second.mIdentityFlags << std::dec << std::endl; + break ; + } +} + void p3GxsReputation::cleanup() { // remove opinions from friends that havn't been seen online for more than the specified delay @@ -539,7 +582,7 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, RsReputations::Rep std::cerr << "getReputationInfo() for " << gxsid << std::endl; #endif - std::map::const_iterator it = mReputations.find(gxsid); + std::map::iterator it = mReputations.find(gxsid); if (it == mReputations.end()) { @@ -689,6 +732,7 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list &savelist) item->mGxsId = rit->first; item->mOwnOpinion = rit->second.mOwnOpinion; item->mOwnOpinionTS = rit->second.mOwnOpinionTs; + item->mIdentityFlags = rit->second.mIdentityFlags; std::map::iterator oit; for(oit = rit->second.mOpinions.begin(); oit != rit->second.mOpinions.end(); ++oit) @@ -719,6 +763,7 @@ bool p3GxsReputation::loadList(std::list& loadList) for(it = loadList.begin(); it != loadList.end(); ++it) { RsGxsReputationConfigItem *item = dynamic_cast(*it); + // Configurations are loaded first. (to establish peerSet). if (item) { @@ -728,13 +773,14 @@ bool p3GxsReputation::loadList(std::list& loadList) config.mPeerId = peerId; config.mLatestUpdate = item->mLatestUpdate; config.mLastQuery = 0; - + peerSet.insert(peerId); } + RsGxsReputationSetItem *set = dynamic_cast(*it); if (set) loadReputationSet(set, peerSet); - + delete (*it); } @@ -903,10 +949,25 @@ void Reputation::updateReputation(uint32_t average_active_friends) if(mOpinions.empty()) // includes the case of no friends! mFriendAverage = 1.0f ; else - mFriendAverage = 1.0+friend_total / float(std::max(average_active_friends,(uint32_t)mOpinions.size())); + { + if(friend_total > 0) + mFriendAverage = 1.0+exp(-friend_total / REPUTATION_FRIEND_VARIANCE) ; + else + mFriendAverage = 1.0-exp( friend_total / REPUTATION_FRIEND_VARIANCE) ; + } + // now compute a bias for PGP-signed ids. + + float pgp_bias = 0.0f ; + + if(mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED) + pgp_bias += REPUTATION_PGP_KNOWN_ID_BIAS ; + + if(mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_KNOWN) + pgp_bias += REPUTATION_PGP_LINKED_ID_BIAS ; + if(mOwnOpinion == RsReputations::OPINION_NEUTRAL) - mReputation = mFriendAverage ; + mReputation = std::max(0.0f,std::min(2.0f,mFriendAverage + pgp_bias)) ; else mReputation = (float)mOwnOpinion ; } diff --git a/libretroshare/src/services/p3gxsreputation.h b/libretroshare/src/services/p3gxsreputation.h index 26beca518..24cb47ee0 100644 --- a/libretroshare/src/services/p3gxsreputation.h +++ b/libretroshare/src/services/p3gxsreputation.h @@ -32,6 +32,10 @@ #include #include +#define REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE 0x0100 +#define REPUTATION_IDENTITY_FLAG_PGP_LINKED 0x0001 +#define REPUTATION_IDENTITY_FLAG_PGP_KNOWN 0x0002 + #include "serialiser/rsgxsreputationitems.h" #include "retroshare/rsidentity.h" @@ -59,10 +63,10 @@ class Reputation { public: Reputation() - :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL) { } + :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) { } Reputation(const RsGxsId& about) - :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL) { } + :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) { } void updateReputation(uint32_t average_active_friends); @@ -72,6 +76,8 @@ public: float mFriendAverage ; float mReputation; + + uint32_t mIdentityFlags; }; @@ -124,6 +130,7 @@ class p3GxsReputation: public p3Service, public p3Config, public RsReputations / void sendReputationRequests(); int sendReputationRequest(RsPeerId peerid); void debug_print() ; + void updateIdentityFlags(); private: RsMutex mReputationMtx; From b009c1135fc544056464ab177722955c70401199 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 25 Oct 2015 23:45:33 -0400 Subject: [PATCH 11/19] changed RsGenExchange strategy to use a threshold on reputation when validating posts --- libretroshare/src/gxs/rsgenexchange.cc | 15 ++- libretroshare/src/retroshare/rsreputations.h | 3 + .../src/serialiser/rsgxsreputationitems.cc | 1 + libretroshare/src/services/p3gxsreputation.cc | 106 ++++++++++-------- libretroshare/src/services/p3gxsreputation.h | 10 +- 5 files changed, 75 insertions(+), 60 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 2dfdde377..43b695f1b 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -60,7 +60,7 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key #define GXS_MASK "GXS_MASK_HACK" -//#define GEN_EXCH_DEBUG 1 +#define GEN_EXCH_DEBUG 1 #define MSG_CLEANUP_PERIOD 60*5 // 5 minutes #define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes @@ -899,7 +899,10 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin idValidate = false; } - if(idValidate && (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)) + // now check reputation of the message author + float reputation_threshold = (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)? RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM: RsReputations::REPUTATION_THRESHOLD_DEFAULT ; + + if(idValidate) { // get key data and check that the key is actually PGP-linked. If not, reject the post. @@ -908,18 +911,18 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin if(!mGixs->getIdDetails(metaData.mAuthorId,details)) { // the key cannot ke reached, although it's in cache. Weird situation. - idValidate = false; std::cerr << "RsGenExchange::validateMsg(): cannot get key data for ID=" << metaData.mAuthorId << ", although it's supposed to be already in cache. Cannot validate." << std::endl; idValidate = false ; } - - if(!details.mPgpLinked) + else if(details.mReputation.mOverallReputationScore < reputation_threshold) { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because key is not PGP linked and the group requires it." << std::endl; + std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation score (" << details.mReputation.mOverallReputationScore <<") is below the accepted threshold (" << reputation_threshold << ")" << std::endl; #endif idValidate = false ; } + std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", accepted. Reputation score (" << details.mReputation.mOverallReputationScore <<") is above accepted threshold (" << reputation_threshold << ")" << std::endl; + } } else diff --git a/libretroshare/src/retroshare/rsreputations.h b/libretroshare/src/retroshare/rsreputations.h index 433eb8368..c79fa2ce3 100644 --- a/libretroshare/src/retroshare/rsreputations.h +++ b/libretroshare/src/retroshare/rsreputations.h @@ -31,6 +31,9 @@ class RsReputations { public: + static const float REPUTATION_THRESHOLD_ANTI_SPAM = 1.2f ; + static const float REPUTATION_THRESHOLD_DEFAULT = 1.0f ; + // This is the interface file for the reputation system // enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ; diff --git a/libretroshare/src/serialiser/rsgxsreputationitems.cc b/libretroshare/src/serialiser/rsgxsreputationitems.cc index 9a291e9a5..379cf4330 100644 --- a/libretroshare/src/serialiser/rsgxsreputationitems.cc +++ b/libretroshare/src/serialiser/rsgxsreputationitems.cc @@ -151,6 +151,7 @@ uint32_t RsGxsReputationSetItem::serial_size() const s += mGxsId.serial_size() ; s += 4 ; // mOwnOpinion s += 4 ; // mOwnOpinionTS + s += 4 ; // mIdentityFlags s += 4 ; // mOpinions.size() diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index 6b0e37eac..010c32b71 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -189,7 +189,7 @@ int p3GxsReputation::tick() // no more than once per 5 second chunk. - if(now > 5+last_identity_flags_update) + if(now > 100+last_identity_flags_update) { last_identity_flags_update = now ; @@ -215,29 +215,48 @@ int p3GxsReputation::status() void p3GxsReputation::updateIdentityFlags() { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - std::cerr << "Updating reputation identity flags" << std::endl; - - for( std::map::iterator rit = mReputations.begin();rit!=mReputations.end();++rit) - if(rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) - { - RsIdentityDetails details; - - if(!rsIdentity->getIdDetails(rit->first,details)) - { - std::cerr << " cannot obtain info for " << rit->first << ". Will do it later." << std::endl; - continue ; - } - - rit->second.mIdentityFlags = 0 ; - - if(details.mPgpLinked) rit->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_LINKED ; - if(details.mPgpKnown ) rit->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_KNOWN ; - - std::cerr << " updated flags for " << rit->first << " to " << std::hex << rit->second.mIdentityFlags << std::dec << std::endl; - break ; - } + std::list to_update ; + + // we need to gather the list to be used in a non locked frame + { + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + + std::cerr << "Updating reputation identity flags" << std::endl; + + for( std::map::iterator rit = mReputations.begin();rit!=mReputations.end();++rit) + if(rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) + to_update.push_back(rit->first) ; + } + + for(std::list::const_iterator rit(to_update.begin());rit!=to_update.end();++rit) + { + RsIdentityDetails details; + + if(!rsIdentity->getIdDetails(*rit,details)) + { + std::cerr << " cannot obtain info for " << *rit << ". Will do it later." << std::endl; + continue ; + } + + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + + std::map::iterator it = mReputations.find(*rit) ; + + if(it == mReputations.end()) + { + std::cerr << " Weird situation: item " << *rit << " has been deleted from the list??" << std::endl; + continue ; + } + it->second.mIdentityFlags = 0 ; + + if(details.mPgpLinked) it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_LINKED ; + if(details.mPgpKnown ) it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_KNOWN ; + + std::cerr << " updated flags for " << *rit << " to " << std::hex << it->second.mIdentityFlags << std::dec << std::endl; + + it->second.updateReputation() ; + IndicateConfigChanged(); + } } void p3GxsReputation::cleanup() @@ -521,7 +540,7 @@ void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& a #ifdef DEBUG_REPUTATION std::cerr << " reputation changed. re-calculating." << std::endl; #endif - reputation.updateReputation(mAverageActiveFriends) ; + reputation.updateReputation() ; } if(updated) @@ -576,39 +595,28 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,time_t latest_update) bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, RsReputations::ReputationInfo& info) { + if(gxsid.isNull()) + return false ; + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ #ifdef DEBUG_REPUTATION std::cerr << "getReputationInfo() for " << gxsid << std::endl; #endif - - std::map::iterator it = mReputations.find(gxsid); + Reputation& rep(mReputations[gxsid]) ; - if (it == mReputations.end()) - { - info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ; - info.mFriendAverage = RsReputations::OPINION_NEUTRAL ; - info.mOverallReputationScore = float(RsReputations::OPINION_NEUTRAL) ; + info.mOwnOpinion = RsReputations::Opinion(rep.mOwnOpinion) ; + info.mOverallReputationScore = rep.mReputation ; + info.mFriendAverage = rep.mFriendAverage ; + + if(info.mOverallReputationScore > REPUTATION_ASSESSMENT_THRESHOLD_X1) info.mAssessment = RsReputations::ASSESSMENT_OK ; -#ifdef DEBUG_REPUTATION - std::cerr << " no information present. Returning default. OwnOp = " << info.mOwnOpinion << ", overall score=" << info.mAssessment << std::endl; -#endif - } else - { - info.mOwnOpinion = RsReputations::Opinion(it->second.mOwnOpinion) ; - info.mOverallReputationScore = it->second.mReputation ; - info.mFriendAverage = it->second.mFriendAverage ; + info.mAssessment = RsReputations::ASSESSMENT_BAD ; - if(info.mOverallReputationScore > REPUTATION_ASSESSMENT_THRESHOLD_X1) - info.mAssessment = RsReputations::ASSESSMENT_OK ; - else - info.mAssessment = RsReputations::ASSESSMENT_BAD ; - #ifdef DEBUG_REPUTATION std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", overall score=" << info.mAssessment << std::endl; #endif - } return true ; } @@ -675,7 +683,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O time_t now = time(NULL); reputation.mOwnOpinion = opinion; reputation.mOwnOpinionTs = now; - reputation.updateReputation(mAverageActiveFriends); + reputation.updateReputation(); mUpdated.insert(std::make_pair(now, gxsid)); mUpdatedReputations.insert(gxsid); @@ -825,7 +833,7 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std: //float old_reputation = reputation.mReputation ; //mUpdatedReputations.insert(gxsId) ; - reputation.updateReputation(mAverageActiveFriends) ; + reputation.updateReputation() ; mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId)); return true; @@ -934,7 +942,7 @@ int p3GxsReputation::sendReputationRequest(RsPeerId peerid) return 1; } -void Reputation::updateReputation(uint32_t average_active_friends) +void Reputation::updateReputation() { // the calculation of reputation makes the whole thing diff --git a/libretroshare/src/services/p3gxsreputation.h b/libretroshare/src/services/p3gxsreputation.h index 24cb47ee0..6bda150ff 100644 --- a/libretroshare/src/services/p3gxsreputation.h +++ b/libretroshare/src/services/p3gxsreputation.h @@ -63,12 +63,12 @@ class Reputation { public: Reputation() - :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) { } + :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ } + + Reputation(const RsGxsId& about) + :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ } - Reputation(const RsGxsId& about) - :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) { } - - void updateReputation(uint32_t average_active_friends); + void updateReputation(); std::map mOpinions; int32_t mOwnOpinion; From c7d0e4cb3514d6a33efa001796bb29a62666687d Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 26 Oct 2015 23:38:10 -0400 Subject: [PATCH 12/19] enabled ID tracking forums. Fixed thresholds for anti-spam forums. Changed computation of reputation scored --- libretroshare/src/grouter/grouteritems.cc | 4 +- libretroshare/src/grouter/grouteritems.h | 2 +- libretroshare/src/grouter/groutermatrix.cc | 19 ++++-- libretroshare/src/grouter/groutermatrix.h | 3 +- libretroshare/src/grouter/p3grouter.cc | 7 ++ libretroshare/src/grouter/p3grouter.h | 1 + libretroshare/src/gxs/rsgenexchange.cc | 51 ++++++++------- libretroshare/src/retroshare/rsgrouter.h | 2 + libretroshare/src/retroshare/rsgxsflags.h | 1 + .../src/retroshare/rsgxsifacetypes.h | 1 - libretroshare/src/retroshare/rsreputations.h | 2 +- libretroshare/src/services/p3gxsreputation.cc | 64 ++++++++++++++----- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 4 +- .../gui/gxsforums/GxsForumThreadWidget.cpp | 24 +++++-- 14 files changed, 130 insertions(+), 55 deletions(-) diff --git a/libretroshare/src/grouter/grouteritems.cc b/libretroshare/src/grouter/grouteritems.cc index f7f01285f..b67ed71e6 100644 --- a/libretroshare/src/grouter/grouteritems.cc +++ b/libretroshare/src/grouter/grouteritems.cc @@ -279,7 +279,7 @@ RsGRouterMatrixTrackItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixTrackI RsGRouterMatrixTrackItem *item = new RsGRouterMatrixTrackItem() ; - ok &= getRawUInt32(data, pktsize, &offset, &item->provider_id) ; + ok &= item->provider_id.deserialise(data, pktsize, offset) ; ok &= item->message_id.deserialise(data,pktsize,offset) ; ok &= getRawTimeT(data, pktsize, &offset, item->time_stamp) ; @@ -679,7 +679,7 @@ bool RsGRouterMatrixTrackItem::serialise(void *data,uint32_t& size) const if(!serialise_header(data,size,tlvsize,offset)) return false ; - ok &= setRawUInt32(data, tlvsize, &offset, provider_id) ; + ok &= provider_id.serialise(data, tlvsize, offset) ; ok &= message_id.serialise(data,tlvsize,offset) ; ok &= setRawTimeT(data, tlvsize, &offset, time_stamp) ; diff --git a/libretroshare/src/grouter/grouteritems.h b/libretroshare/src/grouter/grouteritems.h index 9c3a2041b..574c7b3c4 100644 --- a/libretroshare/src/grouter/grouteritems.h +++ b/libretroshare/src/grouter/grouteritems.h @@ -257,7 +257,7 @@ class RsGRouterMatrixTrackItem: public RsGRouterItem // packet data // RsGxsMessageId message_id ; - uint32_t provider_id ; + RsPeerId provider_id ; time_t time_stamp ; }; class RsGRouterMatrixFriendListItem: public RsGRouterItem diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index f92da9bc0..b7bb6d562 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -37,16 +37,15 @@ GRouterMatrix::GRouterMatrix() bool GRouterMatrix::addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& source_friend) { time_t now = time(NULL) ; - uint32_t fid = getFriendId(source_friend) ; RoutingTrackEntry rte ; - rte.friend_id = fid ; + rte.friend_id = source_friend ; rte.time_stamp = now ; _tracking_clues[mid] = rte ; #ifdef ROUTING_MATRIX_DEBUG - std::cerr << "GRouterMatrix::addTrackingInfo(): Added clue mid=" << mid << ", from " << source_friend << " ID=" << fid << std::endl; + std::cerr << "GRouterMatrix::addTrackingInfo(): Added clue mid=" << mid << ", from " << source_friend << " ID=" << source_friend << std::endl; #endif return true ; } @@ -158,7 +157,19 @@ void GRouterMatrix::getListOfKnownKeys(std::vector& key_ids) const key_ids.clear() ; for(std::map >::const_iterator it(_time_combined_hits.begin());it!=_time_combined_hits.end();++it) - key_ids.push_back(it->first) ; + key_ids.push_back(it->first) ; +} + +bool GRouterMatrix::getTrackingInfo(const RsGxsMessageId& mid, RsPeerId &source_friend) +{ + std::map::const_iterator it = _tracking_clues.find(mid) ; + + if(it == _tracking_clues.end()) + return false ; + + source_friend = it->second.friend_id; + + return true ; } void GRouterMatrix::debugDump() const diff --git a/libretroshare/src/grouter/groutermatrix.h b/libretroshare/src/grouter/groutermatrix.h index 755c5333f..18c0cb189 100644 --- a/libretroshare/src/grouter/groutermatrix.h +++ b/libretroshare/src/grouter/groutermatrix.h @@ -44,7 +44,7 @@ struct RoutingMatrixHitEntry struct RoutingTrackEntry { - uint32_t friend_id ; // not the full key. Gets too big otherwise! + RsPeerId friend_id ; // not the full key. Gets too big otherwise! time_t time_stamp ; }; @@ -79,6 +79,7 @@ class GRouterMatrix void debugDump() const ; void getListOfKnownKeys(std::vector& key_ids) const ; + bool getTrackingInfo(const RsGxsMessageId& id,RsPeerId& source_friend); private: // returns the friend id, possibly creating a new id. // diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index d14460bb4..a5b3d6472 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -2163,6 +2163,13 @@ bool p3GRouter::getRoutingCacheInfo(std::vector& infos) return true ; } +bool p3GRouter::getTrackingInfo(const RsGxsMessageId &mid, RsPeerId &provider_id) +{ + RS_STACK_MUTEX(grMtx) ; + + return _routing_matrix.getTrackingInfo(mid,provider_id) ; +} + // Dump everything // void p3GRouter::debugDump() diff --git a/libretroshare/src/grouter/p3grouter.h b/libretroshare/src/grouter/p3grouter.h index 900e4fe68..0dbadd345 100644 --- a/libretroshare/src/grouter/p3grouter.h +++ b/libretroshare/src/grouter/p3grouter.h @@ -168,6 +168,7 @@ public: // - Cache state (memory size, etc) // virtual bool getRoutingCacheInfo(std::vector& info) ; + virtual bool getTrackingInfo(const RsGxsMessageId& mid, RsPeerId& provider_id) ; //===================================================// // Derived from p3Service // diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 43b695f1b..59d2025d7 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -899,31 +899,36 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin idValidate = false; } - // now check reputation of the message author - float reputation_threshold = (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)? RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM: RsReputations::REPUTATION_THRESHOLD_DEFAULT ; - if(idValidate) - { - // get key data and check that the key is actually PGP-linked. If not, reject the post. - - RsIdentityDetails details ; - - if(!mGixs->getIdDetails(metaData.mAuthorId,details)) - { - // the key cannot ke reached, although it's in cache. Weird situation. - std::cerr << "RsGenExchange::validateMsg(): cannot get key data for ID=" << metaData.mAuthorId << ", although it's supposed to be already in cache. Cannot validate." << std::endl; - idValidate = false ; - } - else if(details.mReputation.mOverallReputationScore < reputation_threshold) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation score (" << details.mReputation.mOverallReputationScore <<") is below the accepted threshold (" << reputation_threshold << ")" << std::endl; -#endif - idValidate = false ; - } - std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", accepted. Reputation score (" << details.mReputation.mOverallReputationScore <<") is above accepted threshold (" << reputation_threshold << ")" << std::endl; + { + // get key data and check that the key is actually PGP-linked. If not, reject the post. - } + RsIdentityDetails details ; + + if(!mGixs->getIdDetails(metaData.mAuthorId,details)) + { + // the key cannot ke reached, although it's in cache. Weird situation. + std::cerr << "RsGenExchange::validateMsg(): cannot get key data for ID=" << metaData.mAuthorId << ", although it's supposed to be already in cache. Cannot validate." << std::endl; + idValidate = false ; + } + else + { + + // now check reputation of the message author + float reputation_threshold = ( (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) && !details.mPgpLinked) ? (RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM): (RsReputations::REPUTATION_THRESHOLD_DEFAULT) ; + + if(details.mReputation.mOverallReputationScore < reputation_threshold) + { +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation score (" << details.mReputation.mOverallReputationScore <<") is below the accepted threshold (" << reputation_threshold << ")" << std::endl; +#endif + idValidate = false ; + } + else + std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", accepted. Reputation score (" << details.mReputation.mOverallReputationScore <<") is above accepted threshold (" << reputation_threshold << ")" << std::endl; + } + + } } else { diff --git a/libretroshare/src/retroshare/rsgrouter.h b/libretroshare/src/retroshare/rsgrouter.h index 7cb3d6a82..acd3aee10 100644 --- a/libretroshare/src/retroshare/rsgrouter.h +++ b/libretroshare/src/retroshare/rsgrouter.h @@ -103,6 +103,8 @@ public: virtual void addRoutingClue(const GRouterKeyId& destination, const RsPeerId& source) =0; virtual void addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& peer_id) =0; + + virtual bool getTrackingInfo(const RsGxsMessageId& mid, RsPeerId& provider_id) =0; }; // To access the GRouter from anywhere diff --git a/libretroshare/src/retroshare/rsgxsflags.h b/libretroshare/src/retroshare/rsgxsflags.h index fc8b0836b..0b2d78a08 100644 --- a/libretroshare/src/retroshare/rsgxsflags.h +++ b/libretroshare/src/retroshare/rsgxsflags.h @@ -104,6 +104,7 @@ namespace GXS_SERV { #define IS_MSG_UNREAD(status) (status & GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD) #define IS_GROUP_PGP_AUTHED(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) +#define IS_GROUP_MESSAGE_TRACKING(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) #define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) #define IS_GROUP_PUBLISHER(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) diff --git a/libretroshare/src/retroshare/rsgxsifacetypes.h b/libretroshare/src/retroshare/rsgxsifacetypes.h index a8c794536..e4c5e6048 100644 --- a/libretroshare/src/retroshare/rsgxsifacetypes.h +++ b/libretroshare/src/retroshare/rsgxsifacetypes.h @@ -127,7 +127,6 @@ public: /// the first 16 bits for service, last 16 for GXS uint32_t mMsgStatus; - RsPeerId mProviderId ; time_t mChildTs; std::string mServiceString; // Service Specific Free-Form extra storage. diff --git a/libretroshare/src/retroshare/rsreputations.h b/libretroshare/src/retroshare/rsreputations.h index c79fa2ce3..807f45f40 100644 --- a/libretroshare/src/retroshare/rsreputations.h +++ b/libretroshare/src/retroshare/rsreputations.h @@ -31,7 +31,7 @@ class RsReputations { public: - static const float REPUTATION_THRESHOLD_ANTI_SPAM = 1.2f ; + static const float REPUTATION_THRESHOLD_ANTI_SPAM = 1.4f ; static const float REPUTATION_THRESHOLD_DEFAULT = 1.0f ; // This is the interface file for the reputation system diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index 010c32b71..1cccb2d04 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -132,13 +132,13 @@ static const int kMaximumPeerAge = 180; // half a static const int kMaximumSetSize = 100; // max set of updates to send at once. static const int ACTIVE_FRIENDS_UPDATE_PERIOD = 600 ; // 10 minutes static const int ACTIVE_FRIENDS_ONLINE_DELAY = 86400*7 ; // 1 week. -static const int kReputationRequestPeriod = 600; // 10 mins -static const int kReputationStoreWait = 180; // 3 minutes. +static const int kReputationRequestPeriod = 60; // 10 mins +static const int kReputationStoreWait = 18; // 3 minutes. static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed static const float REPUTATION_PGP_LINKED_ID_BIAS = 0.2f ; static const float REPUTATION_PGP_KNOWN_ID_BIAS = 0.3f ; // so known pgp-linked ids go up to +0.5f -static const float REPUTATION_FRIEND_VARIANCE = 2.0f ; +static const float REPUTATION_FRIEND_VARIANCE = 3.0f ; p3GxsReputation::p3GxsReputation(p3LinkMgr *lm) @@ -958,24 +958,56 @@ void Reputation::updateReputation() mFriendAverage = 1.0f ; else { - if(friend_total > 0) - mFriendAverage = 1.0+exp(-friend_total / REPUTATION_FRIEND_VARIANCE) ; - else - mFriendAverage = 1.0-exp( friend_total / REPUTATION_FRIEND_VARIANCE) ; + static const float REPUTATION_FRIEND_FACTOR_ANON = 2.0f ; + static const float REPUTATION_FRIEND_FACTOR_PGP_LINKED = 5.0f ; + static const float REPUTATION_FRIEND_FACTOR_PGP_KNOWN = 10.0f ; + + // For positive votes, start from 1 and slowly tend to 2 + // for negative votes, start from 1 and slowly tend to 0 + // depending on signature state, the ID is harder (signed ids) or easier (anon ids) to ban or to promote. + // + // when REPUTATION_FRIEND_VARIANCE = 3, that gives the following values: + // + // total votes | mFriendAverage anon | mFriendAverage PgpLinked | mFriendAverage PgpKnown | + // | F=2.0 | F=5.0 | F=10.0 | + // -------------+----------------------+---------------------------+--------------------------+ + // -10 | 0.00 Banned | 0.13 Banned | 0.36 Banned | + // -5 | 0.08 Banned | 0.36 Banned | 0.60 | + // -4 | 0.13 Banned | 0.44 Banned | 0.67 | + // -3 | 0.22 Banned | 0.54 | 0.74 | + // -2 | 0.36 Banned | 0.67 | 0.81 | + // -1 | 0.60 | 0.81 | 0.90 | + // 0 | 1.0 | 1.0 | 1.00 | + // 1 | 1.39 | 1.18 | 1.09 | + // 2 | 1.63 | 1.32 | 1.18 | + // 3 | 1.77 | 1.45 | 1.25 | + // 4 | 1.86 | 1.55 | 1.32 | + // 5 | 1.91 | 1.63 | 1.39 | + // + // Banning info is provided by the reputation system, and does not depend on PGP-sign state. + // + // However, each service might have its own rules for the different cases. For instance + // PGP-favoring forums might want a score > 1.4 for anon ids, and >= 1.0 for PGP-signed. + + float reputation_bias ; + + if(mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_KNOWN) + reputation_bias = REPUTATION_FRIEND_FACTOR_PGP_KNOWN ; + else if(mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED) + reputation_bias = REPUTATION_FRIEND_FACTOR_PGP_LINKED ; + else + reputation_bias = REPUTATION_FRIEND_FACTOR_ANON ; + + if(friend_total > 0) + mFriendAverage = 2.0f-exp(-friend_total / reputation_bias) ; + else + mFriendAverage = exp( friend_total / reputation_bias) ; } // now compute a bias for PGP-signed ids. - float pgp_bias = 0.0f ; - - if(mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED) - pgp_bias += REPUTATION_PGP_KNOWN_ID_BIAS ; - - if(mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_KNOWN) - pgp_bias += REPUTATION_PGP_LINKED_ID_BIAS ; - if(mOwnOpinion == RsReputations::OPINION_NEUTRAL) - mReputation = std::max(0.0f,std::min(2.0f,mFriendAverage + pgp_bias)) ; + mReputation = mFriendAverage ; else mReputation = (float)mOwnOpinion ; } diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index 593978414..be2e0f85f 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -552,7 +552,7 @@ - <html><head/><body><p>This makes the media increase the reputaiton threshold to 0.2,</p><p>allowing PGP-linked ids to pass through. Anonymous ids however</p><p>can also post, if their local reputation score is above that threshold. </p></body></html> + <html><head/><body><p>This makes the media increase the reputation threshold to 0.4 for anonymous ids,</p><p>while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation </p><p>score is above that threshold.</p></body></html> Favor PGP-signed ids @@ -562,7 +562,7 @@ - <html><head/><body><p align="justify">This feature allows Retroshare to locally keep a record of who</p><p align="justify">forwarded each message to you, for 10 days. Although useless (and already</p><p align="justify">available whatsoever) this information can be used by a group</p><p align="justify">of collaborative friends to locate the source of spams. To be used with care,</p><p align="justify">since it significantly decreases the anonymity of message posts.</p></body></html> + <html><head/><body><p align="justify">This feature allows Retroshare to locally keep a record of who</p><p align="justify">forwarded each message to you, for the last 10 days. Although useless if alone (and already</p><p align="justify">available whatsoever) this information can be used by a group</p><p align="justify">of collaborative friends to easily locate the source of spams. To be used with care,</p><p align="justify">since it significantly decreases the anonymity of message posts.</p></body></html> Keep track of posts diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 3f5119a13..eb77bced7 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -41,6 +41,7 @@ #include "util/QtVersion.h" #include +#include #include #include // These should be in retroshare/ folder. @@ -747,13 +748,23 @@ void GxsForumThreadWidget::insertGroupData() tw->mSignFlags = group.mMeta.mSignFlags; tw->ui->forumName->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str())); - QString anon_allowed_str = (IS_GROUP_PGP_AUTHED(tw->mSignFlags))?tr("No"):tr("Yes") ; + QString anti_spam_features1 ; + if(IS_GROUP_PGP_AUTHED(tw->mSignFlags)) anti_spam_features1 = tr("Anonymous IDs reputation threshold set to 0.4"); + + QString anti_spam_features2 ; + if(IS_GROUP_MESSAGE_TRACKING(tw->mSignFlags)) anti_spam_features2 = tr("Message routing info kept for 10 days"); tw->mForumDescription = QString("%1: \t%2
").arg(tr("Forum name"), QString::fromUtf8( group.mMeta.mGroupName.c_str())); tw->mForumDescription += QString("%1: \t%2
").arg(tr("Subscribers")).arg(group.mMeta.mPop); tw->mForumDescription += QString("%1: \t%2
").arg(tr("Posts (at neighbor nodes)")).arg(group.mMeta.mVisibleMsgCount); tw->mForumDescription += QString("%1: \t%2
").arg(tr("Author"), author); - tw->mForumDescription += QString("%1: \t%2
").arg(tr("Anonymous post allowed")).arg(anon_allowed_str); + + if(!anti_spam_features1.isNull()) + tw->mForumDescription += QString("%1: \t%2
").arg(tr("Anti-spam")).arg(anti_spam_features1); + + if(!anti_spam_features2.isNull()) + tw->mForumDescription += QString("%1: \t%2
").arg(tr("Anti-spam")).arg(anti_spam_features2); + tw->mForumDescription += QString("%1:

%2").arg(tr("Description"), QString::fromUtf8(group.mDescription.c_str())); tw->ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(tw->mSubscribeFlags)); @@ -942,8 +953,13 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_AUTHOR, QString::fromStdString(msg.mMeta.mAuthorId.toStdString())); // Show info about who passed on this message. - if( (mForumGroup.mMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) && !msg.mMeta.mProviderId.isNull() ) - item->setToolTip(COLUMN_THREAD_TITLE,tr("This message was obtained from %1").arg(QString::fromStdString(msg.mMeta.mProviderId.toStdString()))); + if(mForumGroup.mMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) + { + RsPeerId providerId ; + + if(rsGRouter->getTrackingInfo(msg.mMeta.mMsgId,providerId) && !providerId.isNull() ) + item->setToolTip(COLUMN_THREAD_TITLE,tr("This message was obtained from %1").arg(QString::fromUtf8(rsPeers->getPeerName(providerId).c_str()))); + } //#TODO #if 0 text = QString::fromUtf8(authorName.c_str()); From 206b27a262ed73461fc70e685a0dcac8299c5763 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 26 Oct 2015 23:55:34 -0400 Subject: [PATCH 13/19] minor bugfix in msg tracking --- retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp index 596110237..433f354c9 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp @@ -34,7 +34,7 @@ const uint32_t ForumCreateEnabledFlags = ( // GXS_GROUP_FLAGS_PUBLISHSIGN | GXS_GROUP_FLAGS_SHAREKEYS | GXS_GROUP_FLAGS_ANTI_SPAM | - GXS_GROUP_FLAGS_PERSONALSIGN | + // GXS_GROUP_FLAGS_PERSONALSIGN | // GXS_GROUP_FLAGS_COMMENTS | 0); From d69f2709c31c1c5877ac7cf3af0f84da0ec579a3 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 27 Oct 2015 00:02:16 -0400 Subject: [PATCH 14/19] restored constants and output to non debugging state --- libretroshare/src/grouter/groutermatrix.cc | 2 +- libretroshare/src/gxs/rsgenexchange.cc | 2 +- libretroshare/src/services/p3gxsreputation.cc | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index b7bb6d562..ffd28df35 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -27,7 +27,7 @@ #include "groutermatrix.h" #include "grouteritems.h" -#define ROUTING_MATRIX_DEBUG +//#define ROUTING_MATRIX_DEBUG GRouterMatrix::GRouterMatrix() { diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 59d2025d7..6cb5fe71a 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -60,7 +60,7 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key #define GXS_MASK "GXS_MASK_HACK" -#define GEN_EXCH_DEBUG 1 +//#define GEN_EXCH_DEBUG 1 #define MSG_CLEANUP_PERIOD 60*5 // 5 minutes #define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index 1cccb2d04..048d1639f 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -38,7 +38,6 @@ /**** * #define DEBUG_REPUTATION 1 ****/ -#define DEBUG_REPUTATION 1 /************ IMPLEMENTATION NOTES ********************************* * @@ -132,8 +131,8 @@ static const int kMaximumPeerAge = 180; // half a static const int kMaximumSetSize = 100; // max set of updates to send at once. static const int ACTIVE_FRIENDS_UPDATE_PERIOD = 600 ; // 10 minutes static const int ACTIVE_FRIENDS_ONLINE_DELAY = 86400*7 ; // 1 week. -static const int kReputationRequestPeriod = 60; // 10 mins -static const int kReputationStoreWait = 18; // 3 minutes. +static const int kReputationRequestPeriod = 600; // 10 mins +static const int kReputationStoreWait = 180; // 3 minutes. static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed static const float REPUTATION_PGP_LINKED_ID_BIAS = 0.2f ; From 2096cd6c528784ca4965a8a194ddc5d76d473b3b Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 27 Oct 2015 20:15:50 -0400 Subject: [PATCH 15/19] added backward compatibility and API extension for RsGxsGrpMetaData --- libretroshare/src/gxs/rsgenexchange.cc | 2 +- libretroshare/src/gxs/rsgxsdata.cc | 36 ++++++++++++++++--- libretroshare/src/services/p3gxsreputation.cc | 4 --- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 6cb5fe71a..59d2025d7 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -60,7 +60,7 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key #define GXS_MASK "GXS_MASK_HACK" -//#define GEN_EXCH_DEBUG 1 +#define GEN_EXCH_DEBUG 1 #define MSG_CLEANUP_PERIOD 60*5 // 5 minutes #define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index 763a61957..9de06aa83 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -28,6 +28,11 @@ #include "serialiser/rsbaseserial.h" #include "serialiser/rstlvbase.h" +static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0001 = 0x0000 ; // change this, and keep old values if the content changes +static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0002 = 0xaf01 ; // current API + +static const uint32_t RS_GXS_MSG_META_DATA_VERSION_ID_0001 = 0x0000 ; // current API + RsGxsGrpMetaData::RsGxsGrpMetaData() { clear(); @@ -104,7 +109,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) bool ok = true; - ok &= setRsItemHeader(data, tlvsize, 0, tlvsize); + ok &= setRsItemHeader(data, tlvsize, RS_GXS_GRP_META_DATA_VERSION_ID_0002, tlvsize); #ifdef GXS_DEBUG std::cerr << "RsGxsGrpMetaData serialise()" << std::endl; @@ -122,7 +127,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) ok &= setRawUInt32(data, tlvsize, &offset, mGroupFlags); ok &= setRawUInt32(data, tlvsize, &offset, mPublishTs); ok &= setRawUInt32(data, tlvsize, &offset, mCircleType); - ok &= setRawUInt32(data, tlvsize, &offset, mSignFlags); + ok &= setRawUInt32(data, tlvsize, &offset, mAuthenFlags); ok &= mAuthorId.serialise(data, tlvsize, offset); ok &= SetTlvString(data, tlvsize, &offset, 0, mServiceString); ok &= mCircleId.serialise(data, tlvsize, offset); @@ -130,6 +135,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) ok &= signSet.SetTlv(data, tlvsize, &offset); ok &= keys.SetTlv(data, tlvsize, &offset); + ok &= setRawUInt32(data, tlvsize, &offset, mSignFlags); // new in API v2. Was previously missing. Kept in the end for backward compatibility return ok; } @@ -153,13 +159,32 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize) ok &= getRawUInt32(data, pktsize, &offset, &mGroupFlags); ok &= getRawUInt32(data, pktsize, &offset, &mPublishTs); ok &= getRawUInt32(data, pktsize, &offset, &mCircleType); - ok &= getRawUInt32(data, pktsize, &offset, &mSignFlags); + ok &= getRawUInt32(data, pktsize, &offset, &mAuthenFlags); + + ok &= mAuthorId.deserialise(data, pktsize, offset); ok &= GetTlvString(data, pktsize, &offset, 0, mServiceString); ok &= mCircleId.deserialise(data, pktsize, offset); ok &= signSet.GetTlv(data, pktsize, &offset); ok &= keys.GetTlv(data, pktsize, &offset); + + switch(getRsItemId(data)) + { + case RS_GXS_GRP_META_DATA_VERSION_ID_0002: ok &= getRawUInt32(data, pktsize, &offset, &mSignFlags); // current API + break ; + case RS_GXS_GRP_META_DATA_VERSION_ID_0001: mSignFlags = 0; // old API. Do not leave this uninitialised! + break ; + + default: + std::cerr << "(EE) RsGxsGrpMetaData::deserialise(): ERROR: unknown API version " << std::hex << getRsItemId(data) << std::dec << std::endl; + } + + if(offset != pktsize) + { + std::cerr << "(EE) RsGxsGrpMetaData::deserialise(): ERROR: unmatched size " << offset << ", expected: " << pktsize << std::dec << std::endl; + return false ; + } #ifdef DROP_NON_CANONICAL_ITEMS if(mGroupName.length() > RsGxsGrpMetaData::MAX_ALLOWED_STRING_SIZE) { @@ -202,7 +227,8 @@ uint32_t RsGxsMsgMetaData::serial_size() s += signSet.TlvSize(); s += GetTlvStringSize(mMsgName); - s += 4; + s += 4; // mAuthenFlags + s += 4; // mSignFlags s += 4; return s; @@ -239,7 +265,7 @@ bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size) bool ok = true; - ok &= setRsItemHeader(data, tlvsize, 0, tlvsize); + ok &= setRsItemHeader(data, tlvsize, RS_GXS_MSG_META_DATA_VERSION_ID_0001, tlvsize); #ifdef GXS_DEBUG std::cerr << "RsGxsGrpMetaData serialise()" << std::endl; diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index 048d1639f..5352476e2 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -133,11 +133,7 @@ static const int ACTIVE_FRIENDS_UPDATE_PERIOD = 600 ; // 10 minu static const int ACTIVE_FRIENDS_ONLINE_DELAY = 86400*7 ; // 1 week. static const int kReputationRequestPeriod = 600; // 10 mins static const int kReputationStoreWait = 180; // 3 minutes. - static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed -static const float REPUTATION_PGP_LINKED_ID_BIAS = 0.2f ; -static const float REPUTATION_PGP_KNOWN_ID_BIAS = 0.3f ; // so known pgp-linked ids go up to +0.5f -static const float REPUTATION_FRIEND_VARIANCE = 3.0f ; p3GxsReputation::p3GxsReputation(p3LinkMgr *lm) From 79c80c968af56b59e44441e699e324cc583a97a2 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 27 Oct 2015 22:41:29 -0400 Subject: [PATCH 16/19] fixed a few bugs in display of tracking info --- libretroshare/src/grouter/groutermatrix.cc | 6 +++++- libretroshare/src/grouter/groutertypes.h | 2 +- libretroshare/src/grouter/p3grouter.cc | 8 +++++--- libretroshare/src/gxs/gxssecurity.cc | 17 +++++++++++++++-- libretroshare/src/gxs/rsgenexchange.cc | 9 ++++----- libretroshare/src/gxs/rsgxsdata.cc | 12 ++++++------ libretroshare/src/services/p3gxsreputation.cc | 6 ++++++ .../gui/gxsforums/GxsForumThreadWidget.cpp | 19 +++++++++++-------- 8 files changed, 53 insertions(+), 26 deletions(-) diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index ffd28df35..4da0d02ed 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -27,7 +27,7 @@ #include "groutermatrix.h" #include "grouteritems.h" -//#define ROUTING_MATRIX_DEBUG +#define ROUTING_MATRIX_DEBUG GRouterMatrix::GRouterMatrix() { @@ -197,6 +197,10 @@ void GRouterMatrix::debugDump() const std::cerr << it->second[i] << " " ; std::cerr << std::endl; } + std::cerr << " Tracking clues: " << std::endl; + + for(std::map::const_iterator it(_tracking_clues.begin());it!=_tracking_clues.end();++it) + std::cerr << " " << it->first << ": from " << it->second.friend_id << " " << now - it->second.time_stamp << " secs ago." << std::endl; } bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::vector& friends, std::vector& probas) const diff --git a/libretroshare/src/grouter/groutertypes.h b/libretroshare/src/grouter/groutertypes.h index 756c75783..3c4897b0a 100644 --- a/libretroshare/src/grouter/groutertypes.h +++ b/libretroshare/src/grouter/groutertypes.h @@ -39,7 +39,7 @@ static const uint16_t GROUTER_CLIENT_ID_MESSAGES = 0x1001 ; static const uint32_t RS_GROUTER_MATRIX_MAX_HIT_ENTRIES = 10 ; // max number of clues to store static const uint32_t RS_GROUTER_MATRIX_MIN_TIME_BETWEEN_HITS = 60 ; // can be set to up to half the publish time interval. Prevents flooding routes. -static const uint32_t RS_GROUTER_MIN_CONFIG_SAVE_PERIOD = 5 ; // at most save config every 5 seconds +static const uint32_t RS_GROUTER_MIN_CONFIG_SAVE_PERIOD = 10 ; // at most save config every 10 seconds static const uint32_t RS_GROUTER_MAX_KEEP_TRACKING_CLUES = 86400*10 ; // max time for which we keep record of tracking info: 10 days. static const float RS_GROUTER_BASE_WEIGHT_ROUTED_MSG = 1.0f ; // base contribution of routed message clue to routing matrix diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index a5b3d6472..8ed41178c 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -1703,9 +1703,10 @@ void p3GRouter::addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& peer_i { RS_STACK_MUTEX(grMtx) ; #ifdef GROUTER_DEBUG - grouter_debug() << "Received new routing clue for key " << id << " from peer " << peer_id << std::endl; + grouter_debug() << "Received new routing clue for key " << mid << " from peer " << peer_id << std::endl; #endif _routing_matrix.addTrackingInfo(mid,peer_id) ; + _changed = true ; } void p3GRouter::addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id) { @@ -1714,6 +1715,7 @@ void p3GRouter::addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id) grouter_debug() << "Received new routing clue for key " << id << " from peer " << peer_id << std::endl; #endif _routing_matrix.addRoutingClue(id,peer_id,RS_GROUTER_BASE_WEIGHT_GXS_PACKET) ; + _changed = true ; } bool p3GRouter::registerClientService(const GRouterServiceId& id,GRouterClientService *service) @@ -2230,8 +2232,8 @@ void p3GRouter::debugDump() grouter_debug() << " Routing matrix: " << std::endl; -// if(_debug_enabled) - // _routing_matrix.debugDump() ; + if(_debug_enabled) + _routing_matrix.debugDump() ; } diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index 6c1474f3f..1895993ee 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -681,12 +681,25 @@ bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& s EVP_VerifyInit(mdctx, EVP_sha1()); EVP_VerifyUpdate(mdctx, allGrpData, allGrpDataLen); int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); + EVP_MD_CTX_destroy(mdctx); - delete[] allGrpData ; + if(signOk != 1) // try previous API. This is a hack to accept groups previously signed with old APIs. + { + EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + + EVP_VerifyInit(mdctx, EVP_sha1()); + EVP_VerifyUpdate(mdctx, allGrpData, allGrpDataLen-4); // that means ommit the last + signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); + EVP_MD_CTX_destroy(mdctx); + + if(signOk) + std::cerr << "(WW) GXS group with old API found. Signature still checks!" << std::endl; + } + + delete[] allGrpData ; /* clean up */ EVP_PKEY_free(signKey); - EVP_MD_CTX_destroy(mdctx); grpMeta.signSet = signSet; diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 59d2025d7..82726b3a3 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -2661,7 +2661,7 @@ void RsGenExchange::processRecvdMessages() { #ifdef GEN_EXCH_DEBUG - std::cerr << "failed to deserialise incoming meta, msgId: " + std::cerr << "Validation failed for message id " << "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; #endif @@ -2795,8 +2795,7 @@ void RsGenExchange::processRecvdGroups() else if(ret == VALIDATE_FAIL) { #ifdef GEN_EXCH_DEBUG - std::cerr << "failed to deserialise incoming meta, grpId: " - << grp->grpId << std::endl; + std::cerr << "failed to validate incoming meta, grpId: " << grp->grpId << ": wrong signature" << std::endl; #endif delete grp; erase = true; @@ -2805,8 +2804,7 @@ void RsGenExchange::processRecvdGroups() { #ifdef GEN_EXCH_DEBUG - std::cerr << "failed to validate incoming grp, trying again. grpId: " - << grp->grpId << std::endl; + std::cerr << "failed to validate incoming grp, trying again. grpId: " << grp->grpId << std::endl; #endif if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS) @@ -2822,6 +2820,7 @@ void RsGenExchange::processRecvdGroups() } else { + std::cerr << "(EE) deserialise error in group meta data" << std::endl; delete grp; delete meta; erase = true; diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index 9de06aa83..927c73dda 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -51,10 +51,11 @@ uint32_t RsGxsGrpMetaData::serial_size() s += GetTlvStringSize(mServiceString); s += signSet.TlvSize(); s += keys.TlvSize(); - s += 4; // for mCircleType + s += 4; // for mCircleType s += mCircleId.serial_size(); - s += 4; // mAuthenFlag - s += mParentGrpId.serial_size(); + s += 4; // mAuthenFlag + s += mParentGrpId.serial_size(); // mParentGroupId + s += 4; // mSignFlag return s; } @@ -227,9 +228,8 @@ uint32_t RsGxsMsgMetaData::serial_size() s += signSet.TlvSize(); s += GetTlvStringSize(mMsgName); - s += 4; // mAuthenFlags - s += 4; // mSignFlags - s += 4; + s += 4; // mPublishTS + s += 4; // mMsgFlags return s; } diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index 5352476e2..c1eef988a 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -216,7 +216,9 @@ void p3GxsReputation::updateIdentityFlags() { RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ +#ifdef DEBUG_REPUTATION std::cerr << "Updating reputation identity flags" << std::endl; +#endif for( std::map::iterator rit = mReputations.begin();rit!=mReputations.end();++rit) if(rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) @@ -229,7 +231,9 @@ void p3GxsReputation::updateIdentityFlags() if(!rsIdentity->getIdDetails(*rit,details)) { +#ifdef DEBUG_REPUTATION std::cerr << " cannot obtain info for " << *rit << ". Will do it later." << std::endl; +#endif continue ; } @@ -247,7 +251,9 @@ void p3GxsReputation::updateIdentityFlags() if(details.mPgpLinked) it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_LINKED ; if(details.mPgpKnown ) it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_KNOWN ; +#ifdef DEBUG_REPUTATION std::cerr << " updated flags for " << *rit << " to " << std::hex << it->second.mIdentityFlags << std::dec << std::endl; +#endif it->second.updateReputation() ; IndicateConfigChanged(); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index eb77bced7..2fe308cb3 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -548,6 +548,17 @@ void GxsForumThreadWidget::changedThread() mThreadId = RsGxsMessageId(item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString()); } + // Show info about who passed on this message. + if(mForumGroup.mMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) + { + RsPeerId providerId ; + std::string msgId = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + RsGxsMessageId mid(msgId) ; + + if(rsGRouter->getTrackingInfo(mid,providerId) && !providerId.isNull() ) + item->setToolTip(COLUMN_THREAD_TITLE,tr("This message was obtained from %1").arg(QString::fromUtf8(rsPeers->getPeerName(providerId).c_str()))); + } + if (mFillThread) { return; } @@ -952,14 +963,6 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum // Set later with GxsIdRSTreeWidgetItem::setId item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_AUTHOR, QString::fromStdString(msg.mMeta.mAuthorId.toStdString())); - // Show info about who passed on this message. - if(mForumGroup.mMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) - { - RsPeerId providerId ; - - if(rsGRouter->getTrackingInfo(msg.mMeta.mMsgId,providerId) && !providerId.isNull() ) - item->setToolTip(COLUMN_THREAD_TITLE,tr("This message was obtained from %1").arg(QString::fromUtf8(rsPeers->getPeerName(providerId).c_str()))); - } //#TODO #if 0 text = QString::fromUtf8(authorName.c_str()); From b04ce5ef1c58a12bdd1341a67b95c39065c51403 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 27 Oct 2015 22:47:02 -0400 Subject: [PATCH 17/19] removed debug info --- libretroshare/src/gxs/rsgenexchange.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 82726b3a3..70d52eb68 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -60,7 +60,7 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key #define GXS_MASK "GXS_MASK_HACK" -#define GEN_EXCH_DEBUG 1 +//#define GEN_EXCH_DEBUG 1 #define MSG_CLEANUP_PERIOD 60*5 // 5 minutes #define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes From a526a29a2b21da6d2d7132697ef842408b36482d Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 27 Oct 2015 23:40:18 -0400 Subject: [PATCH 18/19] added missing flag check for anti-spam feature display --- retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 26e4bf4b1..880ed6ba7 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -180,7 +180,7 @@ void GxsForumsDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, if (IS_GROUP_ADMIN(groupInfo.mSubscribeFlags)) groupItemInfo.icon = QIcon(":images/konv_message2.png"); - else if (IS_GROUP_PGP_AUTHED(groupInfo.mSignFlags)) + else if ((IS_GROUP_PGP_AUTHED(groupInfo.mSignFlags)) || (IS_GROUP_MESSAGE_TRACKING(groupInfo.mSignFlags)) ) groupItemInfo.icon = QIcon(":images/konv_message3.png"); } From 1471dbc8af9a410ad2678b90b9c81ff9347dcd91 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 27 Oct 2015 23:53:31 -0400 Subject: [PATCH 19/19] fixed tooltips for anti-spam forum features --- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index be2e0f85f..fa0f2e93f 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -552,7 +552,7 @@ - <html><head/><body><p>This makes the media increase the reputation threshold to 0.4 for anonymous ids,</p><p>while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation </p><p>score is above that threshold.</p></body></html> + <html><head/><body><p>This makes the media increase the reputation threshold to 0.4 for anonymous ids, while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation score is above that threshold.</p></body></html> Favor PGP-signed ids @@ -562,7 +562,7 @@ - <html><head/><body><p align="justify">This feature allows Retroshare to locally keep a record of who</p><p align="justify">forwarded each message to you, for the last 10 days. Although useless if alone (and already</p><p align="justify">available whatsoever) this information can be used by a group</p><p align="justify">of collaborative friends to easily locate the source of spams. To be used with care,</p><p align="justify">since it significantly decreases the anonymity of message posts.</p></body></html> + <html><head/><body><p align="justify">This feature allows Retroshare to locally keep a record of who forwarded each message to you, for the last 10 days. Although useless if alone (and already available whatsoever) this information can be used by a group of collaborative friends to easily locate the source of spams. To be used with care, since it significantly decreases the anonymity of message posts.</p></body></html> Keep track of posts