SOURCES: rtorrent-ip_filter.patch (NEW) - adds ip filtering capabilities to...
kosmo
kosmo at pld-linux.org
Thu Sep 11 10:57:07 CEST 2008
Author: kosmo Date: Thu Sep 11 08:57:07 2008 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- adds ip filtering capabilities to rtorrent.
- source and docs: http://libtorrent.rakshasa.no/ticket/239
---- Files affected:
SOURCES:
rtorrent-ip_filter.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/rtorrent-ip_filter.patch
diff -u /dev/null SOURCES/rtorrent-ip_filter.patch:1.1
--- /dev/null Thu Sep 11 10:57:07 2008
+++ SOURCES/rtorrent-ip_filter.patch Thu Sep 11 10:57:01 2008
@@ -0,0 +1,859 @@
+diff -urN rtorrent-0.8.2.orig/ip_filter_test.cc rtorrent-0.8.2/ip_filter_test.cc
+--- rtorrent-0.8.2.orig/ip_filter_test.cc 1970-01-01 01:00:00.000000000 +0100
++++ rtorrent-0.8.2/ip_filter_test.cc 2008-05-21 01:17:53.000000000 +0200
+@@ -0,0 +1,104 @@
++#include <iostream>
++#include <fstream>
++#include <string>
++#include <map>
++
++#include "ip_address.h"
++#include "ip_range.h"
++#include "ip_filter.h"
++
++#define null NULL
++
++using namespace std;
++using namespace core;
++
++void testIncludes( map<const IpAddress,IpRange::ptr>& m, string s ) {
++ cout << "** test includes '" << s << "'" << endl;
++ const IpAddress* ip = IpAddress::parse( s );
++ if( !ip ) {
++ cout << "ip is invalid" << endl;
++ return;
++ }
++ for( map<const IpAddress,IpRange::ptr>::iterator it = m.begin() ; it != m.end(); it++ ) {
++ const IpAddress* a = &(it->first);
++ IpRange* ir = it->second;
++ cout << '\t' << ir->to_string() << ": " << (ir->includes( *ip ) ? "true" : "false") << endl;
++ }
++}
++
++void testMap( map<const IpAddress,IpRange::ptr>& m ) {
++ for( map<const IpAddress,IpRange::ptr>::iterator it = m.begin() ; it != m.end(); it++ ) {
++ const IpAddress a = it->first;
++ IpRange* ir = it->second;
++ cout << a << ": " << *ir << endl;
++ }
++}
++
++IpFilter* testLoad( char* fileName ) {
++ cout << "testLoad" << endl;
++ string s( fileName );
++ IpFilter* f = new IpFilter();
++
++ f->add_from_file( s );
++ cout << *f << endl;
++
++ return f;
++}
++
++IpFilter* testLoadMultiple( char* fileName[], int size ) {
++ cout << "testLoadMultiple" << endl;
++ IpFilter* f = new IpFilter();
++
++ int entries = 0;
++ for( int i = 0; i < size; i++ ) {
++ cout << "Loading '" << fileName[i] << "'...";
++ cout.flush();
++ int merges = f->add_from_file( fileName[i] );
++ if( merges < 0 )
++ break;
++ cout << "done. loaded " << (f->size()-entries) << " entries, " << merges << " merges" << endl;
++ entries = f->size();
++ }
++ cout << "Total loaded " << f->size() << " entries, " << f->get_merges() << " merges" << endl;
++ //cerr << *f << endl;
++
++ return f;
++}
++
++void testIncludes( IpFilter* f, char* ip ) {
++ string s( ip );
++
++ cout << s << " filtered=" << (f->is_filtered(s) ? "true" : "false") << endl;
++}
++
++void testReload( IpFilter* f ) {
++ cout << "Reloading...";
++ cout.flush();
++ f->reload();
++ cout << "done. loaded " << f->size() << " entries, " << f->get_merges() << " merges" << endl;
++}
++
++int main( int argn, char* argv[] ) {
++ try
++ {
++ cout << "testMain" << endl;
++ if( argn < 3 ) {
++ cout << "aruments: file name, ip" << endl;
++ return -1;
++ }
++
++ IpFilter* f = testLoadMultiple( &argv[1], argn-2 );
++ testReload( f );
++ testReload( f );
++// testReload( f );
++ testIncludes( f, argv[argn-1] );
++ delete f;
++ }
++ catch (exception& e)
++ {
++ cout << e.what() << endl;
++ }
++
++ return 0;
++}
++
+diff -urN rtorrent-0.8.2.orig/src/command_network.cc rtorrent-0.8.2/src/command_network.cc
+--- rtorrent-0.8.2.orig/src/command_network.cc 2008-05-07 14:19:11.000000000 +0200
++++ rtorrent-0.8.2/src/command_network.cc 2008-09-11 08:39:12.000000000 +0200
+@@ -36,6 +36,16 @@
+
+ #include "config.h"
+
++#include <string>
++#include <sstream>
++#include <list>
++#include <unistd.h>
++
++#include <string>
++#include <sstream>
++#include <list>
++#include <unistd.h>
++
+ #include <functional>
+ #include <rak/address_info.h>
+ #include <rak/path.h>
+@@ -61,6 +71,14 @@
+ #include "control.h"
+ #include "command_helpers.h"
+
++#include <boost/algorithm/string/trim.hpp>
++#include "core/ip_filter.h"
++
++
++#include <boost/algorithm/string/trim.hpp>
++#include "core/ip_filter.h"
++
++
+ torrent::Object
+ apply_encryption(const torrent::Object& rawArgs) {
+ const torrent::Object::list_type& args = rawArgs.as_list();
+@@ -94,6 +112,57 @@
+ }
+
+ torrent::Object
++apply_ip_filter(const torrent::Object& rawArgs) {
++ const torrent::Object::list_type& args = rawArgs.as_list();
++
++ std::list<std::string> files;
++
++ for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) {
++ std::string file( itr->as_string() );
++ boost::trim( file );
++ if( access(file.c_str(),F_OK | R_OK) )
++ throw torrent::input_error("IpFilter file '" + file + "' does not exist or not readable. Filter could not be loaded");
++ files.push_back( file );
++ }
++
++ std::stringstream logMsg;
++ if( files.empty() ) {
++ logMsg << "IpFilter is empty";
++ control->core()->push_log( logMsg.str().c_str() );
++ }
++ else {
++ core::IpFilter* f = new core::IpFilter();
++ logMsg << "IpFilter is initialized with files: ";
++ int entries = 0;
++ for( std::list<std::string>::iterator itr = files.begin(); itr != files.end(); itr++) {
++ std::cout << "Loading IP filters from '" << *itr << "'...";
++ std::cout.flush();
++ if( itr != files.begin() )
++ logMsg << ", ";
++ logMsg << *itr;
++ int merges = f->add_from_file( *itr );
++ if( merges < 0 ) {
++ std::cout << "error" << std::endl;
++ std::cout.flush();
++ throw torrent::input_error("IpFilter could not load file '" + *itr + "'");
++ }
++ std::cout << "done. Loaded " << (f->size()-entries) << " ranges. " << merges << " ranges were merged." << std::endl;
++ std::cout.flush();
++ entries = f->size();
++ }
++ control->core()->push_log( logMsg.str().c_str() );
++ std::stringstream logMsg2("IpFilter loaded with ");
++ logMsg2 << f->size() << " ranges total. " << f->get_merges() << " ranges were merged.";
++ control->core()->push_log( logMsg2.str().c_str() );
++ std::cout << logMsg2 << std::endl;
++ std::cout.flush();
++ control->core()->set_ip_filter( f );
++ }
++
++ return torrent::Object();
++}
++
++torrent::Object
+ apply_tos(const torrent::Object& rawArg) {
+ rpc::Command::value_type value;
+ torrent::ConnectionManager* cm = torrent::connection_manager();
+@@ -366,6 +486,12 @@
+
+ ADD_VARIABLE_BOOL("peer_exchange", true);
+
++ ADD_COMMAND_VOID("reload_ip_filter", rak::make_mem_fun(control->core(), &core::Manager::reload_ip_filter));
++ ADD_COMMAND_LIST("ip_filter", rak::ptr_fn(&apply_ip_filter));
++
++ ADD_COMMAND_VOID("reload_ip_filter", rak::make_mem_fun(control->core(), &core::Manager::reload_ip_filter));
++ ADD_COMMAND_LIST("ip_filter", rak::ptr_fn(&apply_ip_filter));
++
+ // Not really network stuff:
+ ADD_VARIABLE_BOOL("handshake_log", false);
+ ADD_VARIABLE_STRING("tracker_dump", "");
+diff -urN rtorrent-0.8.2.orig/src/core/ip_address.cc rtorrent-0.8.2/src/core/ip_address.cc
+--- rtorrent-0.8.2.orig/src/core/ip_address.cc 1970-01-01 01:00:00.000000000 +0100
++++ rtorrent-0.8.2/src/core/ip_address.cc 2008-05-21 01:15:13.000000000 +0200
+@@ -0,0 +1,25 @@
++#include <cstdlib>
++#include <string>
++#include <arpa/inet.h>
++#include <boost/xpressive/xpressive.hpp>
++
++#include "ip_address.h"
++
++namespace core {
++
++std::pair<bool,uint32_t> IpAddress::to_int( const std::string& address ) {
++ uint32_t a;
++ int r = inet_pton( AF_INET, address.c_str(), &a);
++ if( r )
++ a = ntohl( a );
++ return std::pair<bool,uint32_t>( (r!=0), a );
++}
++
++std::string IpAddress::to_string() const {
++ char buf[128] = "";
++ uint32_t a = htonl( m_address );
++ inet_ntop( AF_INET, &a, buf, sizeof(buf) );
++ return std::string( buf );
++}
++
++}
+diff -urN rtorrent-0.8.2.orig/src/core/ip_address.h rtorrent-0.8.2/src/core/ip_address.h
+--- rtorrent-0.8.2.orig/src/core/ip_address.h 1970-01-01 01:00:00.000000000 +0100
++++ rtorrent-0.8.2/src/core/ip_address.h 2008-05-21 01:15:13.000000000 +0200
+@@ -0,0 +1,67 @@
++#ifndef IPADDRESS_H
++#define IPADDRESS_H
++
++#include <string>
++#include <boost/xpressive/xpressive.hpp>
++
++#include "printable.h"
++#include "regex_namespace.h"
++
++namespace core {
++
++class IpAddress : public Printable {
++ friend class IpRange;
++
++ private: // constants
++ static const std::string PATTERN_IP_EXPRESSION;
++ static const std::string PATTERN_IP_BYTES_EXPRESSION;
++ static const regex::sregex PATTERN_IP_BYTES;
++
++ static const int GRP_IP_FIRST_BYTE;
++ static const int GRP_IP_BYTES_COUNT;
++
++ private: // fields
++ uint32_t m_address;
++
++ private: // static methods
++
++ private: // dynamic methods
++ IpAddress() : m_address(0) {}
++
++ void copy( const IpAddress& addr ) {
++ m_address = addr.m_address;
++ }
++
++ public: // static methods
++ static std::pair<bool,uint32_t> to_int( const std::string& strAddress );
++ static IpAddress* parse( const std::string& strAddress ) {
++ std::pair<bool,uint32_t> result = to_int( strAddress );
++ return ( !result.first ) ? NULL : new IpAddress( result.second );
++ }
++
++ public: // dynamic methods
++ IpAddress( uint32_t address ) : m_address(address) {}
++ IpAddress( const IpAddress& addr ) { copy( addr ); }
++ IpAddress& operator= ( const IpAddress& addr ) { copy( addr ); return *this; }
++
++ operator uint32_t() const { return m_address; }
++
++ bool operator>= ( const IpAddress& ip ) const { return (m_address >= ip.m_address); }
++ bool operator<= ( const IpAddress& ip ) const { return (m_address <= ip.m_address); }
++ bool operator< ( const IpAddress& ip ) const { return (m_address < ip.m_address); }
++ bool operator> ( const IpAddress& ip ) const { return (m_address > ip.m_address); }
++ bool operator== ( const IpAddress& ip ) const { return (m_address == ip.m_address); }
++ bool operator!= ( const IpAddress& ip ) const { return (m_address != ip.m_address); }
++
++ bool operator>= ( uint32_t ip ) const { return (m_address >= ip); }
++ bool operator<= ( uint32_t ip ) const { return (m_address <= ip); }
++ bool operator< ( uint32_t ip ) const { return (m_address < ip); }
++ bool operator> ( uint32_t ip ) const { return (m_address > ip); }
++ bool operator== ( uint32_t ip ) const { return (m_address == ip); }
++ bool operator!= ( uint32_t ip ) const { return (m_address != ip); }
++
++ std::string to_string() const;
++};
++
++}
++#endif
+diff -urN rtorrent-0.8.2.orig/src/core/ip_filter.cc rtorrent-0.8.2/src/core/ip_filter.cc
+--- rtorrent-0.8.2.orig/src/core/ip_filter.cc 1970-01-01 01:00:00.000000000 +0100
++++ rtorrent-0.8.2/src/core/ip_filter.cc 2008-05-21 01:15:13.000000000 +0200
+@@ -0,0 +1,166 @@
++#include <string>
++#include <map>
++#include <list>
++#include <fstream>
++#include <boost/algorithm/string/trim.hpp>
++
++#include "ip_filter.h"
++
++namespace core {
++
++int IpFilter::merge_and_insert( range_map* rs, IpRange* r ) {
++ if( !r || !r->get_from() )
++ return 0;
++
++ std::pair<const IpAddress,IpRange::ptr> p( *r->get_from(), IpRange::ptr(r) );
++ std::pair<range_itr,bool> duo = rs->insert( p );
++
++ range_itr idx = duo.first;
++ bool wasInserted = duo.second;
++ IpRange* curr = NULL;
++ int mergeCount = 0;
++
++ if( !wasInserted ) { // exactly the same start address already exists
++ curr = idx->second;
++ if( *curr->get_to() < *r->get_to() )
++ curr->set_to( r->get_to() );
++ delete r;
++ r = curr;
++ mergeCount++;
++ }
++ else {
++ if( idx != rs->begin() ) {
++ --idx;
++ curr = idx->second; // previous
++ if( *r->get_from() <= *curr->get_to() )
++ r = curr;
++ else
++ ++idx;
++ }
++ }
++
++ if( idx != rs->end() )
++ ++idx;
++
++ while( idx != rs->end() ) {
++ curr = idx->second;
++ if( *r->get_to() < *curr->get_from() )
++ break;
++
++ std::string d = r->get_description();
++ d += " / " + curr->get_description();
++ r->set_description( d );
++ if( *r->get_to() < *curr->get_to() )
++ r->set_to( curr->get_to() );
++ rs->erase( idx++ );
++ delete curr;
++ mergeCount++;
++ }
++ return mergeCount;
++}
++
++int IpFilter::add_from_file( const std::string& fileName, range_map* rs, str_list* files ) {
++ std::ifstream in( fileName.c_str() );
++ std::string line;
++ int mergeCount = 0;
++
++ if( in.fail() || !in.is_open() )
++ return -1;
++
++ while( in.good() ) {
++ std::getline( in, line );
++ boost::trim( line );
++
++ if( (line[0] == '#') || (line.length() == 0) )
++ continue;
++
++ IpRange* ir = IpRange::parse( line );
++ if( !ir || !ir->get_from() || !ir->get_to() )
++ continue;
++
++ mergeCount += merge_and_insert( rs, ir );
++ }
++ files->push_back( std::string(fileName) );
++ in.close();
++
++ m_merges += mergeCount;
++ return mergeCount;
++}
++
++int IpFilter::add_from_file( const std::string& fileName ) {
++ if( !m_ranges )
++ m_ranges = new range_map();
++ if( !m_loadedFiles )
++ m_loadedFiles = new std::list<std::string>();
++
++ return add_from_file( fileName, m_ranges, m_loadedFiles );
++}
++
++int IpFilter::reload() {
++ if( !m_loadedFiles || m_loadedFiles->empty() )
++ return 0;
++
++ range_map* rs = new range_map();
++ str_list* files = new str_list();
++ int mergeCount = 0;
++ for( str_list::const_iterator it = m_loadedFiles->begin(), end = m_loadedFiles->end(); it != end; it++ )
++ mergeCount += add_from_file( *it, rs, files );
++
++ range_map* rsOld = m_ranges;
++ m_ranges = rs;
++ if( rsOld ) {
++ clear( rsOld );
++ delete rsOld;
++ }
++
++ str_list* filesOld = m_loadedFiles;
++ m_loadedFiles = files;
++ if( filesOld ) {
++ clear( filesOld );
++ delete filesOld;
++ }
++
++ m_merges = mergeCount;
++ return mergeCount;
++}
++
++IpRange* IpFilter::find_range( int ip ) const {
++ if( (ip >= 0) && m_ranges && !m_ranges->empty() ) {
++ range_itr idx = m_ranges->lower_bound( ip );
++ if( idx != m_ranges->begin() )
++ --idx;
++ IpRange* curr = idx->second;
++ if( curr->includes( ip ) )
++ return curr;
++ }
++ return NULL;
++}
++
++std::string IpFilter::to_string() const {
++ std::stringstream result;
++ if( !m_ranges )
++ result << "NULL" << std::endl;
++ else {
++ for( range_map::const_iterator it = m_ranges->begin() ; it != m_ranges->end(); it++ ) {
++ const IpAddress a = it->first;
++ IpRange* ir = it->second;
++ result << a << ": " << *ir << std::endl;
++ }
++ }
++ return result.str();
++}
++
++void IpFilter::clear( range_map* map ) {
++ if( map ) {
++ for( range_itr i = map->begin(), j = map->end(); i != j; i++ )
++ delete i->second;
++ map->clear();
++ }
++}
++
++void IpFilter::clear( str_list* list ) {
++ if( list )
++ list->clear();
++}
++
++}
+diff -urN rtorrent-0.8.2.orig/src/core/ip_filter.h rtorrent-0.8.2/src/core/ip_filter.h
+--- rtorrent-0.8.2.orig/src/core/ip_filter.h 1970-01-01 01:00:00.000000000 +0100
++++ rtorrent-0.8.2/src/core/ip_filter.h 2008-05-21 01:15:13.000000000 +0200
+@@ -0,0 +1,86 @@
++#ifndef IPFILTER_H
++#define IPFILTER_H
++
++#include <string>
++#include <map>
++#include <list>
++
++#include "printable.h"
++#include "ip_address.h"
++#include "ip_range.h"
++#include "regex_namespace.h"
++
++namespace core {
++
++typedef std::map<const IpAddress,IpRange::ptr> range_map;
++typedef range_map::iterator range_itr;
++typedef std::list<std::string> str_list;
++
++class IpFilter : public Printable {
++ private: // fields
++ int m_merges;
++ range_map* m_ranges;
++ str_list* m_loadedFiles;
++
++ private: // static methods
++ static void clear( range_map* map );
++ static void clear( str_list* list );
++
++ private: // dynamic methods
++ void init_members(void) { // to avoid long constructor lines for every ctor
++ m_ranges = NULL;
++ m_loadedFiles = NULL;
++ m_merges = 0;
++ }
++ int merge_and_insert( range_map* rs, IpRange* r );
++ int add_from_file( const std::string& fileName, range_map* rs, str_list* files );
++
++ public: // static methods
++
++ public: // dynamic methods
++ IpFilter() { init_members(); }
++ ~IpFilter() {
++ clear();
++ if( m_ranges ) delete m_ranges;
++ if( m_loadedFiles ) delete m_loadedFiles;
++ m_ranges = NULL;
++ m_loadedFiles = NULL;
++ }
++ IpFilter( std::string* files, int size ) {
++ init_members();
++ for( int i = 0; i < size; i++, files++ )
++ add_from_file( *files );
++ }
++ IpFilter( str_list& files ) {
++ init_members();
++ for( str_list::const_iterator i = files.begin(), last = files.end(); i != last; i++ )
++ add_from_file( *i );
++ }
++ IpFilter( IpFilter& f ) {
++ init_members();
++ m_ranges = new range_map( *f.m_ranges );
++ m_loadedFiles = new str_list( *f.m_loadedFiles );
++ }
++
++ int reload();
++ int add_from_file( const std::string& fileName );
++ int add_from_file( char* fileName ) { std::string s( fileName ); return add_from_file(s); }
++ void clear() { clear( m_ranges ); clear( m_loadedFiles ); }
++
++ IpRange* find_range( int ip ) const;
++
++ bool is_filtered( int ip ) const { return (find_range( ip ) != NULL); }
++ bool is_filtered( std::string ip ) const {
++ static std::pair<bool,int> ipInt = IpAddress::to_int( ip );
++ return (!ipInt.first ? false : is_filtered( ipInt.second ));
++ }
++
++ std::string to_string() const;
++
++ int size(void) { return ( m_ranges ? m_ranges->size() : 0 ); }
++ int get_merges(void) { return m_merges; }
++ void set_files( str_list& files) { m_loadedFiles = new str_list( files ); }
++};
++
++}
++#endif
+diff -urN rtorrent-0.8.2.orig/src/core/ip_filter_statics.cc rtorrent-0.8.2/src/core/ip_filter_statics.cc
+--- rtorrent-0.8.2.orig/src/core/ip_filter_statics.cc 1970-01-01 01:00:00.000000000 +0100
++++ rtorrent-0.8.2/src/core/ip_filter_statics.cc 2008-05-21 01:15:35.000000000 +0200
+@@ -0,0 +1,20 @@
++#include "ip_address.h"
++#include "ip_range.h"
++
++namespace core {
++
++const std::string IpAddress::PATTERN_IP_EXPRESSION = "((?:\\d{1,3}\\.){3}\\d{1,3})";
++const std::string IpAddress::PATTERN_IP_BYTES_EXPRESSION = "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})";
++const regex::sregex IpAddress::PATTERN_IP_BYTES = regex::sregex::compile( PATTERN_IP_BYTES_EXPRESSION );
++
++const int IpAddress::GRP_IP_FIRST_BYTE = 1;
++const int IpAddress::GRP_IP_BYTES_COUNT = 4;
++
++const std::string IpRange::PATTERN_RANGE_EXPRESSION = "\\s*(.*)\\s*:\\s*" + IpAddress::PATTERN_IP_EXPRESSION + "\\s*-\\s*" + IpAddress::PATTERN_IP_EXPRESSION + "\\s*";
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list