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;