Ticket #239: rtorrent-0.8.6-ip_filter_no_boost-fast.patch
| File rtorrent-0.8.6-ip_filter_no_boost-fast.patch, 28.7 KB (added by denis@fateyev.com, 2 years ago) |
|---|
-
src/command_network.cc
Based on 'rtorrent-0.8.5-ip_filter_no_boost-fast.patch' by Richard Monk and 'yb' Adapted for rtorrent-0.8.6 by Denis Fateyev <denis@fateyev.com> See http://libtorrent.rakshasa.no/ticket/239 for more details.
a b 36 36 37 37 #include "config.h" 38 38 39 #include <string> 40 #include <sstream> 41 #include <list> 42 #include <unistd.h> 43 39 44 #include <functional> 40 45 #include <cstdio> 41 46 #include <rak/address_info.h> … … 62 67 #include "control.h" 63 68 #include "command_helpers.h" 64 69 70 #include "utils/pattern.h" 71 #include "core/ip_filter.h" 72 73 65 74 torrent::Object 66 75 apply_throttle(bool up, const torrent::Object& rawArgs) { 67 76 const torrent::Object::list_type& args = rawArgs.as_list(); … … 209 218 } 210 219 211 220 torrent::Object 221 apply_ip_filter(const torrent::Object& rawArgs) { 222 const torrent::Object::list_type& args = rawArgs.as_list(); 223 224 std::list<std::string> files; 225 226 for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) { 227 std::string file( itr->as_string() ); 228 utils::trim( file ); 229 if( access(file.c_str(),F_OK | R_OK) ) 230 throw torrent::input_error("IpFilter file '" + file + "' does not exist or not readable. Filter could not be loaded"); 231 files.push_back( file ); 232 } 233 234 std::stringstream logMsg; 235 if( files.empty() ) { 236 logMsg << "IpFilter is empty"; 237 control->core()->push_log( logMsg.str().c_str() ); 238 } 239 else { 240 core::IpFilter* f = new core::IpFilter(); 241 logMsg << "IpFilter is initialized with files: "; 242 int entries = 0; 243 clock_t time_start = clock(); 244 for( std::list<std::string>::iterator itr = files.begin(); itr != files.end(); itr++) { 245 std::cout << "Loading IP filters from '" << *itr << "'..."; 246 std::cout.flush(); 247 if( itr != files.begin() ) 248 logMsg << ", "; 249 logMsg << *itr; 250 int merges = f->add_from_file( *itr ); 251 if( merges < 0 ) { 252 std::cout << "error" << std::endl; 253 std::cout.flush(); 254 throw torrent::input_error("IpFilter could not load file '" + *itr + "'"); 255 } 256 std::cout << "done. Loaded " << (f->size()-entries) << " ranges. " << merges << " ranges were merged." << std::endl; 257 std::cout.flush(); 258 entries = f->size(); 259 } 260 control->core()->push_log( logMsg.str().c_str() ); 261 std::stringstream logMsg2("IpFilter loaded with "); 262 logMsg2 << f->size() << " ranges total. " << f->get_merges() << " ranges were merged."; 263 control->core()->push_log( logMsg2.str().c_str() ); 264 std::cout << logMsg2.str() << std::endl; 265 std::cout << "IP_Filters loaded in " << (double)(clock()-time_start)/CLOCKS_PER_SEC << " seconds" << std::endl; 266 std::cout.flush(); 267 control->core()->set_ip_filter( f ); 268 } 269 270 return torrent::Object(); 271 } 272 273 torrent::Object 212 274 apply_tos(const torrent::Object& rawArg) { 213 275 rpc::Command::value_type value; 214 276 torrent::ConnectionManager* cm = torrent::connection_manager(); … … 492 554 493 555 ADD_VARIABLE_BOOL("peer_exchange", true); 494 556 557 ADD_COMMAND_VOID("reload_ip_filter", rak::make_mem_fun(control->core(), &core::Manager::reload_ip_filter)); 558 ADD_COMMAND_LIST("ip_filter", rak::ptr_fn(&apply_ip_filter)); 559 495 560 // Not really network stuff: 496 561 ADD_VARIABLE_BOOL("handshake_log", false); 497 562 ADD_VARIABLE_STRING("tracker_dump", ""); -
src/core/Makefile.am
a b 36 36 view.cc \ 37 37 view.h \ 38 38 view_manager.cc \ 39 view_manager.h 39 view_manager.h \ 40 ip_address.cc \ 41 ip_address.h \ 42 ip_filter.cc \ 43 ip_filter.h \ 44 ip_range.cc \ 45 ip_range.h \ 46 printable.h \ 47 regex_namespace.h \ 48 ip_filter_statics.cc 40 49 41 50 INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) -
src/core/Makefile.in
a b 60 60 manager.$(OBJEXT) poll_manager.$(OBJEXT) \ 61 61 poll_manager_epoll.$(OBJEXT) poll_manager_kqueue.$(OBJEXT) \ 62 62 poll_manager_select.$(OBJEXT) view.$(OBJEXT) \ 63 view_manager.$(OBJEXT) 63 view_manager.$(OBJEXT) \ 64 ip_address.$(OBJEXT) \ 65 ip_filter.$(OBJEXT) \ 66 ip_range.$(OBJEXT) \ 67 ip_filter_statics.$(OBJEXT) 64 68 libsub_core_a_OBJECTS = $(am_libsub_core_a_OBJECTS) 65 69 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) 66 70 depcomp = $(SHELL) $(top_srcdir)/depcomp … … 247 251 view.cc \ 248 252 view.h \ 249 253 view_manager.cc \ 250 view_manager.h 254 view_manager.h \ 255 ip_address.cc \ 256 ip_address.h \ 257 ip_filter.cc \ 258 ip_filter.h \ 259 ip_range.cc \ 260 ip_range.h \ 261 printable.h \ 262 regex_namespace.h \ 263 ip_filter_statics.cc 251 264 252 265 INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) 253 266 all: all-am … … 314 327 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll_manager_select.Po@am__quote@ 315 328 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view.Po@am__quote@ 316 329 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view_manager.Po@am__quote@ 330 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_address.Po@am__quote@ 331 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_range.Po@am__quote@ 332 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_filter_statics.Po@am__quote@ 317 333 318 334 .cc.o: 319 335 @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -
src/core/ip_address.cc
a b 1 #include <cstdlib> 2 #include <string> 3 #include <arpa/inet.h> 4 5 #include "ip_address.h" 6 #include "utils/pattern.h" 7 8 namespace core { 9 10 std::pair<bool,uint32_t> IpAddress::to_int( const std::string& address ) { 11 uint32_t a; 12 int r = inet_pton( AF_INET, address.c_str(), &a); 13 if( r ) 14 a = ntohl( a ); 15 return std::pair<bool,uint32_t>( (r!=0), a ); 16 } 17 18 std::string IpAddress::to_string() const { 19 char buf[128] = ""; 20 uint32_t a = htonl( m_address ); 21 inet_ntop( AF_INET, &a, buf, sizeof(buf) ); 22 return std::string( buf ); 23 } 24 25 } -
src/core/ip_address.h
a b 1 #ifndef IPADDRESS_H 2 #define IPADDRESS_H 3 4 #include <inttypes.h> 5 #include <string> 6 7 #include "printable.h" 8 #include "utils/pattern.h" 9 #include "regex_namespace.h" 10 11 namespace core { 12 13 class IpAddress : public Printable { 14 friend class IpRange; 15 16 private: // constants 17 static const std::string PATTERN_IP_EXPRESSION; 18 static const std::string PATTERN_IP_BYTES_EXPRESSION; 19 static const regex::Pattern PATTERN_IP_BYTES; 20 21 static const int GRP_IP_FIRST_BYTE; 22 static const int GRP_IP_BYTES_COUNT; 23 24 private: // fields 25 uint32_t m_address; 26 27 private: // static methods 28 29 private: // dynamic methods 30 IpAddress() : m_address(0) {} 31 32 void copy( const IpAddress& addr ) { m_address = addr.m_address;} 33 34 public: // static methods 35 static std::pair<bool,uint32_t> to_int( const std::string& strAddress ); 36 static IpAddress* parse( const std::string& strAddress ) { 37 std::pair<bool,uint32_t> result = to_int( strAddress ); 38 return ( !result.first ) ? NULL : new IpAddress( result.second ); 39 } 40 41 public: // dynamic methods 42 IpAddress( uint32_t address ) : m_address(address) {} 43 IpAddress( const IpAddress& addr ) { copy( addr ); } 44 IpAddress& operator= ( const IpAddress& addr ) { copy( addr ); return *this; } 45 46 operator uint32_t() const { return m_address; } 47 48 bool operator>= ( const IpAddress& ip ) const { return (m_address >= ip.m_address); } 49 bool operator<= ( const IpAddress& ip ) const { return (m_address <= ip.m_address); } 50 bool operator< ( const IpAddress& ip ) const { return (m_address < ip.m_address); } 51 bool operator> ( const IpAddress& ip ) const { return (m_address > ip.m_address); } 52 bool operator== ( const IpAddress& ip ) const { return (m_address == ip.m_address); } 53 bool operator!= ( const IpAddress& ip ) const { return (m_address != ip.m_address); } 54 55 bool operator>= ( uint32_t ip ) const { return (m_address >= ip); } 56 bool operator<= ( uint32_t ip ) const { return (m_address <= ip); } 57 bool operator< ( uint32_t ip ) const { return (m_address < ip); } 58 bool operator> ( uint32_t ip ) const { return (m_address > ip); } 59 bool operator== ( uint32_t ip ) const { return (m_address == ip); } 60 bool operator!= ( uint32_t ip ) const { return (m_address != ip); } 61 62 std::string to_string() const; 63 }; 64 } 65 #endif -
src/core/ip_filter.cc
a b 1 #include <sstream> 2 #include <string> 3 #include <map> 4 #include <list> 5 #include <fstream> 6 #include <stdio.h> 7 #include <stdlib.h> 8 9 #include "ip_filter.h" 10 11 namespace core { 12 13 int IpFilter::merge_and_insert( range_map* rs, IpRange* r ) { 14 if( !r || !r->get_from() ) 15 return 0; 16 17 std::pair<const IpAddress,IpRange::ptr> p( *r->get_from(), IpRange::ptr(r) ); 18 std::pair<range_itr,bool> duo = rs->insert( p ); 19 20 range_itr idx = duo.first; 21 bool wasInserted = duo.second; 22 IpRange* curr = NULL; 23 int mergeCount = 0; 24 25 if( !wasInserted ) { // exactly the same start address already exists 26 curr = idx->second; 27 if( *curr->get_to() < *r->get_to() ) 28 curr->set_to( r->get_to() ); 29 delete r; 30 r = curr; 31 mergeCount++; 32 } 33 else { 34 if( idx != rs->begin() ) { 35 --idx; 36 curr = idx->second; // previous 37 if( *r->get_from() <= *curr->get_to() ) 38 r = curr; 39 else 40 ++idx; 41 } 42 } 43 44 if( idx != rs->end() ) 45 ++idx; 46 47 while( idx != rs->end() ) { 48 curr = idx->second; 49 if( *r->get_to() < *curr->get_from() ) 50 break; 51 52 std::string d = r->get_description(); 53 d += " / " + curr->get_description(); 54 r->set_description( d ); 55 if( *r->get_to() < *curr->get_to() ) 56 r->set_to( curr->get_to() ); 57 rs->erase( idx++ ); 58 delete curr; 59 mergeCount++; 60 } 61 return mergeCount; 62 } 63 64 int IpFilter::add_from_file( const std::string& fileName, range_map* rs, str_list* files ) { 65 FILE *f = fopen(fileName.c_str(),"r"); 66 int mergeCount = 0; 67 if (f==0) return -1; 68 char *line = (char *)malloc(64); 69 size_t sz=64; 70 int charsread = 0; 71 int linesread=0; 72 while( (charsread=getline(&line,&sz,f)) >=0 ) { 73 if( (line[0] == '#' ) || ( charsread <= 1 ) ) 74 continue; 75 76 IpRange* ir = IpRange::parse( line, charsread ); 77 if( !ir || !ir->get_from() || !ir->get_to() ) 78 continue; 79 80 mergeCount += merge_and_insert( rs, ir ); 81 } 82 free(line); 83 files->push_back( std::string(fileName) ); 84 fclose(f); 85 m_merges += mergeCount; 86 return mergeCount; 87 } 88 89 int IpFilter::add_from_file( const std::string& fileName ) { 90 if( !m_ranges ) 91 m_ranges = new range_map(); 92 if( !m_loadedFiles ) 93 m_loadedFiles = new std::list<std::string>(); 94 95 return add_from_file( fileName, m_ranges, m_loadedFiles ); 96 } 97 98 int IpFilter::reload() { 99 if( !m_loadedFiles || m_loadedFiles->empty() ) 100 return 0; 101 102 range_map* rs = new range_map(); 103 str_list* files = new str_list(); 104 int mergeCount = 0; 105 for( str_list::const_iterator it = m_loadedFiles->begin(), end = m_loadedFiles->end(); it != end; it++ ) 106 mergeCount += add_from_file( *it, rs, files ); 107 108 range_map* rsOld = m_ranges; 109 m_ranges = rs; 110 if( rsOld ) { 111 clear( rsOld ); 112 delete rsOld; 113 } 114 115 str_list* filesOld = m_loadedFiles; 116 m_loadedFiles = files; 117 if( filesOld ) { 118 clear( filesOld ); 119 delete filesOld; 120 } 121 122 m_merges = mergeCount; 123 return mergeCount; 124 } 125 126 IpRange* IpFilter::find_range( uint32_t ip ) const { 127 if( (ip >= 0) && m_ranges && !m_ranges->empty() ) { 128 range_itr idx = m_ranges->upper_bound( ip ); 129 if( idx != m_ranges->begin() ) 130 --idx; 131 IpRange* curr = idx->second; 132 if( curr->includes( ip ) ) 133 return curr; 134 } 135 return NULL; 136 } 137 138 std::string IpFilter::to_string() const { 139 std::stringstream result; 140 if( !m_ranges ) 141 result << "NULL" << std::endl; 142 else { 143 for( range_map::const_iterator it = m_ranges->begin() ; it != m_ranges->end(); it++ ) { 144 const IpAddress a = it->first; 145 IpRange* ir = it->second; 146 result << a << ": " << *ir << std::endl; 147 } 148 } 149 return result.str(); 150 } 151 152 void IpFilter::clear( range_map* map ) { 153 if( map ) { 154 for( range_itr i = map->begin(), j = map->end(); i != j; i++ ) 155 delete i->second; 156 map->clear(); 157 } 158 } 159 160 void IpFilter::clear( str_list* list ) { 161 if( list ) 162 list->clear(); 163 } 164 165 } -
src/core/ip_filter.h
a b 1 #ifndef IPFILTER_H 2 #define IPFILTER_H 3 4 #include <string> 5 #include <map> 6 #include <list> 7 8 #include "printable.h" 9 #include "ip_address.h" 10 #include "ip_range.h" 11 12 namespace core { 13 14 typedef std::map<const IpAddress,IpRange::ptr> range_map; 15 typedef range_map::iterator range_itr; 16 typedef std::list<std::string> str_list; 17 18 class IpFilter : public Printable { 19 private: // fields 20 int m_merges; 21 range_map* m_ranges; 22 str_list* m_loadedFiles; 23 24 private: // static methods 25 static void clear( range_map* map ); 26 static void clear( str_list* list ); 27 28 private: // dynamic methods 29 void init_members(void) { // to avoid long constructor lines for every ctor 30 m_ranges = NULL; 31 m_loadedFiles = NULL; 32 m_merges = 0; 33 } 34 int merge_and_insert( range_map* rs, IpRange* r ); 35 int add_from_file( const std::string& fileName, range_map* rs, str_list* files ); 36 37 public: // static methods 38 39 public: // dynamic methods 40 IpFilter() { init_members(); } 41 ~IpFilter() { 42 clear(); 43 if( m_ranges ) delete m_ranges; 44 if( m_loadedFiles ) delete m_loadedFiles; 45 m_ranges = NULL; 46 m_loadedFiles = NULL; 47 } 48 IpFilter( std::string* files, int size ) { 49 init_members(); 50 for( int i = 0; i < size; i++, files++ ) 51 add_from_file( *files ); 52 } 53 IpFilter( str_list& files ) { 54 init_members(); 55 for( str_list::const_iterator i = files.begin(), last = files.end(); i != last; i++ ) 56 add_from_file( *i ); 57 } 58 IpFilter( IpFilter& f ) { 59 init_members(); 60 m_ranges = new range_map( *f.m_ranges ); 61 m_loadedFiles = new str_list( *f.m_loadedFiles ); 62 } 63 64 int reload(); 65 int add_from_file( const std::string& fileName ); 66 int add_from_file( char* fileName ) { std::string s( fileName ); return add_from_file(s); } 67 void clear() { clear( m_ranges ); clear( m_loadedFiles ); } 68 69 IpRange* find_range( uint32_t ip ) const; 70 71 bool is_filtered( uint32_t ip ) const { return (find_range( ip ) != NULL); } 72 bool is_filtered( std::string ip ) const { 73 static std::pair<bool,uint32_t> ipInt = IpAddress::to_int( ip ); 74 return (!ipInt.first ? false : is_filtered( ipInt.second )); 75 } 76 77 std::string to_string() const; 78 79 int size(void) { return ( m_ranges ? m_ranges->size() : 0 ); } 80 int get_merges(void) { return m_merges; } 81 void set_files( str_list& files) { m_loadedFiles = new str_list( files ); } 82 }; 83 84 } 85 #endif -
src/core/ip_filter_statics.cc
a b 1 #include "ip_address.h" 2 #include "ip_range.h" 3 #include "utils/pattern.h" 4 5 namespace core { 6 7 const std::string IpAddress::PATTERN_IP_EXPRESSION = "(([0-9]{1,3}\\.){3}[0-9]{1,3})"; 8 const std::string IpAddress::PATTERN_IP_BYTES_EXPRESSION = "([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})"; 9 const regex::Pattern IpAddress::PATTERN_IP_BYTES = PATTERN_IP_BYTES_EXPRESSION; 10 11 const int IpAddress::GRP_IP_FIRST_BYTE = 1; 12 const int IpAddress::GRP_IP_BYTES_COUNT = 4; 13 14 const std::string IpRange::PATTERN_RANGE_EXPRESSION = "[[:space:]]*(.*)[[:space:]]*:[[:space:]]*" + IpAddress::PATTERN_IP_EXPRESSION + "[[:space:]]*-[[:space:]]*" + IpAddress::PATTERN_IP_EXPRESSION + "[[:space:]]*"; 15 const regex::Pattern IpRange::PATTERN_RANGE = PATTERN_RANGE_EXPRESSION; 16 17 const int IpRange::GRP_DESCRIPTION = 1; 18 const int IpRange::GRP_FIRST_IP = 2; 19 const int IpRange::GRP_SECOND_IP = 4; 20 21 } -
src/core/ip_range.cc
a b 1 #include <sstream> 2 #include <string> 3 4 #include "ip_range.h" 5 #include "utils/pattern.h" 6 #include "regex_namespace.h" 7 8 namespace core { 9 10 IpRange* IpRange::parse( const std::string& s ) { 11 regex::Match m = PATTERN_RANGE.match( s ); 12 13 if( !m.matches() ) { 14 std::cout << "!! range format is invalid: '" << s << "'" << std::endl; 15 return NULL; 16 } 17 18 std::string description = m.group( GRP_DESCRIPTION ); 19 std::string ip1 = m.group( GRP_FIRST_IP ); 20 std::string ip2 = m.group( GRP_SECOND_IP ); 21 IpAddress* from = IpAddress::parse( ip1 ); 22 IpAddress* to = IpAddress::parse( ip2 ); 23 24 if( !from ) { 25 std::cout << "!! from is invalid: description='" << description << ", ip1=" << ip1 << ", ip2=" << ip2 << std::endl; 26 return NULL; 27 } 28 if( !to ) { 29 std::cout << "!! to is invalid: description='" << description << ", ip1=" << ip1 << ", ip2=" << ip2 << std::endl; 30 return NULL; 31 } 32 33 // if( !from || !to || (*to < *from) ) 34 // return NULL; 35 36 IpRange* r = new IpRange(); 37 38 r->m_description = description; 39 r->m_from = from; 40 r->m_to = to; 41 42 if( to && from && (*to < *from) ) { 43 std::cout << "!! to < from: " << r->to_string() << std::endl; 44 delete r; 45 return NULL; 46 } 47 48 return r; 49 } 50 51 //fast version 52 IpRange* IpRange::parse( const char *s, const int size ){ 53 static char description[256]; 54 static char ip1[24], ip2[24]; 55 int pos=0, post=0, enddesc=size-1; 56 while (enddesc>0 && s[enddesc]!=':') enddesc--; //find last ':' in the line 57 while((pos<enddesc) && (unsigned char)s[pos]<=' ') pos++; // strip from start 58 while ((pos<enddesc)){ 59 if (post<255) description[post++]=s[pos]; 60 pos++; 61 } 62 description[post]=0; 63 if (s[pos]==':') pos++; 64 post=0; 65 while ((pos<size) && s[pos]!='-'){ 66 if (post<23) ip1[post++]=s[pos]; 67 pos++; 68 } 69 ip1[post]=0; 70 if (s[pos]=='-'){ 71 pos++; 72 post=0; 73 while ((pos<size) && s[pos]>' '){ 74 if (post<23) ip2[post++]=s[pos]; 75 pos++; 76 } 77 ip2[post]=0; 78 } else ip2[0]=0; 79 80 IpAddress* from = IpAddress::parse(ip1); 81 IpAddress* to = IpAddress::parse(ip2); 82 83 if( !from ) { 84 std::cout << "!! from is invalid: description='" << description << ", ip1=" << ip1 << ", ip2=" << ip2 << std::endl; 85 return NULL; 86 } 87 if( !to ) { 88 std::cout << "!! to is invalid: description='" << description << ", ip1=" << ip1 << ", ip2=" << ip2 << std::endl; 89 return NULL; 90 } 91 92 IpRange* r = new IpRange(); 93 r->m_description = description; 94 r->m_from = from; 95 r->m_to = to; 96 97 if( (*to < *from) ) { 98 std::cout << "!! to < from: " << r->to_string() << std::endl; 99 delete r; 100 return NULL; 101 } 102 103 return r; 104 } 105 106 std::string IpRange::to_string() const { 107 std::stringstream result; 108 result << m_description << ": [" << m_from->to_string() << " - " << m_to->to_string() << ']'; 109 return result.str(); 110 } 111 112 } -
src/core/ip_range.h
a b 1 #ifndef IPRANGE_H 2 #define IPRANGE_H 3 4 #include <string> 5 6 #include "printable.h" 7 #include "ip_address.h" 8 #include "utils/pattern.h" 9 #include "regex_namespace.h" 10 11 namespace core { 12 13 class IpRange : public Printable { 14 public: // constants 15 static const std::string PATTERN_RANGE_EXPRESSION; 16 static const regex::Pattern PATTERN_RANGE; 17 18 static const int GRP_DESCRIPTION; 19 static const int GRP_FIRST_IP; 20 static const int GRP_SECOND_IP; 21 22 private: // fields 23 std::string m_description; 24 const IpAddress* m_from; 25 const IpAddress* m_to; 26 27 private: // dynamic methods 28 IpRange() : m_description(), m_from(NULL), m_to(NULL) {} 29 30 public: // static methods 31 typedef IpRange* ptr; 32 static IpRange* parse( const std::string& s ); 33 static IpRange* parse( const char *s, const int size ); 34 35 public: // dynamic methods 36 IpRange( IpRange& rng ) { copy(rng); } 37 IpRange& operator= ( IpRange& rng ) { copy(rng); return *this; } 38 39 void copy( IpRange& rng ) { 40 m_description = rng.m_description; 41 m_from = (!rng.m_from) ? NULL : new IpAddress( *rng.m_from ); 42 m_to = (!rng.m_to) ? NULL : new IpAddress( *rng.m_to ); 43 } 44 45 const std::string& get_description ( void ) const { return m_description; } 46 const IpAddress* get_from ( void ) const { return m_from; } 47 const IpAddress* get_to ( void ) const { return m_to; } 48 49 void set_description ( const std::string& description ) { m_description = description; } 50 void set_from ( const IpAddress* from ) { if( m_from ) delete m_from; m_from = new IpAddress( *from ); } 51 void set_to ( const IpAddress* to ) { if( m_to ) delete m_to; m_to = new IpAddress( *to ); } 52 53 bool includes( const IpAddress& ip ) const { return includes((uint32_t)ip); } 54 bool includes( uint32_t ip ) const { return (*m_from <= ip) && (*m_to >= ip); } 55 56 ~IpRange() { 57 delete m_from; 58 m_from = NULL; 59 delete m_to; 60 m_to = NULL; 61 } 62 63 std::string to_string() const; 64 }; 65 66 } 67 #endif -
src/core/manager.cc
a b 39 39 #include <cstdio> 40 40 #include <cstring> 41 41 #include <fstream> 42 #include <sstream> 42 43 #include <unistd.h> 43 44 #include <sys/select.h> 44 45 #include <rak/address_info.h> … … 151 152 } 152 153 } 153 154 155 uint32_t 156 Manager::filter_ip(const sockaddr* sa) { 157 IpRange* r = NULL; 158 // if something's wrong with filter or address it's gonna be allowed 159 if( m_ipFilter && sa ) { 160 const rak::socket_address* socketAddress = rak::socket_address::cast_from(sa); 161 if( socketAddress->is_valid() && (socketAddress->family() == rak::socket_address::af_inet) ) 162 r = m_ipFilter->find_range( socketAddress->sa_inet()->address_h() ); 163 if( r ) 164 m_logComplete.push_front("Address '" + socketAddress->address_str() + "' is rejected by IP filter range '" + r->to_string()); 165 else 166 if( rpc::call_command_value("get_handshake_log") ) 167 m_logComplete.push_front("IP Filter allowed connection with '" + socketAddress->address_str() + "'"); 168 } 169 return (r==NULL); 170 } 171 172 154 173 void 155 174 Manager::push_log(const char* msg) { 156 175 m_logImportant.push_front(msg); … … 158 158 } 159 159 160 160 Manager::Manager() : 161 m_hashingView(NULL) 161 m_hashingView(NULL), 162 m_ipFilter(NULL) 162 163 // m_pollManager(NULL) { 163 164 { 164 165 m_downloadStore = new DownloadStore(); … … 180 199 delete m_downloadStore; 181 200 delete m_httpQueue; 182 201 delete m_fileStatusCache; 202 203 set_ip_filter( NULL ); 183 204 } 184 205 185 206 void … … 259 280 CurlStack::global_init(); 260 281 261 282 torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log)); 283 torrent::connection_manager()->set_filter(sigc::mem_fun(this, &Manager::filter_ip)); 262 284 } 263 285 264 286 void … … 593 615 } 594 616 } 595 617 618 void Manager::reload_ip_filter(void) { 619 if( m_ipFilter ) { 620 push_log("Reloading IP filter"); 621 m_ipFilter->reload(); 622 std::stringstream logMsg("IpFilter reloaded with "); 623 logMsg << m_ipFilter->size() << " ranges total. " << m_ipFilter->get_merges() << " ranges were merged."; 624 push_log( logMsg.str().c_str() ); 625 } 626 } 596 627 } -
src/core/manager.h
a b 47 47 #include "range_map.h" 48 48 #include "log.h" 49 49 50 #include "ip_filter.h" 51 50 52 namespace torrent { 51 53 class Bencode; 52 54 } … … 120 122 121 123 void handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash); 122 124 125 uint32_t filter_ip(const sockaddr* sa); 126 127 void set_ip_filter( IpFilter* ipFilter ) { 128 IpFilter* old = m_ipFilter; 129 m_ipFilter = ipFilter; 130 if( old ) delete old; 131 } 132 void reload_ip_filter(void); 133 123 134 static const int create_start = 0x1; 124 135 static const int create_tied = 0x2; 125 136 static const int create_quiet = 0x4; … … 156 167 PollManager* m_pollManager; 157 168 Log m_logImportant; 158 169 Log m_logComplete; 170 171 IpFilter* m_ipFilter; 159 172 }; 160 173 161 174 // Meh, cleanup. -
src/core/printable.h
a b 1 #ifndef PRINTABLE_H 2 #define PRINTABLE_H 3 4 #include <iostream> 5 6 class Printable { 7 public: 8 virtual std::string to_string() const = 0; 9 }; 10 11 template<typename _CharT,class _Traits> inline std::basic_ostream<_CharT,_Traits>& 12 operator<<( std::basic_ostream<_CharT,_Traits>& out, const Printable& val) { 13 return out << val.to_string(); 14 } 15 16 #endif -
src/core/regex_namespace.h
a b 1 #ifndef REGEXNAMESPACE_H 2 #define REGEXNAMESPACE_H 3 4 namespace regex = utils; 5 6 #endif -
src/utils/Makefile.am
a b 9 9 lockfile.cc \ 10 10 lockfile.h \ 11 11 socket_fd.cc \ 12 socket_fd.h 12 socket_fd.h \ 13 pattern.cc \ 14 pattern.h 13 15 14 16 INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) -
src/utils/Makefile.in
a b 55 55 libsub_utils_a_LIBADD = 56 56 am_libsub_utils_a_OBJECTS = directory.$(OBJEXT) \ 57 57 file_status_cache.$(OBJEXT) lockfile.$(OBJEXT) \ 58 socket_fd.$(OBJEXT) 58 socket_fd.$(OBJEXT) pattern.$(OBJEXT) 59 59 libsub_utils_a_OBJECTS = $(am_libsub_utils_a_OBJECTS) 60 60 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) 61 61 depcomp = $(SHELL) $(top_srcdir)/depcomp … … 215 215 lockfile.cc \ 216 216 lockfile.h \ 217 217 socket_fd.cc \ 218 socket_fd.h 218 socket_fd.h \ 219 pattern.cc \ 220 pattern.h 219 221 220 222 INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) 221 223 all: all-am … … 269 271 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_status_cache.Po@am__quote@ 270 272 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockfile.Po@am__quote@ 271 273 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_fd.Po@am__quote@ 274 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pattern.@am__quote@ 272 275 273 276 .cc.o: 274 277 @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -
src/utils/pattern.cc
a b 1 #include <string> 2 #include <sys/types.h> 3 #include <ctype.h> 4 #include <regex.h> 5 6 #include "pattern.h" 7 8 namespace utils { 9 10 int Pattern::countGroups( const std::string& str ) { 11 int count1 = 0; 12 int count2 = 0; 13 14 for( size_t index = -1; (index = str.find( '(', index+1 )) != std::string::npos; ) 15 count1++; 16 for( size_t index = -1; (index = str.find( ')', index+1 )) != std::string::npos; ) 17 count2++; 18 19 return (count1 < count2) ? count1 : count2; 20 } 21 22 Pattern::Pattern( const std::string& pattern, Flags flags ) : lastResult(-1), 23 preg(NULL) { 24 int regFlags = REG_EXTENDED | REG_ICASE | REG_NEWLINE; 25 if( !(flags & CASE_SENSITIVE) ) 26 regFlags ^= REG_ICASE; 27 if( (flags & DOT_MATCH_NEWLINE) ) 28 regFlags ^= REG_NEWLINE; 29 30 preg = new regex_t; 31 numGroups = countGroups( pattern ) + 1; 32 33 lastResult = regcomp( preg, pattern.c_str(), regFlags ); 34 } 35 36 Pattern::~Pattern() { 37 regfree( preg ); 38 delete( preg ); 39 } 40 41 std::string Pattern::getLastError() const { 42 char errBuf[1024]; 43 regerror( lastResult, preg, errBuf, sizeof(errBuf) ); 44 return std::string(errBuf); 45 } 46 47 Match Pattern::match( const std::string& expression ) const { 48 49 regmatch_t* pmatch = new regmatch_t[numGroups]; 50 int res = regexec( preg, expression.c_str(), numGroups, pmatch, 0 ); 51 return Match( expression, numGroups, pmatch, res, getLastError() ); 52 } 53 54 Match::Match( const std::string& expr, int ngroups, regmatch_t* groups, int result, const std::string& message ) : 55 expression( expr ), 56 nmatch( ngroups ), 57 pmatch( groups ), 58 matchResult( result ), 59 matchMessage( message ) { 60 } 61 62 std::string Match::group( int i ) { 63 if( (i >= nmatch) || (pmatch[i].rm_so < 0) ) 64 return ""; 65 66 return expression.substr( pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so ); 67 } 68 69 std::string& trim( std::string& str ) { 70 std::string::iterator it; 71 for( it = str.begin(); (it < str.end()) && ( isspace(*it) || (*it == 0) ) ; it++ ); 72 str.erase( str.begin(), it ); 73 for( it = str.end()-1; (it >= str.begin()) && ( isspace(*it) || (*it == 0) ) ; it-- ); 74 str.erase( ++it, str.end() ); 75 return str; 76 } 77 78 } 79 -
src/utils/pattern.h
a b 1 #ifndef PATTERN_H 2 #define PATTERN_H 3 4 #include <string> 5 #include <sys/types.h> 6 #include <ctype.h> 7 #include <regex.h> 8 9 namespace utils { 10 11 class Match { 12 public: 13 Match( const std::string& expr, int ngroups, regmatch_t* pmatch, int matchResult, const std::string& matchMessage ); 14 ~Match() { delete[] pmatch; } 15 std::string group( int i ); 16 bool found() { return (matchResult == 0); } 17 bool matches() { return found(); } 18 std::string& getMatchMessage() { return matchMessage; } 19 20 private: 21 std::string expression; 22 int nmatch; 23 regmatch_t* pmatch; 24 int matchResult; 25 std::string matchMessage; 26 }; 27 28 class Pattern { 29 public: 30 enum Flags { 31 DEFAULT = 0, // REG_EXTENDED | REG_ICASE | REG_NEWLINE 32 CASE_SENSITIVE, 33 DOT_MATCH_NEWLINE 34 }; 35 36 public: 37 Pattern( const std::string& pattern, Flags f = Pattern::DEFAULT ); 38 ~Pattern(); 39 bool isSuccess() { return (lastResult == 0); } 40 std::string getLastError() const; 41 Match match( const std::string& expression ) const; 42 43 private: 44 int countGroups( const std::string& str ); 45 46 private: 47 regex_t* preg; 48 int lastResult; 49 int numGroups; 50 }; 51 52 53 std::string& trim( std::string& str ); 54 55 } 56 57 // end of ifdef PATTERN_H 58 #endif 59
