mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-17 13:24:15 -05:00
enabled ID tracking forums. Fixed thresholds for anti-spam forums. Changed computation of reputation scored
This commit is contained in:
parent
b009c1135f
commit
c7d0e4cb35
@ -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) ;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<GRouterKeyId>& key_ids) const
|
||||
key_ids.clear() ;
|
||||
|
||||
for(std::map<GRouterKeyId,std::vector<float> >::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<RsGxsMessageId,RoutingTrackEntry>::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
|
||||
|
@ -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<GRouterKeyId>& key_ids) const ;
|
||||
|
||||
bool getTrackingInfo(const RsGxsMessageId& id,RsPeerId& source_friend);
|
||||
private:
|
||||
// returns the friend id, possibly creating a new id.
|
||||
//
|
||||
|
@ -2163,6 +2163,13 @@ bool p3GRouter::getRoutingCacheInfo(std::vector<GRouterRoutingCacheInfo>& 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()
|
||||
|
@ -168,6 +168,7 @@ public:
|
||||
// - Cache state (memory size, etc)
|
||||
//
|
||||
virtual bool getRoutingCacheInfo(std::vector<GRouterRoutingCacheInfo>& info) ;
|
||||
virtual bool getTrackingInfo(const RsGxsMessageId& mid, RsPeerId& provider_id) ;
|
||||
|
||||
//===================================================//
|
||||
// Derived from p3Service //
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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 ;
|
||||
}
|
||||
|
@ -552,7 +552,7 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="antispam_favorSignedIds">
|
||||
<property name="toolTip">
|
||||
<string><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></string>
|
||||
<string><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></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Favor PGP-signed ids</string>
|
||||
@ -562,7 +562,7 @@
|
||||
<item>
|
||||
<widget class="QRadioButton" name="antispam_keepTrackOfPosts">
|
||||
<property name="toolTip">
|
||||
<string><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></string>
|
||||
<string><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></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Keep track of posts</string>
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "util/QtVersion.h"
|
||||
|
||||
#include <retroshare/rsgxsforums.h>
|
||||
#include <retroshare/rsgrouter.h>
|
||||
#include <retroshare/rsreputations.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
// 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("<b>%1: \t</b>%2<br/>").arg(tr("Forum name"), QString::fromUtf8( group.mMeta.mGroupName.c_str()));
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Subscribers")).arg(group.mMeta.mPop);
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Posts (at neighbor nodes)")).arg(group.mMeta.mVisibleMsgCount);
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Author"), author);
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Anonymous post allowed")).arg(anon_allowed_str);
|
||||
|
||||
if(!anti_spam_features1.isNull())
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Anti-spam")).arg(anti_spam_features1);
|
||||
|
||||
if(!anti_spam_features2.isNull())
|
||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Anti-spam")).arg(anti_spam_features2);
|
||||
|
||||
tw->mForumDescription += QString("<b>%1: </b><br/><br/>%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());
|
||||
|
Loading…
x
Reference in New Issue
Block a user