mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
simplied/improved reputation system. Now ids can be banned based on their owner node using a single checkbox in the Person tab, with immediate effect
This commit is contained in:
parent
c4ef4d7743
commit
7545ad4d11
@ -50,12 +50,13 @@ public:
|
||||
};
|
||||
|
||||
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;
|
||||
virtual bool getReputationInfo(const RsGxsId& id,const RsPgpId& owner_id,ReputationInfo& info) =0 ;
|
||||
virtual bool getReputationInfo(const RsGxsId& id, const RsPgpId &ownerNode, ReputationInfo& info) =0;
|
||||
|
||||
// parameters
|
||||
|
||||
virtual void setNodeAutoBanThreshold(uint32_t n) =0;
|
||||
virtual uint32_t nodeAutoBanThreshold() =0;
|
||||
// virtual void setNodeAutoBanThreshold(uint32_t n) =0;
|
||||
// virtual uint32_t nodeAutoBanThreshold() =0;
|
||||
|
||||
virtual void setNodeAutoPositiveOpinionForContacts(bool b) =0;
|
||||
virtual bool nodeAutoPositiveOpinionForContacts() =0;
|
||||
virtual float nodeAutoBanIdentitiesLimit() =0;
|
||||
@ -64,7 +65,10 @@ public:
|
||||
// This one is a proxy designed to allow fast checking of a GXS id.
|
||||
// it basically returns true if assessment is not ASSESSMENT_OK
|
||||
|
||||
virtual bool isIdentityBanned(const RsGxsId& id,const RsPgpId& owner_node) =0;
|
||||
virtual bool isIdentityBanned(const RsGxsId& id) =0;
|
||||
|
||||
virtual bool isNodeBanned(const RsPgpId& id) =0;
|
||||
virtual void banNode(const RsPgpId& id,bool b) =0;
|
||||
};
|
||||
|
||||
// To access reputations from anywhere
|
||||
|
@ -74,6 +74,11 @@ void RsGxsReputationUpdateItem::clear()
|
||||
mOpinions.clear() ;
|
||||
}
|
||||
|
||||
void RsGxsReputationBannedNodeSetItem::clear()
|
||||
{
|
||||
mKnownIdentities.TlvClear();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
@ -128,6 +133,17 @@ std::ostream& RsGxsReputationRequestItem::print(std::ostream &out, uint16_t inde
|
||||
printRsItemEnd(out, "RsReputationRequestItem", indent);
|
||||
return out;
|
||||
}
|
||||
std::ostream& RsGxsReputationBannedNodeSetItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsReputationBannedNodeSetItem", indent);
|
||||
|
||||
out << "last update: " << time(NULL) - mLastActivityTS << " secs ago." << std::endl;
|
||||
out << "PGP id: " << mPgpId << std::endl;
|
||||
out << "Known ids: " << mKnownIdentities.ids.size() << std::endl;
|
||||
|
||||
printRsItemEnd(out, "RsReputationRequestItem", indent);
|
||||
return out;
|
||||
}
|
||||
/*************************************************************************/
|
||||
|
||||
uint32_t RsGxsReputationConfigItem::serial_size() const
|
||||
@ -135,8 +151,8 @@ uint32_t RsGxsReputationConfigItem::serial_size() const
|
||||
uint32_t s = 8; /* header */
|
||||
|
||||
s += mPeerId.serial_size() ; // PeerId
|
||||
s += 4 ; // mLatestUpdate
|
||||
s += 4 ; // mLastQuery
|
||||
s += 4 ; // mLatestUpdate
|
||||
s += 4 ; // mLastQuery
|
||||
|
||||
return s ;
|
||||
}
|
||||
@ -158,6 +174,17 @@ uint32_t RsGxsReputationSetItem::serial_size() const
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsGxsReputationBannedNodeSetItem::serial_size() const
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
|
||||
s += RsPgpId::serial_size() ; // mPgpId
|
||||
s += 4 ; // mLastActivityTS;
|
||||
s += mKnownIdentities.TlvSize(); // mKnownIdentities
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsGxsReputationUpdateItem::serial_size() const
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
@ -236,6 +263,29 @@ bool RsGxsReputationSetItem::serialise(void *data, uint32_t& pktsize) const
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsGxsReputationBannedNodeSetItem::serialise(void *data, uint32_t& pktsize) const
|
||||
{
|
||||
uint32_t tlvsize ;
|
||||
uint32_t offset=0;
|
||||
|
||||
if(!serialise_header(data,pktsize,tlvsize,offset))
|
||||
return false ;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= mPgpId.serialise(data, tlvsize, offset) ;
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, mLastActivityTS);
|
||||
ok &= mKnownIdentities.SetTlv(data, tlvsize, &offset) ;
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsGxsReputationSetItem::serialisedata() size error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsGxsReputationUpdateItem::serialise(void *data, uint32_t& pktsize) const
|
||||
{
|
||||
uint32_t tlvsize ;
|
||||
@ -308,7 +358,28 @@ RsGxsReputationConfigItem *RsGxsReputationSerialiser::deserialiseReputationConfi
|
||||
|
||||
return item;
|
||||
}
|
||||
RsGxsReputationBannedNodeSetItem *RsGxsReputationSerialiser::deserialiseReputationBannedNodeSetItem(void *data,uint32_t size)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
bool ok = true ;
|
||||
|
||||
RsGxsReputationBannedNodeSetItem *item = new RsGxsReputationBannedNodeSetItem() ;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= item->mPgpId.deserialise(data, size, offset) ;
|
||||
ok &= getRawUInt32(data, size, &offset, &item->mLastActivityTS);
|
||||
ok &= item->mKnownIdentities.GetTlv(data,size,&offset) ;
|
||||
|
||||
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_deprecated(void *data,uint32_t tlvsize)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
@ -462,11 +533,12 @@ 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_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);
|
||||
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_BANNED_NODE_SET_ITEM: return deserialiseReputationBannedNodeSetItem(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;
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "serialiser/rsserviceids.h"
|
||||
#include "serialiser/rsserial.h"
|
||||
#include "serialiser/rstlvidset.h"
|
||||
#include "retroshare/rsgxsifacetypes.h"
|
||||
|
||||
#define RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM 0x01
|
||||
@ -38,6 +39,7 @@
|
||||
#define RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM 0x04
|
||||
#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM_deprecated 0x05
|
||||
#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM 0x06
|
||||
#define RS_PKT_SUBTYPE_GXS_REPUTATION_BANNED_NODE_SET_ITEM 0x07
|
||||
|
||||
/**************************************************************************/
|
||||
class RsReputationItem: public RsItem
|
||||
@ -118,6 +120,24 @@ public:
|
||||
RsPgpId mOwnerNodeId;
|
||||
std::map<RsPeerId, uint32_t> mOpinions; // RsPeerId -> Opinion.
|
||||
};
|
||||
|
||||
class RsGxsReputationBannedNodeSetItem: public RsReputationItem
|
||||
{
|
||||
public:
|
||||
RsGxsReputationBannedNodeSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_BANNED_NODE_SET_ITEM) {}
|
||||
|
||||
virtual ~RsGxsReputationBannedNodeSetItem() {}
|
||||
virtual void clear();
|
||||
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) const ;
|
||||
virtual uint32_t serial_size() const ;
|
||||
|
||||
RsPgpId mPgpId ;
|
||||
uint32_t mLastActivityTS ;
|
||||
RsTlvGxsIdSet mKnownIdentities ;
|
||||
};
|
||||
|
||||
class RsGxsReputationUpdateItem: public RsReputationItem
|
||||
{
|
||||
public:
|
||||
@ -173,6 +193,7 @@ private:
|
||||
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);
|
||||
static RsGxsReputationBannedNodeSetItem *deserialiseReputationBannedNodeSetItem (void *data, uint32_t size);
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
@ -139,6 +139,7 @@ static const uint32_t PGP_AUTO_BAN_THRESHOLD_DEFAULT = 2 ; // above t
|
||||
static const uint32_t IDENTITY_FLAGS_UPDATE_DELAY = 100 ; //
|
||||
static const uint32_t BANNED_NODES_UPDATE_DELAY = 313 ; // update approx every 5 mins. Chosen to not be a multiple of IDENTITY_FLAGS_UPDATE_DELAY
|
||||
static const uint32_t REPUTATION_INFO_KEEP_DELAY = 86400*35; // remove old reputation info 5 days after last usage limit, in case the ID would come back..
|
||||
static const uint32_t BANNED_NODES_INACTIVITY_KEEP = 86400*60; // remove all info about banned nodes after 2 months of inactivity
|
||||
|
||||
p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
||||
:p3Service(), p3Config(),
|
||||
@ -146,7 +147,7 @@ p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
||||
{
|
||||
addSerialType(new RsGxsReputationSerialiser());
|
||||
|
||||
mPgpAutoBanThreshold = PGP_AUTO_BAN_THRESHOLD_DEFAULT ;
|
||||
//mPgpAutoBanThreshold = PGP_AUTO_BAN_THRESHOLD_DEFAULT ;
|
||||
mRequestTime = 0;
|
||||
mStoreTime = 0;
|
||||
mReputationsUpdated = false;
|
||||
@ -154,6 +155,7 @@ p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
||||
mLastIdentityFlagsUpdate = time(NULL) - 3;
|
||||
mAverageActiveFriends = 0 ;
|
||||
mLastBannedNodesUpdate = 0 ;
|
||||
mBannedNodesProxyNeedsUpdate = false;
|
||||
|
||||
mAutoBanIdentitiesLimit = REPUTATION_ASSESSMENT_THRESHOLD_X1;
|
||||
mAutoSetPositiveOptionToContacts = true; // default
|
||||
@ -200,9 +202,15 @@ int p3GxsReputation::tick()
|
||||
if(now > BANNED_NODES_UPDATE_DELAY+mLastBannedNodesUpdate) // 613 is not a multiple of 100, to avoid piling up work
|
||||
{
|
||||
updateIdentityFlags() ; // needed before updateBannedNodesList!
|
||||
updateBannedNodesList();
|
||||
updateBannedNodesProxy();
|
||||
mLastBannedNodesUpdate = now ;
|
||||
}
|
||||
|
||||
if(mBannedNodesProxyNeedsUpdate)
|
||||
{
|
||||
updateBannedNodesProxy();
|
||||
mBannedNodesProxyNeedsUpdate = false ;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_REPUTATION
|
||||
static time_t last_debug_print = time(NULL) ;
|
||||
@ -216,21 +224,21 @@ int p3GxsReputation::tick()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void p3GxsReputation::setNodeAutoBanThreshold(uint32_t n)
|
||||
{
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
if(n != mPgpAutoBanThreshold)
|
||||
{
|
||||
mLastBannedNodesUpdate = 0 ;
|
||||
mPgpAutoBanThreshold = n ;
|
||||
IndicateConfigChanged() ;
|
||||
}
|
||||
}
|
||||
uint32_t p3GxsReputation::nodeAutoBanThreshold()
|
||||
{
|
||||
return mPgpAutoBanThreshold ;
|
||||
}
|
||||
// void p3GxsReputation::setNodeAutoBanThreshold(uint32_t n)
|
||||
// {
|
||||
// RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
//
|
||||
// if(n != mPgpAutoBanThreshold)
|
||||
// {
|
||||
// mLastBannedNodesUpdate = 0 ;
|
||||
// mPgpAutoBanThreshold = n ;
|
||||
// IndicateConfigChanged() ;
|
||||
// }
|
||||
// }
|
||||
// uint32_t p3GxsReputation::nodeAutoBanThreshold()
|
||||
// {
|
||||
// return mPgpAutoBanThreshold ;
|
||||
// }
|
||||
|
||||
void p3GxsReputation::setNodeAutoPositiveOpinionForContacts(bool b)
|
||||
{
|
||||
@ -284,33 +292,21 @@ class ZeroInitCnt
|
||||
operator uint32_t() const { return cnt ; }
|
||||
};
|
||||
|
||||
void p3GxsReputation::updateBannedNodesList()
|
||||
void p3GxsReputation::updateBannedNodesProxy()
|
||||
{
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << "Updating PGP ban list based on signed GxsIds to ban" << std::endl;
|
||||
#endif
|
||||
std::map<RsGxsId, Reputation> tmpreps ;
|
||||
//#ifdef DEBUG_REPUTATION
|
||||
// std::cerr << "Updating PGP ban list based on signed GxsIds to ban. Ban threshold = " << mPgpAutoBanThreshold << std::endl;
|
||||
//#endif
|
||||
// This function keeps the Banned GXS id proxy up to date.
|
||||
//
|
||||
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
tmpreps = mReputations ;
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
std::map<RsPgpId,ZeroInitCnt> pgp_ids_to_ban ;
|
||||
mPerNodeBannedIdsProxy.clear();
|
||||
|
||||
for( std::map<RsGxsId, Reputation>::iterator rit = tmpreps.begin();rit!=tmpreps.end();++rit)
|
||||
if((rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED) && !rit->second.mOwnerNode.isNull() && rit->second.mOwnOpinion == p3GxsReputation::OPINION_NEGATIVE)
|
||||
++pgp_ids_to_ban[rit->second.mOwnerNode] ;
|
||||
|
||||
mBannedPgpIds.clear() ;
|
||||
|
||||
if(mPgpAutoBanThreshold > 0)
|
||||
for(std::map<RsPgpId,ZeroInitCnt>::const_iterator it(pgp_ids_to_ban.begin());it!=pgp_ids_to_ban.end();++it)
|
||||
{
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << "PGP Id: " << it->first << ". Ban count=" << it->second << " - " << (( it->second >= mPgpAutoBanThreshold)?"Banned!":"OK" ) << std::endl;
|
||||
#endif
|
||||
if(it->second >= mPgpAutoBanThreshold)
|
||||
mBannedPgpIds.insert(it->first) ;
|
||||
}
|
||||
for( std::map<RsPgpId, BannedNodeInfo>::iterator rit = mBannedPgpIds.begin();rit!=mBannedPgpIds.end();++rit)
|
||||
for(std::set<RsGxsId>::const_iterator it(rit->second.known_identities.begin());it!=rit->second.known_identities.end();++it)
|
||||
mPerNodeBannedIdsProxy.insert(*it) ;
|
||||
}
|
||||
|
||||
void p3GxsReputation::updateIdentityFlags()
|
||||
@ -326,7 +322,7 @@ void p3GxsReputation::updateIdentityFlags()
|
||||
#endif
|
||||
|
||||
for( std::map<RsGxsId, Reputation>::iterator rit = mReputations.begin();rit!=mReputations.end();++rit)
|
||||
if(rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE)
|
||||
if( (rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) && (mPerNodeBannedIdsProxy.find(rit->first) == mPerNodeBannedIdsProxy.end()))
|
||||
to_update.push_back(rit->first) ;
|
||||
}
|
||||
|
||||
@ -387,9 +383,9 @@ void p3GxsReputation::cleanup()
|
||||
#endif
|
||||
std::cerr << "p3GxsReputation::cleanup() " << std::endl;
|
||||
|
||||
// remove optionions about identities that do not exist anymore. That will in particular avoid asking p3idservice about deleted
|
||||
// identities, which would cause an excess of hits to the database.
|
||||
// We do it in two steps to avoid a deadlock when calling rsIdentity from here.
|
||||
// Remove opinions about identities that do not exist anymore. That will in particular avoid asking p3idservice about deleted
|
||||
// identities, which would cause an excess of hits to the database. We do it in two steps to avoid a deadlock when calling rsIdentity from here.
|
||||
// Also, neutral opinions for banned PGP linked nodes are kept, so as to be able to not request them again.
|
||||
|
||||
bool updated = false ;
|
||||
time_t now = time(NULL) ;
|
||||
@ -400,15 +396,15 @@ void p3GxsReputation::cleanup()
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
for(std::map<RsGxsId,Reputation>::iterator it(mReputations.begin());it!=mReputations.end();)
|
||||
if(it->second.mOpinions.empty() && it->second.mOwnOpinion == RsReputations::OPINION_NEUTRAL)
|
||||
if(it->second.mOpinions.empty() && it->second.mOwnOpinion == RsReputations::OPINION_NEUTRAL && (it->second.mOwnerNode.isNull()))
|
||||
{
|
||||
std::map<RsGxsId,Reputation>::iterator tmp(it) ;
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << " ID " << it->first << ": own is neutral and no opinions from friends => remove entry" << std::endl;
|
||||
#endif
|
||||
std::map<RsGxsId,Reputation>::iterator tmp(it) ;
|
||||
++tmp ;
|
||||
mReputations.erase(it) ;
|
||||
it = tmp ;
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << " ID " << it->first << ": own is neutral and no opinions from friends => remove entry" << std::endl;
|
||||
#endif
|
||||
updated = true ;
|
||||
}
|
||||
else
|
||||
@ -424,12 +420,31 @@ void p3GxsReputation::cleanup()
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << " Identity " << *it << " has a last usage TS of " << now - rsIdentity->getLastUsageTS(*it) << " secs ago: deleting it." << std::endl;
|
||||
#endif
|
||||
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
mReputations.erase(*it) ;
|
||||
updated = true ;
|
||||
}
|
||||
|
||||
{
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
for(std::map<RsPgpId,BannedNodeInfo>::iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();)
|
||||
if(it->second.last_activity_TS + BANNED_NODES_INACTIVITY_KEEP < now)
|
||||
{
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << " Removing all info about banned node " << it->first << " by lack of activity." << std::endl;
|
||||
#endif
|
||||
std::map<RsPgpId,BannedNodeInfo>::iterator tmp(it ) ;
|
||||
++tmp ;
|
||||
mBannedPgpIds.erase(it) ;
|
||||
it = tmp ;
|
||||
|
||||
updated = true ;
|
||||
}
|
||||
else
|
||||
++it ;
|
||||
}
|
||||
|
||||
if(updated)
|
||||
IndicateConfigChanged() ;
|
||||
}
|
||||
@ -762,37 +777,63 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,time_t latest_update)
|
||||
* Opinion
|
||||
****/
|
||||
|
||||
bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& owner_id, RsReputations::ReputationInfo& info)
|
||||
bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& ownerNode, RsReputations::ReputationInfo& info)
|
||||
{
|
||||
if(gxsid.isNull())
|
||||
return false ;
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
#ifdef DEBUG_REPUTATION
|
||||
#ifdef DEBUG_REPUTATION2
|
||||
std::cerr << "getReputationInfo() for " << gxsid << std::endl;
|
||||
#endif
|
||||
std::map<RsGxsId,Reputation>::const_iterator it = mReputations.find(gxsid) ;
|
||||
std::map<RsGxsId,Reputation>::iterator it = mReputations.find(gxsid) ;
|
||||
RsPgpId owner_id ;
|
||||
|
||||
if(it == mReputations.end())
|
||||
{
|
||||
info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ;
|
||||
info.mOverallReputationScore = RsReputations::REPUTATION_THRESHOLD_DEFAULT ;
|
||||
info.mFriendAverage = REPUTATION_THRESHOLD_DEFAULT ;
|
||||
info.mFriendAverage = REPUTATION_THRESHOLD_DEFAULT ;
|
||||
|
||||
owner_id = ownerNode ;
|
||||
}
|
||||
else
|
||||
{
|
||||
const Reputation& rep(it->second) ;
|
||||
Reputation& rep(it->second) ;
|
||||
|
||||
info.mOwnOpinion = RsReputations::Opinion(rep.mOwnOpinion) ;
|
||||
info.mOverallReputationScore = rep.mReputation ;
|
||||
info.mFriendAverage = rep.mFriendAverage ;
|
||||
|
||||
if(rep.mOwnerNode.isNull())
|
||||
rep.mOwnerNode = ownerNode ;
|
||||
|
||||
owner_id = rep.mOwnerNode ;
|
||||
}
|
||||
|
||||
if(!owner_id.isNull() && (mBannedPgpIds.find(owner_id) != mBannedPgpIds.end()))
|
||||
std::map<RsPgpId,BannedNodeInfo>::iterator it2 ;
|
||||
|
||||
if(!owner_id.isNull() && (it2 = mBannedPgpIds.find(owner_id))!=mBannedPgpIds.end())
|
||||
{
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned." << std::endl;
|
||||
if(it2->second.known_identities.find(gxsid) == it2->second.known_identities.end())
|
||||
{
|
||||
it2->second.known_identities.insert(gxsid) ;
|
||||
it2->second.last_activity_TS = now ;
|
||||
mBannedNodesProxyNeedsUpdate = true ;
|
||||
}
|
||||
|
||||
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
|
||||
#ifdef DEBUG_REPUTATION2
|
||||
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in banned nodes list)." << std::endl;
|
||||
#endif
|
||||
}
|
||||
else if(mPerNodeBannedIdsProxy.find(gxsid) != mPerNodeBannedIdsProxy.end())
|
||||
{
|
||||
#ifdef DEBUG_REPUTATION2
|
||||
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in proxy)." << std::endl;
|
||||
#endif
|
||||
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
|
||||
}
|
||||
@ -801,18 +842,46 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
|
||||
else
|
||||
info.mAssessment = RsReputations::ASSESSMENT_OK ;
|
||||
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", overall score=" << info.mAssessment << std::endl;
|
||||
#ifdef DEBUG_REPUTATION2
|
||||
std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", owner node=" << owner_id << ", overall score=" << info.mAssessment << std::endl;
|
||||
#endif
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3GxsReputation::isIdentityBanned(const RsGxsId &id,const RsPgpId& owner_node)
|
||||
void p3GxsReputation::banNode(const RsPgpId& id,bool b)
|
||||
{
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
if(b)
|
||||
{
|
||||
if(mBannedPgpIds.find(id) == mBannedPgpIds.end())
|
||||
{
|
||||
mBannedPgpIds[id] = BannedNodeInfo() ;
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mBannedPgpIds.find(id) != mBannedPgpIds.end())
|
||||
{
|
||||
mBannedPgpIds.erase(id) ;
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
bool p3GxsReputation::isNodeBanned(const RsPgpId& id)
|
||||
{
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
return mBannedPgpIds.find(id) != mBannedPgpIds.end();
|
||||
}
|
||||
|
||||
bool p3GxsReputation::isIdentityBanned(const RsGxsId &id)
|
||||
{
|
||||
RsReputations::ReputationInfo info ;
|
||||
|
||||
if(!getReputationInfo(id,owner_node,info))
|
||||
if(!getReputationInfo(id,RsPgpId(),info))
|
||||
return false ;
|
||||
|
||||
#ifdef DEBUG_REPUTATION
|
||||
@ -943,12 +1012,23 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
|
||||
savelist.push_back(item);
|
||||
count++;
|
||||
}
|
||||
|
||||
for(std::map<RsPgpId,BannedNodeInfo>::const_iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();++it)
|
||||
{
|
||||
RsGxsReputationBannedNodeSetItem *item = new RsGxsReputationBannedNodeSetItem();
|
||||
|
||||
item->mPgpId = it->first ;
|
||||
item->mLastActivityTS = it->second.last_activity_TS;
|
||||
item->mKnownIdentities.ids = it->second.known_identities;
|
||||
|
||||
savelist.push_back(item) ;
|
||||
}
|
||||
|
||||
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
|
||||
RsTlvKeyValue kv;
|
||||
kv.key = "AUTO_BAN_NODES_THRESHOLD" ;
|
||||
rs_sprintf(kv.value, "%d", mPgpAutoBanThreshold);
|
||||
vitem->tlvkvs.pairs.push_back(kv) ;
|
||||
// kv.key = "AUTO_BAN_NODES_THRESHOLD" ;
|
||||
// rs_sprintf(kv.value, "%d", mPgpAutoBanThreshold);
|
||||
// vitem->tlvkvs.pairs.push_back(kv) ;
|
||||
|
||||
kv.key = "AUTO_BAN_IDENTITIES_THRESHOLD" ;
|
||||
rs_sprintf(kv.value, "%f", mAutoBanIdentitiesLimit);
|
||||
@ -971,7 +1051,7 @@ void p3GxsReputation::saveDone()
|
||||
bool p3GxsReputation::loadList(std::list<RsItem *>& loadList)
|
||||
{
|
||||
#ifdef DEBUG_REPUTATION
|
||||
std::cerr << "p3GxsReputation::saveList()" << std::endl;
|
||||
std::cerr << "p3GxsReputation::loadList()" << std::endl;
|
||||
#endif
|
||||
std::list<RsItem *>::iterator it;
|
||||
std::set<RsPeerId> peerSet;
|
||||
@ -990,28 +1070,39 @@ bool p3GxsReputation::loadList(std::list<RsItem *>& loadList)
|
||||
config.mLatestUpdate = item->mLatestUpdate;
|
||||
config.mLastQuery = 0;
|
||||
|
||||
peerSet.insert(peerId);
|
||||
peerSet.insert(peerId);
|
||||
}
|
||||
|
||||
RsGxsReputationSetItem *set = dynamic_cast<RsGxsReputationSetItem *>(*it);
|
||||
|
||||
if (set)
|
||||
loadReputationSet(set, peerSet);
|
||||
|
||||
|
||||
RsGxsReputationBannedNodeSetItem *itm2 = dynamic_cast<RsGxsReputationBannedNodeSetItem*>(*it) ;
|
||||
|
||||
if(itm2 != NULL)
|
||||
{
|
||||
BannedNodeInfo& info(mBannedPgpIds[itm2->mPgpId]) ;
|
||||
info.last_activity_TS = itm2->mLastActivityTS ;
|
||||
info.known_identities = itm2->mKnownIdentities.ids ;
|
||||
}
|
||||
|
||||
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet *>(*it);
|
||||
|
||||
if(vitem)
|
||||
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
|
||||
{
|
||||
if(kit->key == "AUTO_BAN_NODES_THRESHOLD")
|
||||
{
|
||||
int val ;
|
||||
if (sscanf(kit->value.c_str(), "%d", &val) == 1)
|
||||
{
|
||||
mPgpAutoBanThreshold = val ;
|
||||
std::cerr << "Setting AutoBanNode threshold to " << val << std::endl ;
|
||||
mLastBannedNodesUpdate = 0 ; // force update
|
||||
}
|
||||
};
|
||||
// if(kit->key == "AUTO_BAN_NODES_THRESHOLD")
|
||||
// {
|
||||
// int val ;
|
||||
// if (sscanf(kit->value.c_str(), "%d", &val) == 1)
|
||||
// {
|
||||
// mPgpAutoBanThreshold = val ;
|
||||
// std::cerr << "Setting AutoBanNode threshold to " << val << std::endl ;
|
||||
// mLastBannedNodesUpdate = 0 ; // force update
|
||||
// }
|
||||
// };
|
||||
if(kit->key == "AUTO_BAN_IDENTITIES_THRESHOLD")
|
||||
{
|
||||
float val ;
|
||||
@ -1034,53 +1125,62 @@ bool p3GxsReputation::loadList(std::list<RsItem *>& loadList)
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
updateBannedNodesProxy();
|
||||
loadList.clear() ;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std::set<RsPeerId> &peerSet)
|
||||
{
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
{
|
||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
std::map<RsGxsId, Reputation>::iterator rit;
|
||||
std::map<RsGxsId, Reputation>::iterator rit;
|
||||
|
||||
if(item->mGxsId.isNull()) // just a protection against potential errors having put 00000 into ids.
|
||||
if(item->mGxsId.isNull()) // just a protection against potential errors having put 00000 into ids.
|
||||
return false ;
|
||||
|
||||
/* find matching Reputation */
|
||||
RsGxsId gxsId(item->mGxsId);
|
||||
rit = mReputations.find(gxsId);
|
||||
if (rit != mReputations.end())
|
||||
{
|
||||
std::cerr << "ERROR";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
Reputation &reputation = mReputations[gxsId];
|
||||
/* find matching Reputation */
|
||||
RsGxsId gxsId(item->mGxsId);
|
||||
rit = mReputations.find(gxsId);
|
||||
if (rit != mReputations.end())
|
||||
{
|
||||
std::cerr << "ERROR";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
// install opinions.
|
||||
std::map<RsPeerId, uint32_t>::const_iterator oit;
|
||||
for(oit = item->mOpinions.begin(); oit != item->mOpinions.end(); ++oit)
|
||||
{
|
||||
// expensive ... but necessary.
|
||||
RsPeerId peerId(oit->first);
|
||||
if (peerSet.end() != peerSet.find(peerId))
|
||||
reputation.mOpinions[peerId] = safe_convert_uint32t_to_opinion(oit->second);
|
||||
}
|
||||
Reputation &reputation = mReputations[gxsId];
|
||||
|
||||
reputation.mOwnOpinion = item->mOwnOpinion;
|
||||
reputation.mOwnOpinionTs = item->mOwnOpinionTS;
|
||||
reputation.mOwnerNode = item->mOwnerNodeId;
|
||||
// install opinions.
|
||||
std::map<RsPeerId, uint32_t>::const_iterator oit;
|
||||
for(oit = item->mOpinions.begin(); oit != item->mOpinions.end(); ++oit)
|
||||
{
|
||||
// expensive ... but necessary.
|
||||
RsPeerId peerId(oit->first);
|
||||
if (peerSet.end() != peerSet.find(peerId))
|
||||
reputation.mOpinions[peerId] = safe_convert_uint32t_to_opinion(oit->second);
|
||||
}
|
||||
|
||||
// if dropping entries has changed the score -> must update.
|
||||
|
||||
//float old_reputation = reputation.mReputation ;
|
||||
//mUpdatedReputations.insert(gxsId) ;
|
||||
|
||||
reputation.updateReputation() ;
|
||||
reputation.mOwnOpinion = item->mOwnOpinion;
|
||||
reputation.mOwnOpinionTs = item->mOwnOpinionTS;
|
||||
reputation.mOwnerNode = item->mOwnerNodeId;
|
||||
reputation.mIdentityFlags = item->mIdentityFlags | REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE;
|
||||
|
||||
mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId));
|
||||
return true;
|
||||
// if dropping entries has changed the score -> must update.
|
||||
|
||||
//float old_reputation = reputation.mReputation ;
|
||||
//mUpdatedReputations.insert(gxsId) ;
|
||||
|
||||
reputation.updateReputation() ;
|
||||
|
||||
mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId));
|
||||
}
|
||||
#ifdef DEBUG_REPUTATION
|
||||
RsReputations::ReputationInfo info ;
|
||||
getReputationInfo(item->mGxsId,item->mOwnerNodeId,info) ;
|
||||
std::cerr << item->mGxsId << " : own: " << info.mOwnOpinion << ", owner node: " << item->mOwnerNodeId << ", assessment: " << ((info.mAssessment==ASSESSMENT_BAD)?"BAD":"OK") << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1260,16 +1360,33 @@ void p3GxsReputation::debug_print()
|
||||
{
|
||||
std::cerr << "Reputations database: " << std::endl;
|
||||
std::cerr << " Average number of peers: " << mAverageActiveFriends << std::endl;
|
||||
|
||||
std::cerr << " GXS ID data: " << std::endl;
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
|
||||
for(std::map<RsGxsId,Reputation>::const_iterator it(mReputations.begin());it!=mReputations.end();++it)
|
||||
{
|
||||
std::cerr << " ID=" << it->first << ", own: " << it->second.mOwnOpinion << ", Friend average: " << it->second.mFriendAverage << ", global_score: " << it->second.mReputation
|
||||
<< ", last own update: " << now - it->second.mOwnOpinionTs << " secs ago." << std::endl;
|
||||
|
||||
for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2)
|
||||
std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion << ", Friend average: " << it->second.mFriendAverage << ", global_score: " << it->second.mReputation
|
||||
<< ", last own update: " << now - it->second.mOwnOpinionTs << " secs ago." << std::endl;
|
||||
#ifdef DEBUG_REPUTATION2
|
||||
for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2)
|
||||
std::cerr << " " << it2->first << ": " << it2->second << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::cerr << " Banned RS nodes by ID: " << std::endl;
|
||||
|
||||
for(std::map<RsPgpId,BannedNodeInfo>::const_iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();++it)
|
||||
{
|
||||
std::cerr << " Node " << it->first << ", last activity: " << now - it->second.last_activity_TS << " secs ago." << std::endl;
|
||||
|
||||
for(std::set<RsGxsId>::const_iterator it2(it->second.known_identities.begin());it2!=it->second.known_identities.end();++it2)
|
||||
std::cerr << " " << *it2 << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << " Per node Banned GXSIds proxy: " << std::endl;
|
||||
|
||||
for(std::set<RsGxsId>::const_iterator it(mPerNodeBannedIdsProxy.begin());it!=mPerNodeBannedIdsProxy.end();++it)
|
||||
std::cerr << " " << *it << std::endl;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,12 @@ public:
|
||||
time_t mLastQuery;
|
||||
};
|
||||
|
||||
struct BannedNodeInfo
|
||||
{
|
||||
time_t last_activity_TS ; // updated everytime a node or one of its former identities is required
|
||||
std::set<RsGxsId> known_identities ; // list of known identities from this node. This is kept for a while, and useful in order to avoid re-asking these keys.
|
||||
};
|
||||
|
||||
class Reputation
|
||||
{
|
||||
public:
|
||||
@ -77,7 +83,7 @@ public:
|
||||
float mFriendAverage ;
|
||||
float mReputation;
|
||||
|
||||
RsPgpId mOwnerNode;
|
||||
RsPgpId mOwnerNode;
|
||||
|
||||
uint32_t mIdentityFlags;
|
||||
};
|
||||
@ -97,11 +103,15 @@ public:
|
||||
|
||||
/***** Interface for RsReputations *****/
|
||||
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ;
|
||||
virtual bool getReputationInfo(const RsGxsId& id, const RsPgpId &owner_id, ReputationInfo& info) ;
|
||||
virtual bool isIdentityBanned(const RsGxsId& id, const RsPgpId &owner_node) ;
|
||||
virtual bool getReputationInfo(const RsGxsId& id, const RsPgpId &ownerNode, ReputationInfo& info) ;
|
||||
virtual bool isIdentityBanned(const RsGxsId& id) ;
|
||||
|
||||
virtual bool isNodeBanned(const RsPgpId& id);
|
||||
virtual void banNode(const RsPgpId& id,bool b) ;
|
||||
|
||||
//virtual void setNodeAutoBanThreshold(uint32_t n) ;
|
||||
//virtual uint32_t nodeAutoBanThreshold() ;
|
||||
|
||||
virtual void setNodeAutoBanThreshold(uint32_t n) ;
|
||||
virtual uint32_t nodeAutoBanThreshold() ;
|
||||
virtual void setNodeAutoPositiveOpinionForContacts(bool b) ;
|
||||
virtual bool nodeAutoPositiveOpinionForContacts() ;
|
||||
virtual float nodeAutoBanIdentitiesLimit() ;
|
||||
@ -129,7 +139,8 @@ private:
|
||||
bool RecvReputations(RsGxsReputationUpdateItem *item);
|
||||
bool updateLatestUpdate(RsPeerId peerid, time_t latest_update);
|
||||
void updateActiveFriends() ;
|
||||
void updateBannedNodesList();
|
||||
|
||||
void updateBannedNodesProxy();
|
||||
|
||||
// internal update of data. Takes care of cleaning empty boxes.
|
||||
void locked_updateOpinion(const RsPeerId &from, const RsGxsId &about, RsReputations::Opinion op);
|
||||
@ -167,8 +178,10 @@ private:
|
||||
std::set<RsGxsId> mUpdatedReputations;
|
||||
|
||||
// PGP Ids auto-banned. This is updated regularly.
|
||||
std::set<RsPgpId> mBannedPgpIds ;
|
||||
uint32_t mPgpAutoBanThreshold ;
|
||||
std::map<RsPgpId,BannedNodeInfo> mBannedPgpIds ;
|
||||
std::set<RsGxsId> mPerNodeBannedIdsProxy ;
|
||||
//uint32_t mPgpAutoBanThreshold ;
|
||||
bool mBannedNodesProxyNeedsUpdate ;
|
||||
};
|
||||
|
||||
#endif //SERVICE_RSGXSREPUTATION_HEADER
|
||||
|
@ -51,16 +51,16 @@
|
||||
* #define GXSID_GEN_DUMMY_DATA 1
|
||||
****/
|
||||
|
||||
#define ID_REQUEST_LIST 0x0001
|
||||
#define ID_REQUEST_IDENTITY 0x0002
|
||||
#define ID_REQUEST_LIST 0x0001
|
||||
#define ID_REQUEST_IDENTITY 0x0002
|
||||
#define ID_REQUEST_REPUTATION 0x0003
|
||||
#define ID_REQUEST_OPINION 0x0004
|
||||
#define ID_REQUEST_OPINION 0x0004
|
||||
|
||||
#define GXSID_MAX_CACHE_SIZE 5000
|
||||
|
||||
// unused keys are deleted according to some heuristic that should favor known keys, signed keys etc.
|
||||
|
||||
static const time_t MAX_KEEP_KEYS_BANNED = 2 * 86400 ; // get rid of banned ids after 2 days. That gives a chance to un-ban someone before he gets kicked out
|
||||
static const time_t MAX_KEEP_KEYS_BANNED = 1 * 86400 ; // get rid of banned ids after 1 days. That gives a chance to un-ban someone before he gets definitely kicked out
|
||||
static const time_t MAX_KEEP_KEYS_DEFAULT = 5 * 86400 ; // default for unsigned identities: 5 days
|
||||
static const time_t MAX_KEEP_KEYS_SIGNED = 8 * 86400 ; // signed identities by unknown key
|
||||
static const time_t MAX_KEEP_KEYS_SIGNED_KNOWN = 30 * 86400 ; // signed identities by known node keys
|
||||
@ -324,7 +324,7 @@ public:
|
||||
time_t now = time(NULL);
|
||||
const RsGxsId& gxs_id = entry.details.mId ;
|
||||
|
||||
bool is_id_banned = rsReputations->isIdentityBanned(gxs_id,entry.details.mPgpId) ;
|
||||
bool is_id_banned = rsReputations->isIdentityBanned(gxs_id) ;
|
||||
bool is_own_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID) ;
|
||||
bool is_known_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN) ;
|
||||
bool is_signed_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) ;
|
||||
@ -739,6 +739,18 @@ bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers
|
||||
return true;
|
||||
else
|
||||
{
|
||||
// Normally we should call getIdDetails(), but since the key is not known, we need to digg a possibly old information
|
||||
// from the reputation system, which keeps its own list of banned keys. Of course, the owner ID is not known at this point.
|
||||
|
||||
RsReputations::ReputationInfo info ;
|
||||
rsReputations->getReputationInfo(id,RsPgpId(),info) ;
|
||||
|
||||
if(info.mAssessment == RsReputations::ASSESSMENT_BAD)
|
||||
{
|
||||
std::cerr << "(II) not requesting Key " << id << " because it has been banned." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<RsGxsId,std::list<RsPeerId> >::iterator rit = mIdsNotPresent.find(id) ;
|
||||
|
@ -333,6 +333,7 @@ IdDialog::IdDialog(QWidget *parent) :
|
||||
|
||||
//connect(ui->treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected()));
|
||||
connect(ui->treeWidget_membership, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CircleListCustomPopupMenu(QPoint)));
|
||||
connect(ui->autoBanIdentities_CB, SIGNAL(toggled(bool)), this, SLOT(toggleAutoBanIdentities(bool)));
|
||||
|
||||
|
||||
/* Setup TokenQueue */
|
||||
@ -349,6 +350,17 @@ IdDialog::IdDialog(QWidget *parent) :
|
||||
tmer->start(10000) ; // update every 10 secs.
|
||||
}
|
||||
|
||||
void IdDialog::toggleAutoBanIdentities(bool b)
|
||||
{
|
||||
RsPgpId id(ui->lineEdit_GpgId->text().left(16).toStdString());
|
||||
|
||||
if(!id.isNull())
|
||||
{
|
||||
rsReputations->banNode(id,b) ;
|
||||
requestIdList();
|
||||
}
|
||||
}
|
||||
|
||||
void IdDialog::updateCirclesDisplay()
|
||||
{
|
||||
if(RsAutoUpdatePage::eventsLocked())
|
||||
@ -1676,6 +1688,8 @@ void IdDialog::insertIdDetails(uint32_t token)
|
||||
else
|
||||
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()) + tr(" [unverified]"));
|
||||
|
||||
ui->autoBanIdentities_CB->setVisible(!data.mPgpId.isNull()) ;
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
ui->lineEdit_LastUsed->setText(getHumanReadableDuration(now - data.mLastUsageTS)) ;
|
||||
ui->headerTextLabel_Person->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE));
|
||||
@ -1769,6 +1783,8 @@ void IdDialog::insertIdDetails(uint32_t token)
|
||||
ui->inviteButton->setEnabled(true);
|
||||
}
|
||||
|
||||
ui->autoBanIdentities_CB->setChecked(rsReputations->isNodeBanned(data.mPgpId));
|
||||
|
||||
/* now fill in the reputation information */
|
||||
|
||||
#ifdef SUSPENDED
|
||||
|
@ -77,6 +77,7 @@ private slots:
|
||||
void createExternalCircle();
|
||||
void showEditExistingCircle();
|
||||
void updateCirclesDisplay();
|
||||
void toggleAutoBanIdentities(bool b);
|
||||
|
||||
void acceptCircleSubscription() ;
|
||||
void cancelCircleSubscription() ;
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
<height>872</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -117,7 +117,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
@ -278,7 +278,7 @@
|
||||
<string>Reputation</string>
|
||||
</property>
|
||||
<property name="textAlignment">
|
||||
<set>AlignLeading|AlignVCenter</set>
|
||||
<set>AlignLeft|AlignVCenter</set>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
@ -534,6 +534,13 @@
|
||||
<string>Reputation</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="reputationGroupBoxVLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="autoBanIdentities_CB">
|
||||
<property name="text">
|
||||
<string>Auto-Ban all identities from this node</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="reputationGLayout">
|
||||
<property name="leftMargin">
|
||||
@ -806,8 +813,8 @@ p, li { white-space: pre-wrap; }
|
||||
<tabstop>idTreeWidget</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../images.qrc"/>
|
||||
<include location="../icons.qrc"/>
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -37,11 +37,6 @@ PeoplePage::~PeoplePage()
|
||||
/** Saves the changes on this page */
|
||||
bool PeoplePage::save(QString &/*errmsg*/)
|
||||
{
|
||||
if(!ui.identityBan_CB->isChecked())
|
||||
rsReputations->setNodeAutoBanThreshold(0) ;
|
||||
else
|
||||
rsReputations->setNodeAutoBanThreshold(ui.identityBanThreshold_SB->value()) ;
|
||||
|
||||
if(ui.autoPositiveOpinion_CB->isChecked())
|
||||
rsReputations->setNodeAutoPositiveOpinionForContacts(true) ;
|
||||
else
|
||||
@ -55,12 +50,9 @@ bool PeoplePage::save(QString &/*errmsg*/)
|
||||
/** Loads the settings for this page */
|
||||
void PeoplePage::load()
|
||||
{
|
||||
uint32_t ban_limit = rsReputations->nodeAutoBanThreshold() ;
|
||||
bool auto_positive_contacts = rsReputations->nodeAutoPositiveOpinionForContacts() ;
|
||||
float node_auto_ban_identities_limit = rsReputations->nodeAutoBanIdentitiesLimit();
|
||||
|
||||
ui.identityBan_CB->setChecked(ban_limit > 0) ;
|
||||
ui.identityBanThreshold_SB->setValue(ban_limit) ;
|
||||
ui.autoPositiveOpinion_CB->setChecked(auto_positive_contacts);
|
||||
ui.autoBanIdentitiesLimit_SB->setValue(node_auto_ban_identities_limit);
|
||||
}
|
||||
|
@ -17,50 +17,6 @@
|
||||
<string>Identities handling</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="identityBan_CB">
|
||||
<property name="text">
|
||||
<string>ban all identities of a node when more than</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="identityBanThreshold_SB">
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string> of them have a negative opinion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="autoPositiveOpinion_CB">
|
||||
<property name="toolTip">
|
||||
|
Loading…
Reference in New Issue
Block a user