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