Ticket #239: fixed-rtorrent-0.8.7-ip_filter_no_boost-fast-bsd2.patch
| File fixed-rtorrent-0.8.7-ip_filter_no_boost-fast-bsd2.patch, 32.3 KB (added by jcuzella@lyraphase.com, 17 months ago) |
|---|
-
configure.ac
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> Adapted for rtorrent-0.8.7 by James Cuzella <james.cuzella@lyraphase.com> Rev.2 (BSD/MacOSX support provided) See http://libtorrent.rakshasa.no/ticket/239 for more details.
a b 4 4 AM_CONFIG_HEADER(config.h) 5 5 AM_PATH_CPPUNIT(1.9.6) 6 6 7 AC_CHECK_FUNCS(getline) 7 8 AC_PROG_CXX 8 9 AC_PROG_LIBTOOL 9 10 -
src/command_network.cc
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> … … 61 66 #include "control.h" 62 67 #include "command_helpers.h" 63 68 69 #include "utils/pattern.h" 70 #include "core/ip_filter.h" 71 72 64 73 torrent::Object 65 74 apply_throttle(const torrent::Object::list_type& args, bool up) { 66 75 torrent::Object::list_const_iterator argItr = args.begin(); … … 202 211 return torrent::Object(); 203 212 } 204 213 214 torrent::Object 215 apply_ip_filter(const torrent::Object::list_type& args) { 216 217 std::list<std::string> files; 218 219 for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) { 220 std::string file( itr->as_string() ); 221 utils::trim( file ); 222 if( access(file.c_str(),F_OK | R_OK) ) 223 throw torrent::input_error("IpFilter file '" + file + "' does not exist or not readable. Filter could not be loaded"); 224 files.push_back( file ); 225 } 226 227 std::stringstream logMsg; 228 if( files.empty() ) { 229 logMsg << "IpFilter is empty"; 230 control->core()->push_log( logMsg.str().c_str() ); 231 } 232 else { 233 core::IpFilter* f = new core::IpFilter(); 234 logMsg << "IpFilter is initialized with files: "; 235 int entries = 0; 236 clock_t time_start = clock(); 237 for( std::list<std::string>::iterator itr = files.begin(); itr != files.end(); itr++) { 238 std::cout << "Loading IP filters from '" << *itr << "'..."; 239 std::cout.flush(); 240 if( itr != files.begin() ) 241 logMsg << ", "; 242 logMsg << *itr; 243 int merges = f->add_from_file( *itr ); 244 if( merges < 0 ) { 245 std::cout << "error" << std::endl; 246 std::cout.flush(); 247 throw torrent::input_error("IpFilter could not load file '" + *itr + "'"); 248 } 249 std::cout << "done. Loaded " << (f->size()-entries) << " ranges. " << merges << " ranges were merged." << std::endl; 250 std::cout.flush(); 251 entries = f->size(); 252 } 253 control->core()->push_log( logMsg.str().c_str() ); 254 std::stringstream logMsg2("IpFilter loaded with "); 255 logMsg2 << f->size() << " ranges total. " << f->get_merges() << " ranges were merged."; 256 control->core()->push_log( logMsg2.str().c_str() ); 257 std::cout << logMsg2.str() << std::endl; 258 std::cout << "IP_Filters loaded in " << (double)(clock()-time_start)/CLOCKS_PER_SEC << " seconds" << std::endl; 259 std::cout.flush(); 260 control->core()->set_ip_filter( f ); 261 } 262 263 return torrent::Object(); 264 } 265 205 266 torrent::Object 206 267 apply_tos(const torrent::Object::string_type& arg) { 207 268 rpc::command_base::value_type value; … … 417 478 torrent::FileManager* fileManager = torrent::file_manager(); 418 479 core::CurlStack* httpStack = control->core()->http_stack(); 419 480 481 CMD2_ANY_V ("reload_ip_filter", std::tr1::bind(&core::Manager::reload_ip_filter, control->core())); 482 CMD2_ANY_LIST ("ip_filter", std::tr1::bind(&apply_ip_filter, std::tr1::placeholders::_2)); 483 484 420 485 CMD2_VAR_BOOL ("log.handshake", false); 421 486 CMD2_VAR_STRING ("log.tracker", ""); 422 487 -
src/core/getline.cc
a b 1 #include <string> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <limits.h> 7 #include <errno.h> 8 9 namespace core { 10 11 /* getline.c --- Implementation of replacement getline function. 12 Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005 Free 13 Software Foundation, Inc. 14 15 /* Ported from glibc by Simon Josefsson. */ 16 17 #ifndef SIZE_MAX 18 # define SIZE_MAX ((size_t) -1) 19 #endif 20 #ifndef SSIZE_MAX 21 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) 22 #endif 23 #if !HAVE_FLOCKFILE 24 # undef flockfile 25 # define flockfile(x) ((void) 0) 26 #endif 27 #if !HAVE_FUNLOCKFILE 28 # undef funlockfile 29 # define funlockfile(x) ((void) 0) 30 #endif 31 32 /* Read up to (and including) a DELIMITER from FP into *LINEPTR (and 33 NUL-terminate it). *LINEPTR is a pointer returned from malloc (or 34 NULL), pointing to *N characters of space. It is realloc'ed as 35 necessary. Returns the number of characters read (not including 36 the null terminator), or -1 on error or EOF. */ 37 38 ssize_t getline (char **lineptr, size_t *n, FILE *fp) 39 { 40 ssize_t result; 41 size_t cur_len = 0; 42 43 if (lineptr == NULL || n == NULL || fp == NULL) 44 { 45 errno = EINVAL; 46 return -1; 47 } 48 49 flockfile (fp); 50 51 if (*lineptr == NULL || *n == 0) 52 { 53 *n = 120; 54 *lineptr = (char *) malloc (*n); 55 if (*lineptr == NULL) 56 { 57 result = -1; 58 goto unlock_return; 59 } 60 } 61 62 for (;;) 63 { 64 int i; 65 66 i = getc (fp); 67 if (i == EOF) 68 { 69 result = -1; 70 break; 71 } 72 73 /* Make enough space for len+1 (for final NUL) bytes. */ 74 if (cur_len + 1 >= *n) 75 { 76 size_t needed_max = 77 SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; 78 size_t needed = 2 * *n + 1; /* Be generous. */ 79 char *new_lineptr; 80 81 if (needed_max < needed) 82 needed = needed_max; 83 if (cur_len + 1 >= needed) 84 { 85 result = -1; 86 goto unlock_return; 87 } 88 89 new_lineptr = (char *) realloc (*lineptr, needed); 90 if (new_lineptr == NULL) 91 { 92 result = -1; 93 94 95 96 goto unlock_return; 97 } 98 99 *lineptr = new_lineptr; 100 *n = needed; 101 } 102 103 (*lineptr)[cur_len] = i; 104 cur_len++; 105 106 if (i == '\n') 107 break; 108 } 109 (*lineptr)[cur_len] = '\0'; 110 result = cur_len ? cur_len : result; 111 112 unlock_return: 113 funlockfile (fp); 114 return result; 115 } 116 117 } -
src/core/getline.h
a b 1 #include <string> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <limits.h> 7 #include <errno.h> 8 9 namespace core { 10 11 /* getline.c --- Implementation of replacement getline function. 12 Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005 Free 13 Software Foundation, Inc. 14 15 /* Ported from glibc by Simon Josefsson. */ 16 17 /* Read up to (and including) a DELIMITER from FP into *LINEPTR (and 18 NUL-terminate it). *LINEPTR is a pointer returned from malloc (or 19 NULL), pointing to *N characters of space. It is realloc'ed as 20 necessary. Returns the number of characters read (not including 21 the null terminator), or -1 on error or EOF. */ 22 23 ssize_t getline (char **lineptr, size_t *n, FILE *fp); 24 25 } -
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 #ifdef HAVE_CONFIG_H 10 #include <config.h> 11 #endif 12 13 #ifndef __linux__ 14 #ifndef HAVE_GETLINE 15 #include "getline.h" 16 #endif 17 #endif 18 19 #include "ip_filter.h" 20 21 namespace core { 22 23 int IpFilter::merge_and_insert( range_map* rs, IpRange* r ) { 24 if( !r || !r->get_from() ) 25 return 0; 26 27 std::pair<const IpAddress,IpRange::ptr> p( *r->get_from(), IpRange::ptr(r) ); 28 std::pair<range_itr,bool> duo = rs->insert( p ); 29 30 range_itr idx = duo.first; 31 bool wasInserted = duo.second; 32 IpRange* curr = NULL; 33 int mergeCount = 0; 34 35 if( !wasInserted ) { // exactly the same start address already exists 36 curr = idx->second; 37 if( *curr->get_to() < *r->get_to() ) 38 curr->set_to( r->get_to() ); 39 delete r; 40 r = curr; 41 mergeCount++; 42 } 43 else { 44 if( idx != rs->begin() ) { 45 --idx; 46 curr = idx->second; // previous 47 if( *r->get_from() <= *curr->get_to() ) 48 r = curr; 49 else 50 ++idx; 51 } 52 } 53 54 if( idx != rs->end() ) 55 ++idx; 56 57 while( idx != rs->end() ) { 58 curr = idx->second; 59 if( *r->get_to() < *curr->get_from() ) 60 break; 61 62 std::string d = r->get_description(); 63 d += " / " + curr->get_description(); 64 r->set_description( d ); 65 if( *r->get_to() < *curr->get_to() ) 66 r->set_to( curr->get_to() ); 67 rs->erase( idx++ ); 68 delete curr; 69 mergeCount++; 70 } 71 return mergeCount; 72 } 73 74 int IpFilter::add_from_file( const std::string& fileName, range_map* rs, str_list* files ) { 75 FILE *f = fopen(fileName.c_str(),"r"); 76 int mergeCount = 0; 77 if (f==0) return -1; 78 char *line = (char *)malloc(64); 79 size_t sz=64; 80 int charsread = 0; 81 int linesread=0; 82 while( (charsread=getline(&line,&sz,f)) >=0 ) { 83 if( (line[0] == '#' ) || ( charsread <= 1 ) ) 84 continue; 85 86 IpRange* ir = IpRange::parse( line, charsread ); 87 if( !ir || !ir->get_from() || !ir->get_to() ) 88 continue; 89 90 mergeCount += merge_and_insert( rs, ir ); 91 } 92 free(line); 93 files->push_back( std::string(fileName) ); 94 fclose(f); 95 m_merges += mergeCount; 96 return mergeCount; 97 } 98 99 int IpFilter::add_from_file( const std::string& fileName ) { 100 if( !m_ranges ) 101 m_ranges = new range_map(); 102 if( !m_loadedFiles ) 103 m_loadedFiles = new std::list<std::string>(); 104 105 return add_from_file( fileName, m_ranges, m_loadedFiles ); 106 } 107 108 int IpFilter::reload() { 109 if( !m_loadedFiles || m_loadedFiles->empty() ) 110 return 0; 111 112 range_map* rs = new range_map(); 113 str_list* files = new str_list(); 114 int mergeCount = 0; 115 for( str_list::const_iterator it = m_loadedFiles->begin(), end = m_loadedFiles->end(); it != end; it++ ) 116 mergeCount += add_from_file( *it, rs, files ); 117 118 range_map* rsOld = m_ranges; 119 m_ranges = rs; 120 if( rsOld ) { 121 clear( rsOld ); 122 delete rsOld; 123 } 124 125 str_list* filesOld = m_loadedFiles; 126 m_loadedFiles = files; 127 if( filesOld ) { 128 clear( filesOld ); 129 delete filesOld; 130 } 131 132 m_merges = mergeCount; 133 return mergeCount; 134 } 135 136 IpRange* IpFilter::find_range( uint32_t ip ) const { 137 if( (ip >= 0) && m_ranges && !m_ranges->empty() ) { 138 range_itr idx = m_ranges->upper_bound( ip ); 139 if( idx != m_ranges->begin() ) 140 --idx; 141 IpRange* curr = idx->second; 142 if( curr->includes( ip ) ) 143 return curr; 144 } 145 return NULL; 146 } 147 148 std::string IpFilter::to_string() const { 149 std::stringstream result; 150 if( !m_ranges ) 151 result << "NULL" << std::endl; 152 else { 153 for( range_map::const_iterator it = m_ranges->begin() ; it != m_ranges->end(); it++ ) { 154 const IpAddress a = it->first; 155 IpRange* ir = it->second; 156 result << a << ": " << *ir << std::endl; 157 } 158 } 159 return result.str(); 160 } 161 162 void IpFilter::clear( range_map* map ) { 163 if( map ) { 164 for( range_itr i = map->begin(), j = map->end(); i != j; i++ ) 165 delete i->second; 166 map->clear(); 167 } 168 } 169 170 void IpFilter::clear( str_list* list ) { 171 if( list ) 172 list->clear(); 173 } 174 175 } -
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/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 \ 49 getline.h \ 50 getline.cc 40 51 41 52 INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) -
src/core/Makefile.in
a b 63 63 manager.$(OBJEXT) poll_manager.$(OBJEXT) \ 64 64 poll_manager_epoll.$(OBJEXT) poll_manager_kqueue.$(OBJEXT) \ 65 65 poll_manager_select.$(OBJEXT) view.$(OBJEXT) \ 66 view_manager.$(OBJEXT) 66 view_manager.$(OBJEXT) \ 67 ip_address.$(OBJEXT) \ 68 ip_filter.$(OBJEXT) \ 69 ip_range.$(OBJEXT) \ 70 ip_filter_statics.$(OBJEXT) \ 71 getline.$(OBJEXT) 67 72 libsub_core_a_OBJECTS = $(am_libsub_core_a_OBJECTS) 68 73 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) 69 74 depcomp = $(SHELL) $(top_srcdir)/depcomp … … 256 261 view.cc \ 257 262 view.h \ 258 263 view_manager.cc \ 259 view_manager.h 264 view_manager.h \ 265 ip_address.cc \ 266 ip_address.h \ 267 ip_filter.cc \ 268 ip_filter.h \ 269 ip_range.cc \ 270 ip_range.h \ 271 printable.h \ 272 regex_namespace.h \ 273 ip_filter_statics.cc \ 274 getline.cc \ 275 getline.h 260 276 261 277 INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) 262 278 all: all-am … … 324 340 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll_manager_select.Po@am__quote@ 325 341 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view.Po@am__quote@ 326 342 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view_manager.Po@am__quote@ 343 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_address.Po@am__quote@ 344 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_range.Po@am__quote@ 345 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_filter_statics.Po@am__quote@ 346 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getline.Po@am__quote@ 327 347 328 348 .cc.o: 329 349 @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -
src/core/manager.cc
a b 153 153 } 154 154 } 155 155 156 uint32_t 157 Manager::filter_ip(const sockaddr* sa) { 158 IpRange* r = NULL; 159 // if something's wrong with filter or address it's gonna be allowed 160 if( m_ipFilter && sa ) { 161 const rak::socket_address* socketAddress = rak::socket_address::cast_from(sa); 162 if( socketAddress->is_valid() && (socketAddress->family() == rak::socket_address::af_inet) ) 163 r = m_ipFilter->find_range( socketAddress->sa_inet()->address_h() ); 164 if( r ) 165 m_logComplete.push_front("Address '" + socketAddress->address_str() + "' is rejected by IP filter range '" + r->to_string()); 166 else 167 if( rpc::call_command_value("get_handshake_log") ) 168 m_logComplete.push_front("IP Filter allowed connection with '" + socketAddress->address_str() + "'"); 169 } 170 return (r==NULL); 171 } 172 173 156 174 void 157 175 Manager::push_log(const char* msg) { 158 176 m_logImportant.push_front(msg); … … 160 178 } 161 179 162 180 Manager::Manager() : 163 m_hashingView(NULL) 181 m_hashingView(NULL), 182 m_ipFilter(NULL) 164 183 // m_pollManager(NULL) { 165 184 { 166 185 m_downloadStore = new DownloadStore(); … … 181 200 delete m_downloadStore; 182 201 delete m_httpQueue; 183 202 delete m_fileStatusCache; 203 204 set_ip_filter( NULL ); 184 205 } 185 206 186 207 void … … 226 247 CurlStack::global_init(); 227 248 228 249 torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log)); 250 torrent::connection_manager()->set_filter(sigc::mem_fun(this, &Manager::filter_ip)); 229 251 } 230 252 231 253 void … … 585 607 } 586 608 } 587 609 610 void Manager::reload_ip_filter(void) { 611 if( m_ipFilter ) { 612 push_log("Reloading IP filter"); 613 m_ipFilter->reload(); 614 std::stringstream logMsg("IpFilter reloaded with "); 615 logMsg << m_ipFilter->size() << " ranges total. " << m_ipFilter->get_merges() << " ranges were merged."; 616 push_log( logMsg.str().c_str() ); 617 } 618 } 619 588 620 } -
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 } … … 118 120 119 121 void handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash); 120 122 123 uint32_t filter_ip(const sockaddr* sa); 124 125 void set_ip_filter( IpFilter* ipFilter ) { 126 IpFilter* old = m_ipFilter; 127 m_ipFilter = ipFilter; 128 if( old ) delete old; 129 } 130 void reload_ip_filter(void); 131 121 132 static const int create_start = 0x1; 122 133 static const int create_tied = 0x2; 123 134 static const int create_quiet = 0x4; … … 154 165 155 166 Log m_logImportant; 156 167 Log m_logComplete; 168 169 IpFilter* m_ipFilter; 157 170 }; 158 171 159 172 // 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 58 58 libsub_utils_a_LIBADD = 59 59 am_libsub_utils_a_OBJECTS = directory.$(OBJEXT) \ 60 60 file_status_cache.$(OBJEXT) lockfile.$(OBJEXT) \ 61 socket_fd.$(OBJEXT) 61 socket_fd.$(OBJEXT) pattern.$(OBJEXT) 62 62 libsub_utils_a_OBJECTS = $(am_libsub_utils_a_OBJECTS) 63 63 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) 64 64 depcomp = $(SHELL) $(top_srcdir)/depcomp … … 224 224 lockfile.cc \ 225 225 lockfile.h \ 226 226 socket_fd.cc \ 227 socket_fd.h 227 socket_fd.h \ 228 pattern.cc \ 229 pattern.h 228 230 229 231 INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) 230 232 all: all-am … … 279 281 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_status_cache.Po@am__quote@ 280 282 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockfile.Po@am__quote@ 281 283 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_fd.Po@am__quote@ 284 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pattern.Po@am__quote@ 282 285 283 286 .cc.o: 284 287 @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
