(libT) allow custom blocklists... now all you need to do is place a file in the blocklists/ folder and Transmission will automatically use it the next time it starts.

This commit is contained in:
Charles Kerr 2008-06-11 16:15:45 +00:00
parent d2459fa2af
commit f0229ed8ad
10 changed files with 190 additions and 56 deletions

View File

@ -14,6 +14,7 @@
#include <stdlib.h> /* free */
#include <string.h>
#include <libgen.h> /* basename */
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -89,7 +90,14 @@ blocklistLoad( tr_blocklist * b )
b->byteCount = st.st_size;
b->ruleCount = st.st_size / sizeof( struct tr_ip_range );
b->fd = fd;
tr_inf( _( "Blocklist contains %'u entries" ), (unsigned int)b->ruleCount );
{
char * name;
char buf[MAX_PATH_LENGTH];
tr_strlcpy( buf, b->filename, sizeof( buf ) );
name = basename( buf );
tr_inf( _( "Blocklist \"%s\" contains %'u entries" ), name, (unsigned int)b->ruleCount );
}
}
static void
@ -133,6 +141,12 @@ _tr_blocklistNew( const char * filename, int isEnabled )
return b;
}
const char*
_tr_blocklistGetFilename( const tr_blocklist * b )
{
return b->filename;
}
void
_tr_blocklistFree( tr_blocklist * b )
{
@ -142,9 +156,16 @@ _tr_blocklistFree( tr_blocklist * b )
}
int
_tr_blocklistGetRuleCount( tr_blocklist * b )
_tr_blocklistExists( const tr_blocklist * b )
{
blocklistEnsureLoaded( b );
struct stat st;
return !stat( b->filename, &st );
}
int
_tr_blocklistGetRuleCount( const tr_blocklist * b )
{
blocklistEnsureLoaded( (tr_blocklist*)b );
return b->ruleCount;
}
@ -185,13 +206,6 @@ _tr_blocklistHasAddress( tr_blocklist * b, const struct in_addr * addr )
return range != NULL;
}
int
_tr_blocklistExists( const tr_blocklist * b )
{
struct stat st;
return !stat( b->filename, &st );
}
int
_tr_blocklistSetContent( tr_blocklist * b,
const char * filename )
@ -255,7 +269,14 @@ _tr_blocklistSetContent( tr_blocklist * b,
++lineCount;
}
tr_inf( _( "Blocklist updated with %'d entries" ), lineCount );
{
char * name;
char buf[MAX_PATH_LENGTH];
tr_strlcpy( buf, b->filename, sizeof( buf ) );
name = basename( buf );
tr_inf( _( "Blocklist \"%s\" updated with %'d entries" ), name, lineCount );
}
fclose( out );
fclose( in );

View File

@ -17,12 +17,13 @@ struct in_addr;
typedef struct tr_blocklist tr_blocklist;
tr_blocklist* _tr_blocklistNew ( const char * filename, int isEnabled );
void _tr_blocklistFree ( tr_blocklist * b );
int _tr_blocklistGetRuleCount( tr_blocklist * b );
int _tr_blocklistIsEnabled ( tr_blocklist * b );
void _tr_blocklistSetEnabled ( tr_blocklist * b, int isEnabled );
int _tr_blocklistHasAddress ( tr_blocklist * b, const struct in_addr * addr );
int _tr_blocklistExists ( const tr_blocklist * b );
int _tr_blocklistSetContent ( tr_blocklist * b, const char * filename );
int _tr_blocklistExists ( const tr_blocklist * );
const char* _tr_blocklistGetFilename ( const tr_blocklist * );
int _tr_blocklistGetRuleCount( const tr_blocklist * );
void _tr_blocklistFree ( tr_blocklist * );
int _tr_blocklistIsEnabled ( tr_blocklist * );
void _tr_blocklistSetEnabled ( tr_blocklist *, int isEnabled );
int _tr_blocklistHasAddress ( tr_blocklist *, const struct in_addr * addr );
int _tr_blocklistSetContent ( tr_blocklist *, const char * filename );
#endif

