enabled ID tracking forums. Fixed thresholds for anti-spam forums. Changed computation of reputation scored

This commit is contained in:
csoler 2015-10-26 23:38:10 -04:00
parent b009c1135f
commit c7d0e4cb35
14 changed files with 130 additions and 55 deletions

View File

@ -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) ;

View File

@ -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

View File

@ -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

View File

@ -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.
//

View File

@ -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()

View File

@ -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 //

View File

@ -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
{

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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 ;
}

View File

@ -552,7 +552,7 @@
<item>
<widget class="QCheckBox" name="antispam_favorSignedIds">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This makes the media increase the reputaiton threshold to 0.2,&lt;/p&gt;&lt;p&gt;allowing PGP-linked ids to pass through. Anonymous ids however&lt;/p&gt;&lt;p&gt;can also post, if their local reputation score is above that threshold. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This makes the media increase the reputation threshold to 0.4 for anonymous ids,&lt;/p&gt;&lt;p&gt;while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation &lt;/p&gt;&lt;p&gt;score is above that threshold.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;This feature allows Retroshare to locally keep a record of who&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;forwarded each message to you, for 10 days. Although useless (and already&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;available whatsoever) this information can be used by a group&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;of collaborative friends to locate the source of spams. To be used with care,&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;since it significantly decreases the anonymity of message posts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;This feature allows Retroshare to locally keep a record of who&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;forwarded each message to you, for the last 10 days. Although useless if alone (and already&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;available whatsoever) this information can be used by a group&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;of collaborative friends to easily locate the source of spams. To be used with care,&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;since it significantly decreases the anonymity of message posts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Keep track of posts</string>

View File

@ -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());