2011-11-23 11:40:32 -05:00
/*
* libretroshare / src / services p3banlist . cc
*
* Ban List Service for RetroShare .
*
* Copyright 2011 - 2011 by Robert Fernie .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA .
*
* Please report all bugs and problems to " retroshare@lunamutt.com " .
*
*/
2014-03-28 23:57:44 -04:00
# include "pqi/p3servicecontrol.h"
2011-11-23 11:40:32 -05:00
# include "pqi/p3netmgr.h"
2015-05-29 16:49:37 -04:00
# include "pqi/p3cfgmgr.h"
2011-11-23 11:40:32 -05:00
# include "util/rsnet.h"
# include "services/p3banlist.h"
# include "serialiser/rsbanlistitems.h"
2015-05-29 16:49:37 -04:00
# include "serialiser/rsconfigitems.h"
2015-05-26 17:17:09 -04:00
# include "retroshare/rsdht.h"
2015-05-30 05:29:43 -04:00
# include "retroshare/rsbanlist.h"
2011-11-23 11:40:32 -05:00
# include <sys/time.h>
/****
* # define DEBUG_BANLIST 1
* * * */
2015-05-26 17:17:09 -04:00
# define DEBUG_BANLIST 1
2015-05-27 17:30:40 -04:00
# define DEBUG_BANLIST_CONDENSE 1
2011-11-23 11:40:32 -05:00
/* DEFINE INTERFACE POINTER! */
//RsBanList *rsBanList = NULL;
2015-05-28 17:44:43 -04:00
# define RSBANLIST_ENTRY_MAX_AGE (60 * 60 * 1) // 1 HOURS
# define RSBANLIST_SEND_PERIOD 600 // 10 Minutes.
2015-05-26 17:17:09 -04:00
2015-05-28 17:44:43 -04:00
# define RSBANLIST_DELAY_BETWEEN_TALK_TO_DHT 60 // should be more: e.g. 600 secs.
# define RSBANLIST_DEFAULT_AUTORANGE_LIMIT 3 // default number of IPs in same range to trigger a complete IP range filter.
# define RSBANLIST_DEFAULT_AUTORANGE_ENABLED true
# define RSBANLIST_DEFAULT_FRIEND_GATHERING_ENABLED true
# define RSBANLIST_DEFAULT_DHT_GATHERING_ENABLED true
# define RSBANLIST_DEFAULT_ENABLED true
2011-11-23 11:40:32 -05:00
/************ IMPLEMENTATION NOTES *********************************
*
* Get Bad Peers passed to us ( from DHT mainly ) .
* we distribute and track the network list of bad peers .
*
*/
2015-05-26 17:17:09 -04:00
RsBanList * rsBanList = NULL ;
2011-11-23 11:40:32 -05:00
2014-03-28 23:57:44 -04:00
p3BanList : : p3BanList ( p3ServiceControl * sc , p3NetMgr * nm )
: p3Service ( ) , mBanMtx ( " p3BanList " ) , mServiceCtrl ( sc ) , mNetMgr ( nm )
2011-11-23 11:40:32 -05:00
{
addSerialType ( new RsBanListSerialiser ( ) ) ;
2015-05-26 17:17:09 -04:00
mSentListTime = 0 ;
mLastDhtInfoRequest = 0 ;
2011-11-23 11:40:32 -05:00
2015-05-28 17:44:43 -04:00
mIPFilteringEnabled = RSBANLIST_DEFAULT_ENABLED ;
mAutoRangeLimit = RSBANLIST_DEFAULT_AUTORANGE_LIMIT ;
mAutoRangeIps = RSBANLIST_DEFAULT_AUTORANGE_ENABLED ;
mIPFriendGatheringEnabled = RSBANLIST_DEFAULT_FRIEND_GATHERING_ENABLED ;
mIPDHTGatheringEnabled = RSBANLIST_DEFAULT_DHT_GATHERING_ENABLED ;
}
2011-11-23 11:40:32 -05:00
2014-03-21 23:53:44 -04:00
const std : : string BANLIST_APP_NAME = " banlist " ;
const uint16_t BANLIST_APP_MAJOR_VERSION = 1 ;
const uint16_t BANLIST_APP_MINOR_VERSION = 0 ;
const uint16_t BANLIST_MIN_MAJOR_VERSION = 1 ;
const uint16_t BANLIST_MIN_MINOR_VERSION = 0 ;
RsServiceInfo p3BanList : : getServiceInfo ( )
{
return RsServiceInfo ( RS_SERVICE_TYPE_BANLIST ,
BANLIST_APP_NAME ,
BANLIST_APP_MAJOR_VERSION ,
BANLIST_APP_MINOR_VERSION ,
BANLIST_MIN_MAJOR_VERSION ,
2015-05-26 17:17:09 -04:00
BANLIST_MIN_MINOR_VERSION ) ;
2014-03-21 23:53:44 -04:00
}
2015-05-28 17:44:43 -04:00
bool p3BanList : : ipFilteringEnabled ( ) { return mIPFilteringEnabled ; }
void p3BanList : : enableIPFiltering ( bool b ) { mIPFilteringEnabled = b ; }
void p3BanList : : enableIPsFromFriends ( bool b ) { mIPFriendGatheringEnabled = b ; mLastDhtInfoRequest = 0 ; }
void p3BanList : : enableIPsFromDHT ( bool b )
{
mIPDHTGatheringEnabled = b ;
mLastDhtInfoRequest = 0 ;
}
void p3BanList : : enableAutoRange ( bool b )
{
mAutoRangeIps = b ;
autoFigureOutBanRanges ( ) ;
}
void p3BanList : : setAutoRangeLimit ( int n )
{
mAutoRangeLimit = n ;
autoFigureOutBanRanges ( ) ;
}
class ZeroedInt
{
public :
ZeroedInt ( ) { n = 0 ; }
uint32_t n ;
} ;
BanListPeer : : BanListPeer ( )
2015-05-27 17:30:40 -04:00
{
2015-05-28 17:44:43 -04:00
masked_bytes = 0 ;
reason = RSBANLIST_REASON_UNKNOWN ;
level = RSBANLIST_ORIGIN_UNKNOWN ;
2015-05-29 14:03:14 -04:00
state = true ;
2015-05-28 17:44:43 -04:00
connect_attempts = 0 ;
mTs = 0 ;
2015-05-27 17:30:40 -04:00
}
2015-05-29 16:49:37 -04:00
void BanListPeer : : toRsTlvBanListEntry ( RsTlvBanListEntry & e ) const
{
e . addr . addr = addr ;
e . level = level ;
e . reason = reason ;
e . masked_bytes = masked_bytes ;
e . age = time ( NULL ) - mTs ;
}
void BanListPeer : : fromRsTlvBanListEntry ( const RsTlvBanListEntry & e )
{
addr = e . addr . addr ;
masked_bytes = e . masked_bytes ; // 0 = []/32. 1=[]/24, 2=[]/16
reason = e . reason ; // User, DHT
level = e . level ; // LOCAL, FRIEND, FoF.
state = true ; // true=>active, false=>just stored but inactive
connect_attempts = 0 ; // recorded by the BanList service
mTs = time ( NULL ) - e . age ;
comment . clear ( ) ; //
}
2015-05-29 14:03:14 -04:00
static sockaddr_storage makeBitsRange ( const sockaddr_storage & addr , int masked_bytes )
2015-05-27 17:30:40 -04:00
{
2015-05-28 17:44:43 -04:00
sockaddr_storage s ;
sockaddr_storage_clear ( s ) ;
sockaddr_storage_copyip ( s , addr ) ;
sockaddr_in * ad = ( sockaddr_in * ) ( & s ) ;
2015-05-29 14:03:14 -04:00
if ( masked_bytes = = 1 )
ad - > sin_addr . s_addr | = 0xff000000 ;
else if ( masked_bytes = = 2 )
ad - > sin_addr . s_addr | = 0xffff0000 ;
else if ( masked_bytes ! = 0 )
std : : cerr < < " Warning: unhandled mask size for IP range: " < < masked_bytes < < std : : endl ;
2015-05-28 17:44:43 -04:00
return s ;
}
void p3BanList : : autoFigureOutBanRanges ( )
{
RS_STACK_MUTEX ( mBanMtx ) ;
2015-05-29 14:03:14 -04:00
// clear automatic ban ranges
for ( std : : map < sockaddr_storage , BanListPeer > : : iterator it ( mBanRanges . begin ( ) ) ; it ! = mBanRanges . end ( ) ; )
if ( it - > second . reason = = RSBANLIST_REASON_AUTO_RANGE )
{
std : : map < sockaddr_storage , BanListPeer > : : iterator it2 = it ;
+ + it2 ;
mBanRanges . erase ( it ) ;
it = it2 ;
}
else
+ + it ;
2015-05-28 17:44:43 -04:00
if ( ! mAutoRangeIps )
return ;
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-28 17:44:43 -04:00
std : : cerr < < " Automatically figuring out IP ranges from banned IPs. " < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-28 17:44:43 -04:00
std : : map < sockaddr_storage , ZeroedInt > range_map ;
for ( std : : map < sockaddr_storage , BanListPeer > : : iterator it ( mBanSet . begin ( ) ) ; it ! = mBanSet . end ( ) ; + + it )
2015-05-29 14:03:14 -04:00
+ + range_map [ makeBitsRange ( it - > first , 1 ) ] . n ;
2015-05-28 17:44:43 -04:00
time_t now = time ( NULL ) ;
for ( std : : map < sockaddr_storage , ZeroedInt > : : const_iterator it = range_map . begin ( ) ; it ! = range_map . end ( ) ; + + it )
{
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-28 17:44:43 -04:00
std : : cerr < < " Ban range: " < < sockaddr_storage_iptostring ( it - > first ) < < " : " < < it - > second . n < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-28 17:44:43 -04:00
if ( it - > second . n > = mAutoRangeLimit )
{
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-29 12:07:35 -04:00
std : : cerr < < " --> creating new ban range. " < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-29 12:07:35 -04:00
BanListPeer & peer ( mBanRanges [ it - > first ] ) ;
2015-05-29 14:03:14 -04:00
if ( peer . reason = = RSBANLIST_REASON_USER )
continue ;
2015-05-29 12:07:35 -04:00
peer . addr = it - > first ;
peer . masked_bytes = 1 ;
peer . reason = RSBANLIST_REASON_AUTO_RANGE ;
peer . level = RSBANLIST_ORIGIN_SELF ;
peer . state = true ;
peer . mTs = now ;
peer . connect_attempts = 0 ;
peer . connect_attempts = it - > second . n ;
2015-05-28 17:44:43 -04:00
}
}
condenseBanSources_locked ( ) ;
2015-05-27 17:30:40 -04:00
}
2015-05-30 05:29:43 -04:00
bool p3BanList : : isAddressAccepted ( const sockaddr_storage & addr , uint32_t checking_flags , uint32_t & check_result )
2015-05-26 17:17:09 -04:00
{
2015-05-30 05:29:43 -04:00
check_result = RSBANLIST_CHECK_RESULT_NOCHECK ;
2015-05-28 17:44:43 -04:00
if ( ! mIPFilteringEnabled )
return true ;
2015-05-30 09:57:10 -04:00
std : : cerr < < " isAddressAccepted(): tested addr= " < < sockaddr_storage_iptostring ( addr ) < < " , checking flags= " < < checking_flags ;
2015-05-26 17:17:09 -04:00
// we should normally work this including entire ranges of IPs. For now, just check the exact IPs.
2015-05-29 14:03:14 -04:00
sockaddr_storage addr_24 = makeBitsRange ( addr , 1 ) ;
sockaddr_storage addr_16 = makeBitsRange ( addr , 2 ) ;
2015-05-28 17:44:43 -04:00
2015-05-30 09:57:10 -04:00
bool white_list_found = false ;
2015-05-30 05:29:43 -04:00
2015-05-30 09:57:10 -04:00
white_list_found = white_list_found | | ( mWhiteListedRanges . find ( addr_16 ) ! = mWhiteListedRanges . end ( ) ) ;
white_list_found = white_list_found | | ( mWhiteListedRanges . find ( addr_24 ) ! = mWhiteListedRanges . end ( ) ) ;
white_list_found = white_list_found | | ( mWhiteListedRanges . find ( addr ) ! = mWhiteListedRanges . end ( ) ) ;
2015-05-30 05:29:43 -04:00
2015-05-30 09:57:10 -04:00
if ( white_list_found )
{
check_result = RSBANLIST_CHECK_RESULT_ACCEPTED ;
std : : cerr < < " . Address is in whitelist. Accepting " < < std : : endl ;
return true ;
}
if ( checking_flags & RSBANLIST_CHECKING_FLAGS_WHITELIST )
{
check_result = RSBANLIST_CHECK_RESULT_NOT_WHITELISTED ;
std : : cerr < < " . Address is not whitelist, and whitelist is required. Rejecting " < < std : : endl ;
return false ;
2015-05-30 05:29:43 -04:00
}
if ( ! ( checking_flags & RSBANLIST_CHECKING_FLAGS_BLACKLIST ) )
2015-05-30 09:57:10 -04:00
{
std : : cerr < < " . No blacklisting required. Accepting. " < < std : : endl ;
2015-05-30 05:29:43 -04:00
return true ;
2015-05-30 09:57:10 -04:00
}
2015-05-28 17:44:43 -04:00
std : : map < sockaddr_storage , BanListPeer > : : iterator it ;
2015-05-29 14:03:14 -04:00
if ( ( it = mBanRanges . find ( addr_16 ) ) ! = mBanRanges . end ( ) )
{
+ + it - > second . connect_attempts ;
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-30 09:57:10 -04:00
std : : cerr < < " found in blacklisted range " < < sockaddr_storage_iptostring ( it - > first ) < < " /16. returning false. attempts= " < < it - > second . connect_attempts < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-30 05:29:43 -04:00
check_result = RSBANLIST_CHECK_RESULT_BLACKLISTED ;
2015-05-29 14:03:14 -04:00
return false ;
}
2015-05-28 17:44:43 -04:00
if ( ( it = mBanRanges . find ( addr_24 ) ) ! = mBanRanges . end ( ) )
{
+ + it - > second . connect_attempts ;
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-30 09:57:10 -04:00
std : : cerr < < " found in blacklisted range " < < sockaddr_storage_iptostring ( it - > first ) < < " /24. returning false. attempts= " < < it - > second . connect_attempts < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-30 05:29:43 -04:00
check_result = RSBANLIST_CHECK_RESULT_BLACKLISTED ;
2015-05-26 17:17:09 -04:00
return false ;
2015-05-28 17:44:43 -04:00
}
2015-05-26 17:17:09 -04:00
2015-05-28 17:44:43 -04:00
if ( ( it = mBanSet . find ( addr ) ) ! = mBanSet . end ( ) )
{
+ + it - > second . connect_attempts ;
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-30 09:57:10 -04:00
std : : cerr < < " found as blacklisted address " < < sockaddr_storage_iptostring ( it - > first ) < < " . returning false. attempts= " < < it - > second . connect_attempts < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-30 05:29:43 -04:00
check_result = RSBANLIST_CHECK_RESULT_BLACKLISTED ;
2015-05-28 17:44:43 -04:00
return false ;
}
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-30 09:57:10 -04:00
std : : cerr < < " not blacklisted. Accepting. " < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-30 05:29:43 -04:00
check_result = RSBANLIST_CHECK_RESULT_ACCEPTED ;
2015-05-26 17:17:09 -04:00
return true ;
}
2015-05-30 09:57:10 -04:00
void p3BanList : : getWhiteListedIps ( std : : list < BanListPeer > & lst )
{
RS_STACK_MUTEX ( mBanMtx ) ;
2014-03-21 23:53:44 -04:00
2015-05-30 09:57:10 -04:00
lst . clear ( ) ;
for ( std : : map < sockaddr_storage , BanListPeer > : : const_iterator it ( mWhiteListedRanges . begin ( ) ) ; it ! = mWhiteListedRanges . end ( ) ; + + it )
lst . push_back ( it - > second ) ;
}
void p3BanList : : getBannedIps ( std : : list < BanListPeer > & lst )
2015-05-26 17:17:09 -04:00
{
2015-05-29 10:06:15 -04:00
RS_STACK_MUTEX ( mBanMtx ) ;
2015-05-30 09:57:10 -04:00
lst . clear ( ) ;
2015-05-26 17:17:09 -04:00
for ( std : : map < sockaddr_storage , BanListPeer > : : const_iterator it ( mBanSet . begin ( ) ) ; it ! = mBanSet . end ( ) ; + + it )
2015-05-29 14:03:14 -04:00
if ( mBanRanges . find ( makeBitsRange ( it - > first , 1 ) ) = = mBanRanges . end ( )
& & mBanRanges . find ( makeBitsRange ( it - > first , 2 ) ) = = mBanRanges . end ( ) )
2015-05-29 10:06:15 -04:00
lst . push_back ( it - > second ) ;
2015-05-28 17:44:43 -04:00
for ( std : : map < sockaddr_storage , BanListPeer > : : const_iterator it ( mBanRanges . begin ( ) ) ; it ! = mBanRanges . end ( ) ; + + it )
lst . push_back ( it - > second ) ;
2015-05-26 17:17:09 -04:00
}
2014-03-21 23:53:44 -04:00
2015-05-30 09:57:10 -04:00
void p3BanList : : removeIpRange ( const struct sockaddr_storage & addr , int masked_bytes , uint32_t list_type )
{
# warning NOT IMPLEMENTED YET
}
void p3BanList : : addIpRange ( const sockaddr_storage & addr , int masked_bytes , uint32_t list_type , const std : : string & comment )
2015-05-29 14:03:14 -04:00
{
RS_STACK_MUTEX ( mBanMtx ) ;
BanListPeer blp ;
blp . level = RSBANLIST_ORIGIN_SELF ;
blp . connect_attempts = 0 ;
blp . addr = addr ;
blp . masked_bytes = masked_bytes ;
blp . mTs = time ( NULL ) ;
blp . reason = RSBANLIST_REASON_USER ;
blp . comment = comment ;
if ( masked_bytes ! = 0 & & masked_bytes ! = 1 & & masked_bytes ! = 2 )
{
std : : cerr < < " Unhandled masked byte size " < < masked_bytes < < " . Should be 0,1 or 2 " < < std : : endl ;
return ;
}
sockaddr_storage addrrange = makeBitsRange ( addr , masked_bytes ) ;
2015-05-30 09:57:10 -04:00
if ( list_type = = RSBANLIST_CHECKING_FLAGS_BLACKLIST )
mBanRanges [ addrrange ] = blp ;
else if ( list_type = = RSBANLIST_CHECKING_FLAGS_WHITELIST )
mWhiteListedRanges [ addrrange ] = blp ;
else
std : : cerr < < " (EE) Cannot add IP range. Bad list_type. Should be eiter RSBANLIST_CHECKING_FLAGS_BLACKLIST or RSBANLIST_CHECKING_FLAGS_WHITELIST " < < std : : endl ;
2015-05-29 14:03:14 -04:00
}
2015-05-30 09:57:10 -04:00
int p3BanList : : tick ( )
2011-11-23 11:40:32 -05:00
{
2015-05-28 17:44:43 -04:00
processIncoming ( ) ;
sendPackets ( ) ;
2011-11-23 11:40:32 -05:00
2015-05-26 17:17:09 -04:00
time_t now = time ( NULL ) ;
if ( mLastDhtInfoRequest + RSBANLIST_DELAY_BETWEEN_TALK_TO_DHT < now )
{
2015-05-28 17:44:43 -04:00
if ( mIPDHTGatheringEnabled )
getDhtInfo ( ) ;
2015-05-29 14:03:14 -04:00
2015-05-26 17:17:09 -04:00
mLastDhtInfoRequest = now ;
2015-05-28 17:44:43 -04:00
if ( mAutoRangeIps )
autoFigureOutBanRanges ( ) ;
2015-05-26 17:17:09 -04:00
}
2015-05-28 17:44:43 -04:00
return 0 ;
2011-11-23 11:40:32 -05:00
}
int p3BanList : : status ( )
{
return 1 ;
}
2015-05-26 17:17:09 -04:00
void p3BanList : : getDhtInfo ( )
{
// Get the list of masquerading peers from the DHT. Add them as potential IPs to be banned.
// Don't make them active. Just insert them in the list.
std : : list < RsDhtFilteredPeer > filtered_peers ;
rsDht - > getListOfBannedIps ( filtered_peers ) ;
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-26 17:17:09 -04:00
std : : cerr < < " p3BanList::getDhtInfo() Got list of banned IPs. " < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-26 17:17:09 -04:00
RsPeerId ownId = mServiceCtrl - > getOwnId ( ) ;
for ( std : : list < RsDhtFilteredPeer > : : const_iterator it ( filtered_peers . begin ( ) ) ; it ! = filtered_peers . end ( ) ; + + it )
{
2015-05-29 16:49:37 -04:00
# ifdef DEBUG_BANLIST
2015-05-26 17:17:09 -04:00
std : : cerr < < " filtered peer: " < < rs_inet_ntoa ( ( * it ) . mAddr . sin_addr ) < < std : : endl ;
2015-05-29 16:49:37 -04:00
# endif
2015-05-26 17:17:09 -04:00
2015-05-27 17:30:40 -04:00
int int_reason = RSBANLIST_REASON_DHT ;
int time_stamp = ( * it ) . mLastSeen ;
uint8_t masked_bytes = 0 ;
2015-05-28 17:44:43 -04:00
sockaddr_storage ad ;
sockaddr_storage_setipv4 ( ad , & ( * it ) . mAddr ) ;
2015-05-26 17:17:09 -04:00
2015-05-27 17:30:40 -04:00
addBanEntry ( ownId , ad , RSBANLIST_ORIGIN_SELF , int_reason , time_stamp , masked_bytes ) ;
2015-05-26 17:17:09 -04:00
}
2015-05-28 05:38:13 -04:00
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
2015-05-26 17:17:09 -04:00
condenseBanSources_locked ( ) ;
}
2011-11-23 11:40:32 -05:00
/***** Implementation ******/
bool p3BanList : : processIncoming ( )
{
/* for each packet - pass to specific handler */
RsItem * item = NULL ;
bool updated = false ;
while ( NULL ! = ( item = recvItem ( ) ) )
{
2011-11-24 19:58:01 -05:00
# ifdef DEBUG_BANLIST
std : : cerr < < " p3BanList::processingIncoming() Received Item: " ;
std : : cerr < < std : : endl ;
item - > print ( std : : cerr ) ;
std : : cerr < < std : : endl ;
# endif
2011-11-23 11:40:32 -05:00
switch ( item - > PacketSubType ( ) )
{
default :
break ;
case RS_PKT_SUBTYPE_BANLIST_ITEM :
{
2011-12-01 12:21:52 -05:00
// Order is important!.
updated = ( recvBanItem ( ( RsBanListItem * ) item ) | | updated ) ;
2011-11-23 11:40:32 -05:00
}
break ;
}
/* clean up */
delete item ;
}
if ( updated )
{
{
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
condenseBanSources_locked ( ) ;
}
/* pass list to NetAssist */
}
return true ;
}
bool p3BanList : : recvBanItem ( RsBanListItem * item )
{
bool updated = false ;
2015-05-27 17:30:40 -04:00
time_t now = time ( NULL ) ;
2015-05-29 16:49:37 -04:00
std : : list < RsTlvBanListEntry > : : const_iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = item - > peerList . mList . begin ( ) ; it ! = item - > peerList . mList . end ( ) ; + + it )
2011-11-23 11:40:32 -05:00
{
2011-12-01 12:21:52 -05:00
// Order is important!.
2015-05-27 17:30:40 -04:00
updated = ( addBanEntry ( item - > PeerId ( ) , it - > addr . addr , it - > level , it - > reason , now - it - > age , it - > masked_bytes ) | | updated ) ;
2011-11-23 11:40:32 -05:00
}
return updated ;
}
2011-11-24 19:58:01 -05:00
/* overloaded from pqiNetAssistSharePeer */
2015-05-27 17:30:40 -04:00
void p3BanList : : updatePeer ( const RsPeerId & /*id*/ , const struct sockaddr_storage & addr , int type , int /*reason*/ , int time_stamp )
2011-11-24 19:58:01 -05:00
{
2015-05-27 17:30:40 -04:00
RsPeerId ownId = mServiceCtrl - > getOwnId ( ) ;
2011-11-24 19:58:01 -05:00
2015-05-27 17:30:40 -04:00
int int_reason = RSBANLIST_REASON_DHT ;
2011-11-24 19:58:01 -05:00
2015-05-27 17:30:40 -04:00
addBanEntry ( ownId , addr , RSBANLIST_ORIGIN_SELF , int_reason , time_stamp , 0 ) ;
2011-11-24 19:58:01 -05:00
2015-05-27 17:30:40 -04:00
/* process */
{
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
condenseBanSources_locked ( ) ;
}
2011-11-24 19:58:01 -05:00
}
2015-05-29 16:49:37 -04:00
RsSerialiser * p3BanList : : setupSerialiser ( )
{
RsSerialiser * rss = new RsSerialiser ;
rss - > addSerialType ( new RsBanListSerialiser ( ) ) ;
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
return rss ;
}
bool p3BanList : : saveList ( bool & cleanup , std : : list < RsItem * > & itemlist )
{
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
cleanup = true ;
for ( std : : map < RsPeerId , BanList > : : const_iterator it ( mBanSources . begin ( ) ) ; it ! = mBanSources . end ( ) ; + + it )
{
RsBanListConfigItem * item = new RsBanListConfigItem ;
item - > peerId = it - > second . mPeerId ;
item - > update_time = it - > second . mLastUpdate ;
item - > banned_peers . TlvClear ( ) ;
for ( std : : map < sockaddr_storage , BanListPeer > : : const_iterator it2 = it - > second . mBanPeers . begin ( ) ; it2 ! = it - > second . mBanPeers . end ( ) ; + + it2 )
{
RsTlvBanListEntry e ;
it2 - > second . toRsTlvBanListEntry ( e ) ;
item - > banned_peers . mList . push_back ( e ) ;
}
itemlist . push_back ( item ) ;
}
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
RsTlvKeyValue kv ;
kv . key = " IP_FILTERING_ENABLED " ;
kv . value = mIPFilteringEnabled ? " TRUE " : " FALSE " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
kv . key = " IP_FILTERING_AUTORANGE_IPS " ;
kv . value = mAutoRangeIps ? " TRUE " : " FALSE " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
kv . key = " IP_FILTERING_FRIEND_GATHERING_ENABLED " ;
kv . value = mIPFriendGatheringEnabled ? " TRUE " : " FALSE " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
kv . key = " IP_FILTERING_DHT_GATHERING_ENABLED " ;
kv . value = mIPDHTGatheringEnabled ? " TRUE " : " FALSE " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
itemlist . push_back ( vitem ) ;
return true ;
}
bool p3BanList : : loadList ( std : : list < RsItem * > & load )
{
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
for ( std : : list < RsItem * > : : const_iterator it ( load . begin ( ) ) ; it ! = load . end ( ) ; + + it )
{
RsConfigKeyValueSet * vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ;
if ( vitem ! = NULL )
for ( std : : list < RsTlvKeyValue > : : const_iterator it2 ( vitem - > tlvkvs . pairs . begin ( ) ) ; it2 ! = vitem - > tlvkvs . pairs . end ( ) ; + + it2 )
{
if ( it2 - > key = = " IP_FILTERING_ENABLED " ) mIPFilteringEnabled = ( it2 - > value = = " TRUE " ) ;
if ( it2 - > key = = " IP_FILTERING_AUTORANGE_IPS " ) mAutoRangeIps = ( it2 - > value = = " TRUE " ) ;
if ( it2 - > key = = " IP_FILTERING_FRIEND_GATHERING_ENABLED " ) mIPFriendGatheringEnabled = ( it2 - > value = = " TRUE " ) ;
if ( it2 - > key = = " IP_FILTERING_DHT_GATHERING_ENABLED " ) mIPDHTGatheringEnabled = ( it2 - > value = = " TRUE " ) ;
}
RsBanListConfigItem * citem = dynamic_cast < RsBanListConfigItem * > ( * it ) ;
if ( citem ! = NULL )
{
BanList & bl ( mBanSources [ citem - > peerId ] ) ;
bl . mPeerId = citem - > peerId ;
bl . mLastUpdate = citem - > update_time ;
bl . mBanPeers . clear ( ) ;
for ( std : : list < RsTlvBanListEntry > : : const_iterator it2 ( citem - > banned_peers . mList . begin ( ) ) ; it2 ! = citem - > banned_peers . mList . end ( ) ; + + it2 )
{
BanListPeer blp ;
blp . fromRsTlvBanListEntry ( * it2 ) ;
bl . mBanPeers [ blp . addr ] = blp ;
}
}
delete * it ;
}
return true ;
}
2011-11-24 19:58:01 -05:00
2015-05-27 17:30:40 -04:00
bool p3BanList : : addBanEntry ( const RsPeerId & peerId , const struct sockaddr_storage & addr ,
int level , uint32_t reason , time_t time_stamp , uint8_t masked_bytes )
2011-11-23 11:40:32 -05:00
{
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
time_t now = time ( NULL ) ;
bool updated = false ;
2011-11-24 19:58:01 -05:00
# ifdef DEBUG_BANLIST
2015-05-27 17:30:40 -04:00
std : : cerr < < " p3BanList::addBanEntry() Addr: " < < sockaddr_storage_iptostring ( addr ) < < " Origin: " < < level ;
std : : cerr < < " Reason: " < < reason < < " Age: " < < now - time_stamp ;
2011-11-24 19:58:01 -05:00
std : : cerr < < std : : endl ;
# endif
2011-12-01 12:21:52 -05:00
/* Only Accept it - if external address */
2013-09-13 10:35:19 -04:00
if ( ! sockaddr_storage_isExternalNet ( addr ) )
2011-12-01 12:21:52 -05:00
{
# ifdef DEBUG_BANLIST
2013-09-13 10:35:19 -04:00
std : : cerr < < " p3BanList::addBanEntry() Ignoring Non External Addr: " < < sockaddr_storage_iptostring ( addr ) ;
2011-12-01 12:21:52 -05:00
std : : cerr < < std : : endl ;
# endif
return false ;
}
2014-03-17 16:56:06 -04:00
std : : map < RsPeerId , BanList > : : iterator it ;
2011-11-23 11:40:32 -05:00
it = mBanSources . find ( peerId ) ;
if ( it = = mBanSources . end ( ) )
{
BanList bl ;
bl . mPeerId = peerId ;
2011-11-24 19:58:01 -05:00
bl . mLastUpdate = now ;
2011-11-23 11:40:32 -05:00
mBanSources [ peerId ] = bl ;
it = mBanSources . find ( peerId ) ;
updated = true ;
}
2013-09-13 10:35:19 -04:00
// index is FAMILY + IP - the rest should be Zeros..
struct sockaddr_storage bannedaddr ;
sockaddr_storage_clear ( bannedaddr ) ;
sockaddr_storage_copyip ( bannedaddr , addr ) ;
sockaddr_storage_setport ( bannedaddr , 0 ) ;
std : : map < struct sockaddr_storage , BanListPeer > : : iterator mit ;
mit = it - > second . mBanPeers . find ( bannedaddr ) ;
2011-11-23 11:40:32 -05:00
if ( mit = = it - > second . mBanPeers . end ( ) )
{
/* add in */
BanListPeer blp ;
blp . addr = addr ;
blp . reason = reason ;
2015-05-27 17:30:40 -04:00
blp . level = level ;
blp . mTs = time_stamp ;
blp . masked_bytes = masked_bytes ;
2013-09-13 10:35:19 -04:00
it - > second . mBanPeers [ bannedaddr ] = blp ;
2011-11-24 19:58:01 -05:00
it - > second . mLastUpdate = now ;
2011-11-23 11:40:32 -05:00
updated = true ;
}
else
{
/* see if it needs an update */
if ( ( mit - > second . reason ! = reason ) | |
2015-05-27 17:30:40 -04:00
( mit - > second . level ! = level ) | |
( mit - > second . mTs < time_stamp ) | |
( mit - > second . masked_bytes < masked_bytes )
)
2011-11-23 11:40:32 -05:00
{
/* update */
mit - > second . addr = addr ;
mit - > second . reason = reason ;
2015-05-27 17:30:40 -04:00
mit - > second . level = level ;
mit - > second . mTs = time_stamp ;
mit - > second . masked_bytes = masked_bytes ;
2011-11-24 19:58:01 -05:00
it - > second . mLastUpdate = now ;
2011-11-23 11:40:32 -05:00
updated = true ;
}
}
return updated ;
}
2011-12-08 15:15:08 -05:00
/***
* EXTRA DEBUGGING .
* # define DEBUG_BANLIST_CONDENSE 1
* * */
2011-11-23 11:40:32 -05:00
int p3BanList : : condenseBanSources_locked ( )
{
2015-05-28 17:44:43 -04:00
mBanSet . clear ( ) ;
2015-05-29 16:49:37 -04:00
// time_t now = time(NULL);
2014-03-28 23:57:44 -04:00
RsPeerId ownId = mServiceCtrl - > getOwnId ( ) ;
2011-11-23 11:40:32 -05:00
2011-11-24 19:58:01 -05:00
# ifdef DEBUG_BANLIST
std : : cerr < < " p3BanList::condenseBanSources_locked() " ;
std : : cerr < < std : : endl ;
# endif
2014-03-17 16:56:06 -04:00
std : : map < RsPeerId , BanList > : : const_iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = mBanSources . begin ( ) ; it ! = mBanSources . end ( ) ; + + it )
2011-11-23 11:40:32 -05:00
{
2015-05-27 17:30:40 -04:00
// if (now - it->second.mLastUpdate > RSBANLIST_ENTRY_MAX_AGE)
// {
//#ifdef DEBUG_BANLIST_CONDENSE
// std::cerr << "p3BanList::condenseBanSources_locked()";
// std::cerr << " Ignoring Out-Of-Date peer: " << it->first;
// std::cerr << std::endl;
//#endif
// continue;
// }
2011-11-24 19:58:01 -05:00
2011-12-08 15:15:08 -05:00
# ifdef DEBUG_BANLIST_CONDENSE
2011-11-24 19:58:01 -05:00
std : : cerr < < " p3BanList::condenseBanSources_locked() " ;
std : : cerr < < " Condensing Info from peer: " < < it - > first ;
std : : cerr < < std : : endl ;
# endif
2011-11-23 11:40:32 -05:00
2013-09-13 10:35:19 -04:00
std : : map < struct sockaddr_storage , BanListPeer > : : const_iterator lit ;
2015-05-28 17:44:43 -04:00
for ( lit = it - > second . mBanPeers . begin ( ) ; lit ! = it - > second . mBanPeers . end ( ) ; + + lit )
{
/* check timestamp */
// if (now > RSBANLIST_ENTRY_MAX_AGE + lit->second.mTs)
// {
//#ifdef DEBUG_BANLIST_CONDENSE
// std::cerr << "p3BanList::condenseBanSources_locked()";
// std::cerr << " Ignoring Out-Of-Date Entry for: ";
// std::cerr << sockaddr_storage_iptostring(lit->second.addr);
// std::cerr << " time stamp= " << lit->second.mTs << ", age=" << now - lit->second.mTs;
// std::cerr << std::endl;
//#endif
// continue;
// }
int lvl = lit - > second . level ;
if ( it - > first ! = ownId )
{
/* as from someone else, increment level */
lvl + + ;
}
2015-05-27 17:30:40 -04:00
2015-05-28 17:44:43 -04:00
struct sockaddr_storage bannedaddr ;
sockaddr_storage_clear ( bannedaddr ) ;
sockaddr_storage_copyip ( bannedaddr , lit - > second . addr ) ;
sockaddr_storage_setport ( bannedaddr , 0 ) ;
2011-11-23 11:40:32 -05:00
2015-05-28 17:44:43 -04:00
/* check if it exists in the Set already */
std : : map < struct sockaddr_storage , BanListPeer > : : iterator sit ;
sit = mBanSet . find ( bannedaddr ) ;
if ( ( sit = = mBanSet . end ( ) ) | | ( lvl < sit - > second . level ) )
{
BanListPeer bp = lit - > second ;
bp . level = lvl ;
sockaddr_storage_setport ( bp . addr , 0 ) ;
mBanSet [ bannedaddr ] = bp ;
2011-12-08 15:15:08 -05:00
# ifdef DEBUG_BANLIST_CONDENSE
2015-05-28 17:44:43 -04:00
std : : cerr < < " p3BanList::condenseBanSources_locked() " ;
std : : cerr < < " Added New Entry for: " ;
std : : cerr < < sockaddr_storage_iptostring ( bannedaddr ) ;
std : : cerr < < std : : endl ;
2011-11-24 19:58:01 -05:00
# endif
2015-05-28 17:44:43 -04:00
}
else
{
2011-12-08 15:15:08 -05:00
# ifdef DEBUG_BANLIST_CONDENSE
2015-05-28 17:44:43 -04:00
std : : cerr < < " p3BanList::condenseBanSources_locked() " ;
std : : cerr < < " Merging Info for: " ;
std : : cerr < < sockaddr_storage_iptostring ( bannedaddr ) ;
std : : cerr < < std : : endl ;
2011-11-24 19:58:01 -05:00
# endif
2015-05-28 17:44:43 -04:00
/* update if necessary */
if ( lvl = = sit - > second . level )
{
sit - > second . reason | = lit - > second . reason ;
if ( sit - > second . mTs < lit - > second . mTs )
{
sit - > second . mTs = lit - > second . mTs ;
}
}
}
}
2011-11-23 11:40:32 -05:00
}
2011-11-24 19:58:01 -05:00
# ifdef DEBUG_BANLIST
std : : cerr < < " p3BanList::condenseBanSources_locked() Printing New Set: " ;
std : : cerr < < std : : endl ;
printBanSet_locked ( std : : cerr ) ;
2012-01-20 12:50:19 -05:00
# endif
2011-11-24 19:58:01 -05:00
2012-01-12 15:56:36 -05:00
return true ;
2011-11-23 11:40:32 -05:00
}
int p3BanList : : sendPackets ( )
{
time_t now = time ( NULL ) ;
time_t pt ;
{
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
pt = mSentListTime ;
}
if ( now - pt > RSBANLIST_SEND_PERIOD )
{
sendBanLists ( ) ;
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
2011-11-24 19:58:01 -05:00
2012-01-20 12:50:19 -05:00
# ifdef DEBUG_BANLIST
2011-11-24 19:58:01 -05:00
std : : cerr < < " p3BanList::sendPackets() Regular Broadcast " ;
std : : cerr < < std : : endl ;
printBanSources_locked ( std : : cerr ) ;
printBanSet_locked ( std : : cerr ) ;
2012-01-20 12:50:19 -05:00
# endif
2011-11-24 19:58:01 -05:00
2011-11-23 11:40:32 -05:00
mSentListTime = now ;
}
return true ;
}
void p3BanList : : sendBanLists ( )
{
/* we ping our peers */
/* who is online? */
2014-03-28 23:57:44 -04:00
std : : set < RsPeerId > idList ;
2011-11-23 11:40:32 -05:00
2014-03-28 23:57:44 -04:00
mServiceCtrl - > getPeersConnected ( getServiceInfo ( ) . mServiceType , idList ) ;
2011-11-23 11:40:32 -05:00
# ifdef DEBUG_BANLIST
std : : cerr < < " p3BanList::sendBanList() " ;
std : : cerr < < std : : endl ;
# endif
/* prepare packets */
2014-03-28 23:57:44 -04:00
std : : set < RsPeerId > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = idList . begin ( ) ; it ! = idList . end ( ) ; + + it )
2011-11-23 11:40:32 -05:00
{
# ifdef DEBUG_BANLIST
2015-05-26 17:17:09 -04:00
std : : cerr < < " p3BanList::sendBanList() To: " < < * it ;
2011-11-23 11:40:32 -05:00
std : : cerr < < std : : endl ;
# endif
sendBanSet ( * it ) ;
}
}
2014-03-17 16:56:06 -04:00
int p3BanList : : sendBanSet ( const RsPeerId & peerid )
2011-11-23 11:40:32 -05:00
{
2015-05-29 16:49:37 -04:00
/* */
RsBanListItem * item = new RsBanListItem ( ) ;
item - > PeerId ( peerid ) ;
2011-11-23 11:40:32 -05:00
2015-05-29 16:49:37 -04:00
//time_t now = time(NULL);
{
RsStackMutex stack ( mBanMtx ) ; /****** LOCKED MUTEX *******/
std : : map < struct sockaddr_storage , BanListPeer > : : iterator it ;
for ( it = mBanSet . begin ( ) ; it ! = mBanSet . end ( ) ; + + it )
{
2015-05-27 17:30:40 -04:00
if ( it - > second . level > = RSBANLIST_ORIGIN_FRIEND )
2015-05-29 16:49:37 -04:00
continue ; // only share OWN for the moment.
2011-11-23 11:40:32 -05:00
2015-05-29 16:49:37 -04:00
RsTlvBanListEntry bi ;
it - > second . toRsTlvBanListEntry ( bi ) ;
item - > peerList . mList . push_back ( bi ) ;
}
}
sendItem ( item ) ;
return 1 ;
2011-11-23 11:40:32 -05:00
}
2011-11-24 19:58:01 -05:00
int p3BanList : : printBanSet_locked ( std : : ostream & out )
2011-11-23 11:40:32 -05:00
{
2011-11-24 19:58:01 -05:00
out < < " p3BanList::printBanSet_locked() " ;
2011-11-23 11:40:32 -05:00
out < < std : : endl ;
time_t now = time ( NULL ) ;
2013-09-13 10:35:19 -04:00
std : : map < struct sockaddr_storage , BanListPeer > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = mBanSet . begin ( ) ; it ! = mBanSet . end ( ) ; + + it )
2011-11-23 11:40:32 -05:00
{
2013-09-13 10:35:19 -04:00
out < < " Ban: " < < sockaddr_storage_iptostring ( it - > second . addr ) ;
2011-11-23 11:40:32 -05:00
out < < " Reason: " < < it - > second . reason ;
2015-05-27 17:30:40 -04:00
out < < " Level: " < < it - > second . level ;
if ( it - > second . level > RSBANLIST_ORIGIN_FRIEND )
2011-11-23 11:40:32 -05:00
{
out < < " (unused) " ;
}
out < < " Age: " < < now - it - > second . mTs ;
out < < std : : endl ;
}
2012-01-12 15:56:36 -05:00
return true ;
2011-11-23 11:40:32 -05:00
}
2011-11-24 19:58:01 -05:00
int p3BanList : : printBanSources_locked ( std : : ostream & out )
2011-11-23 11:40:32 -05:00
{
time_t now = time ( NULL ) ;
2014-03-17 16:56:06 -04:00
std : : map < RsPeerId , BanList > : : const_iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = mBanSources . begin ( ) ; it ! = mBanSources . end ( ) ; + + it )
2011-11-23 11:40:32 -05:00
{
out < < " BanList from: " < < it - > first ;
out < < " LastUpdate: " < < now - it - > second . mLastUpdate ;
out < < std : : endl ;
2013-09-13 10:35:19 -04:00
std : : map < struct sockaddr_storage , BanListPeer > : : const_iterator lit ;
2011-11-23 11:40:32 -05:00
for ( lit = it - > second . mBanPeers . begin ( ) ;
2014-10-24 18:07:26 -04:00
lit ! = it - > second . mBanPeers . end ( ) ; + + lit )
2011-11-23 11:40:32 -05:00
{
out < < " \t " ;
2013-09-13 10:35:19 -04:00
out < < " Ban: " < < sockaddr_storage_iptostring ( lit - > second . addr ) ;
2011-11-23 11:40:32 -05:00
out < < " Reason: " < < lit - > second . reason ;
2015-05-27 17:30:40 -04:00
out < < " Level: " < < lit - > second . level ;
2011-11-23 11:40:32 -05:00
out < < " Age: " < < now - lit - > second . mTs ;
out < < std : : endl ;
}
}
2015-05-28 17:44:43 -04:00
return true ;
2011-11-23 11:40:32 -05:00
}