View File

@ -1015,7 +1015,7 @@ tr_peerMgrAddIncoming( tr_peerMgr * manager,
{
managerLock( manager );
if( tr_blocklistHasAddress( manager->handle, addr ) )
if( tr_sessionIsAddressBlocked( manager->handle, addr ) )
{
tr_dbg( "Banned IP address \"%s\" tried to connect to us",
inet_ntoa( *addr ) );
@ -1053,7 +1053,7 @@ tr_peerMgrAddPex( tr_peerMgr * manager,
managerLock( manager );
t = getExistingTorrent( manager, torrentHash );
if( !tr_blocklistHasAddress( t->manager->handle, &pex->in_addr ) )
if( !tr_sessionIsAddressBlocked( t->manager->handle, &pex->in_addr ) )
ensureAtomExists( t, &pex->in_addr, pex->port, pex->flags, from );
managerUnlock( manager );
@ -1799,7 +1799,7 @@ getPeerCandidates( Torrent * t, int * setmeSize )
}
/* Don't connect to peers in our blocklist */
if( tr_blocklistHasAddress( t->manager->handle, &atom->addr ) )
if( tr_sessionIsAddressBlocked( t->manager->handle, &atom->addr ) )
continue;
ret[retCount++] = atom;

View File

@ -30,7 +30,7 @@ testWildcard( const char * in, const char * expected )
{
int ok;
char * str = cidrize( in );
fprintf( stderr, "in [%s] out [%s] should be [%s]\n", in, str, expected );
/* fprintf( stderr, "in [%s] out [%s] should be [%s]\n", in, str, expected ); */
ok = expected ? !strcmp( expected, str ) : !str;
tr_free( str );
return ok;

View File

@ -116,6 +116,71 @@ tr_sessionSetEncryption( tr_session * session, tr_encryption_mode mode )
****
***/
static void
loadBlocklists( tr_session * session )
{
int binCount = 0;
int newCount = 0;
struct stat sb;
char dirname[MAX_PATH_LENGTH];
DIR * odir = NULL;
tr_list * list = NULL;
const int isEnabled = session->isBlocklistEnabled;
/* walk through the directory and find blocklists */
tr_buildPath( dirname, sizeof( dirname ), session->configDir, "blocklists", NULL );
if( !stat( dirname, &sb ) && S_ISDIR( sb.st_mode ) && (( odir = opendir( dirname ))))
{
struct dirent *d;
for( d=readdir( odir ); d; d=readdir( odir ) )
{
char filename[MAX_PATH_LENGTH];
if( !d->d_name || d->d_name[0]=='.' ) /* skip dotfiles, ., and .. */
continue;
tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
if( tr_stringEndsWith( filename, ".bin" ) )
{
/* if we don't already have this blocklist, add it */
if( !tr_list_find( list, filename, (TrListCompareFunc)strcmp ) )
{
tr_list_append( &list, _tr_blocklistNew( filename, isEnabled ) );
++binCount;
}
}
else
{
/* strip out the file suffix, if there is one, and add ".bin" instead */
tr_blocklist * b;
const char * dot = strrchr( d->d_name, '.' );
const int len = dot ? dot - d->d_name : (int)strlen( d->d_name );
char tmp[MAX_PATH_LENGTH];
snprintf( tmp, sizeof( tmp ),
"%s%c%*.*s.bin", dirname, TR_PATH_DELIMITER, len, len, d->d_name );
b = _tr_blocklistNew( tmp, isEnabled );
_tr_blocklistSetContent( b, filename );
tr_list_append( &list, b );
++newCount;
}
}
closedir( odir );
}
session->blocklists = list;
if( binCount )
tr_dbg( "Found %d blocklists in \"%s\"", binCount, dirname );
if( newCount )
tr_dbg( "Found %d new blocklists in \"%s\"", newCount, dirname );
}
/***
****
***/
static void metainfoLookupRescan( tr_handle * h );
tr_handle *
@ -206,8 +271,8 @@ tr_sessionInitFull( const char * configDir,
/* initialize the blocklist */
tr_buildPath( filename, sizeof( filename ), h->configDir, "blocklists", NULL );
tr_mkdirp( filename, 0777 );
tr_buildPath( filename, sizeof( filename ), h->configDir, "blocklists", "level1.bin", NULL );
h->blocklist = _tr_blocklistNew( filename, isBlocklistEnabled );
h->isBlocklistEnabled = isBlocklistEnabled;
loadBlocklists( h );
tr_statsInit( h );
@ -485,8 +550,7 @@ tr_sessionClose( tr_handle * h )
while( !h->isClosed && !deadlineReached( deadline ) )
tr_wait( 100 );
_tr_blocklistFree( h->blocklist );
h->blocklist = NULL;
tr_list_free( &h->blocklists, (TrListForeachFunc)_tr_blocklistFree );
tr_webClose( &h->web );
tr_eventClose( h );
@ -535,11 +599,14 @@ tr_sessionLoadTorrents ( tr_handle * h,
tr_torrent * tor;
char filename[MAX_PATH_LENGTH];
tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
tr_ctorSetMetainfoFromFile( ctor, filename );
tor = tr_torrentNew( h, ctor, NULL );
if( tor ) {
tr_list_append( &list, tor );
n++;
if( tr_stringEndsWith( filename, ".torrent" ) )
{
tr_ctorSetMetainfoFromFile( ctor, filename );
tor = tr_torrentNew( h, ctor, NULL );
if( tor ) {
tr_list_append( &list, tor );
++n;
}
}
}
}
@ -600,39 +667,66 @@ tr_sessionIsPortForwardingEnabled( const tr_handle * h )
***/
int
tr_blocklistGetRuleCount( tr_handle * handle )
tr_blocklistGetRuleCount( const tr_session * session )
{
return _tr_blocklistGetRuleCount( handle->blocklist );
int n = 0;
tr_list * l;
for( l=session->blocklists; l; l=l->next )
n += _tr_blocklistGetRuleCount( l->data );
return n;
}
int
tr_blocklistIsEnabled( const tr_handle * handle )
tr_blocklistIsEnabled( const tr_session * session )
{
return _tr_blocklistIsEnabled( handle->blocklist );
return session->isBlocklistEnabled;
}
void
tr_blocklistSetEnabled( tr_handle * handle, int isEnabled )
tr_blocklistSetEnabled( tr_session * session, int isEnabled )
{
_tr_blocklistSetEnabled( handle->blocklist, isEnabled );
tr_list * l;
session->isBlocklistEnabled = isEnabled ? 1 : 0;
for( l=session->blocklists; l; l=l->next )
_tr_blocklistSetEnabled( l->data, isEnabled );
}
int
tr_blocklistExists( const tr_handle * handle )
tr_blocklistExists( const tr_session * session )
{
return _tr_blocklistExists( handle->blocklist );
return session->blocklists != NULL;
}
int
tr_blocklistSetContent( tr_handle * handle, const char * filename )
tr_blocklistSetContent( tr_session * session, const char * contentFilename )
{
return _tr_blocklistSetContent( handle->blocklist, filename );
tr_list * l;
tr_blocklist * b;
const char * defaultName = "level1.bin";
for( b=NULL, l=session->blocklists; !b && l; l=l->next )
if( tr_stringEndsWith( _tr_blocklistGetFilename( l->data ), defaultName ) )
b = l->data;
if( !b ) {
char filename[MAX_PATH_LENGTH];
tr_buildPath( filename, sizeof( filename ), session->configDir, "blocklists", defaultName, NULL );
b = _tr_blocklistNew( filename, session->isBlocklistEnabled );
tr_list_append( &session->blocklists, b );
}
return _tr_blocklistSetContent( b, contentFilename );
}
int
tr_blocklistHasAddress( tr_handle * handle, const struct in_addr * addr )
tr_sessionIsAddressBlocked( const tr_session * session,
const struct in_addr * addr )
{
return _tr_blocklistHasAddress( handle->blocklist, addr );
tr_list * l;
for( l=session->blocklists; l; l=l->next )
if( _tr_blocklistHasAddress( l->data, addr ) )
return TRUE;
return FALSE;
}
/***

View File

@ -51,6 +51,7 @@ struct tr_handle
{
unsigned int isPortSet : 1;
unsigned int isPexEnabled : 1;
unsigned int isBlocklistEnabled : 1;
unsigned int isProxyEnabled : 1;
unsigned int isProxyAuthEnabled : 1;
unsigned int isClosed : 1;
@ -80,7 +81,7 @@ struct tr_handle
struct tr_ratecontrol * upload;
struct tr_ratecontrol * download;
struct tr_blocklist * blocklist;
struct tr_list * blocklists;
struct tr_peerMgr * peerMgr;
struct tr_shared * shared;
@ -106,6 +107,12 @@ void tr_sessionSetTorrentFile( tr_session * session,
const char * hashString,
const char * filename );
struct in_addr;
int tr_sessionIsAddressBlocked( const tr_session * session,
const struct in_addr * addr );
void tr_globalLock ( tr_session * );
void tr_globalUnlock ( tr_session * );
int tr_globalIsLocked ( const tr_session * );

View File

@ -605,22 +605,18 @@ void tr_freeMessageList( tr_msg_list * freeme );
*
* Passing NULL for a filename will clear the blocklist.
*/
int tr_blocklistSetContent( tr_handle * handle,
const char * filename );
int tr_blocklistSetContent ( tr_session * session,
const char * filename );
int tr_blocklistGetRuleCount( tr_handle * handle );
int tr_blocklistGetRuleCount ( const tr_session * session );
int tr_blocklistExists( const tr_handle * handle );
int tr_blocklistExists ( const tr_session * session );
int tr_blocklistIsEnabled( const tr_handle * handle );
int tr_blocklistIsEnabled ( const tr_session * session );
void tr_blocklistSetEnabled( tr_handle * handle,
int isEnabled );
void tr_blocklistSetEnabled ( tr_session * session,
int isEnabled );
struct in_addr;
int tr_blocklistHasAddress( tr_handle * handle,
const struct in_addr * addr);
/** @} */

View File

@ -93,6 +93,13 @@ main( void )
tr_free( in );
tr_free( out );
/* tr_stringEndsWith */
check( tr_stringEndsWith( "the", "the" ) );
check( tr_stringEndsWith( "dress", "dress" ) );
check( tr_stringEndsWith( "address", "dress" ) );
check( !tr_stringEndsWith( "foo.bin", "gfoo.bin" ) );
check( !tr_stringEndsWith( "xyz", "xyw" ) );
/* simple bitfield tests */
for( l=0; l<NUM_LOOPS; ++l )
if(( i = test_bitfields( )))

View File

@ -921,6 +921,14 @@ tr_wait( uint64_t delay_milliseconds )
****
***/
int
tr_stringEndsWith( const char * str, const char * end )
{
const size_t slen = strlen( str );
const size_t elen = strlen( end );
return slen>=elen && !memcmp( &str[slen-elen], end, elen );
}
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).

View File

@ -197,7 +197,7 @@ char* tr_base64_decode( const void * input, int inlen, int *outlen ) TR_GNUC_MAL
size_t tr_strlcpy( char * dst, const char * src, size_t siz );
int tr_stringEndsWith( const char * string, const char * end );
const char* tr_strerror( int );