Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 265024 | Differences between
and this patch

Collapse All | Expand All

(-)rtorrent-0.8.4/src/core/ip_filter_statics.cc (+21 lines)
Line 0 Link Here
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
}
(-)rtorrent-0.8.4/src/core/manager.h (+13 lines)
Lines 44-49 Link Here
44
#include "poll_manager.h"
44
#include "poll_manager.h"
45
#include "log.h"
45
#include "log.h"
46
46
47
#include "ip_filter.h"
48
47
namespace torrent {
49
namespace torrent {
48
  class Bencode;
50
  class Bencode;
49
}
51
}
Lines 108-113 Link Here
108
110
109
  void                handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash);
111
  void                handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash);
110
112
113
  uint32_t            filter_ip(const sockaddr* sa);
114
115
  void                set_ip_filter( IpFilter* ipFilter ) {
116
                        IpFilter* old = m_ipFilter;
117
                        m_ipFilter = ipFilter;
118
                        if( old ) delete old;
119
                      }
120
  void                reload_ip_filter(void);
121
111
  static const int create_start    = 0x1;
122
  static const int create_start    = 0x1;
112
  static const int create_tied     = 0x2;
123
  static const int create_tied     = 0x2;
113
  static const int create_quiet    = 0x4;
124
  static const int create_quiet    = 0x4;
Lines 139-144 Link Here
139
  PollManager*        m_pollManager;
150
  PollManager*        m_pollManager;
140
  Log                 m_logImportant;
151
  Log                 m_logImportant;
141
  Log                 m_logComplete;
152
  Log                 m_logComplete;
153
154
  IpFilter*           m_ipFilter;
142
};
155
};
143
156
144
// Meh, cleanup.
157
// Meh, cleanup.
(-)rtorrent-0.8.4/src/core/ip_address.cc (+25 lines)
Line 0 Link Here
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
}
(-)rtorrent-0.8.4/src/core/ip_address.h (+64 lines)
Line 0 Link Here
1
#ifndef IPADDRESS_H
2
#define IPADDRESS_H
3
4
#include <string>
5
6
#include "printable.h"
7
#include "utils/pattern.h"
8
#include "regex_namespace.h"
9
10
namespace core {
11
12
class IpAddress : public Printable {
13
	friend class IpRange;
14
	
15
	private: // constants
16
		static const std::string	PATTERN_IP_EXPRESSION;
17
		static const std::string	PATTERN_IP_BYTES_EXPRESSION;
18
		static const regex::Pattern	PATTERN_IP_BYTES;
19
20
		static const int		GRP_IP_FIRST_BYTE;
21
		static const int		GRP_IP_BYTES_COUNT;
22
23
	private: // fields
24
		uint32_t			m_address;
25
	
26
	private: // static methods
27
	
28
	private: // dynamic methods
29
		IpAddress() : m_address(0) {}
30
	
31
		void copy( const IpAddress& addr ) { m_address = addr.m_address;}
32
	
33
	public: // static methods
34
		static std::pair<bool,uint32_t> to_int( const std::string& strAddress );
35
		static IpAddress* parse( const std::string& strAddress ) {
36
			std::pair<bool,uint32_t> result = to_int( strAddress );
37
			return ( !result.first ) ? NULL : new IpAddress( result.second );
38
		}
39
	
40
	public: // dynamic methods
41
		IpAddress( uint32_t address ) : m_address(address) {}
42
		IpAddress( const IpAddress& addr ) { copy( addr ); }
43
		IpAddress& operator= ( const IpAddress& addr ) { copy( addr ); return *this; } 
44
45
		operator uint32_t() const { return m_address; }
46
47
		bool operator>= ( const IpAddress& ip ) const { return (m_address >=    ip.m_address); }
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
54
		bool operator>= ( uint32_t ip ) const { return (m_address >= ip); }
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
61
		std::string to_string() const;
62
	};
63
}
64
#endif
(-)rtorrent-0.8.4/src/core/ip_range.h (+66 lines)
Line 0 Link Here
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
	
34
	public: // dynamic methods
35
		IpRange( IpRange& rng ) { copy(rng); }
36
		IpRange& operator= ( IpRange& rng ) { copy(rng); return *this; }
37
	
38
		void copy( IpRange& rng ) {
39
			m_description = rng.m_description;
40
			m_from = (!rng.m_from) ? NULL : new IpAddress( *rng.m_from );
41
			m_to = (!rng.m_to) ? NULL : new IpAddress( *rng.m_to );
42
		}
43
	
44
		const std::string&      get_description ( void ) const  { return m_description; }
45
		const IpAddress*        get_from        ( void ) const  { return m_from; }
46
		const IpAddress*        get_to          ( void ) const  { return m_to; }
47
		
48
		void    set_description ( const std::string&    description )   { m_description = description; }
49
		void    set_from        ( const IpAddress*      from )          { if( m_from ) delete m_from; m_from = new IpAddress( *from ); }
50
		void    set_to          ( const IpAddress*      to )            { if( m_to ) delete m_to; m_to = new IpAddress( *to ); }
51
		
52
		bool    includes( const IpAddress& ip ) const { return includes((uint32_t)ip); }
53
		bool    includes( uint32_t ip ) const { return (*m_from <= ip) && (*m_to >= ip); }
54
		
55
		~IpRange() {
56
			delete m_from;
57
			m_from = NULL;
58
			delete m_to;
59
			m_to = NULL;
60
		}
61
62
	std::string to_string() const;
63
};
64
65
}
66
#endif
(-)rtorrent-0.8.4/src/core/manager.cc (-1 / +32 lines)
Lines 39-44 Link Here
39
#include <cstdio>
39
#include <cstdio>
40
#include <cstring>
40
#include <cstring>
41
#include <fstream>
41
#include <fstream>
42
#include <sstream>
42
#include <unistd.h>
43
#include <unistd.h>
43
#include <sys/select.h>
44
#include <sys/select.h>
44
#include <rak/address_info.h>
45
#include <rak/address_info.h>
Lines 150-155 Link Here
150
  }
151
  }
151
}
152
}
152
153
154
uint32_t
155
Manager::filter_ip(const sockaddr* sa) {
156
  IpRange* r = NULL;
157
  // if something's wrong with filter or address it's gonna be allowed
158
  if( m_ipFilter && sa ) {
159
    const rak::socket_address* socketAddress = rak::socket_address::cast_from(sa);
160
    if( socketAddress->is_valid() && (socketAddress->family() == rak::socket_address::af_inet) )
161
      r = m_ipFilter->find_range( socketAddress->sa_inet()->address_h() );
162
    if( r )
163
      m_logComplete.push_front("Address '" + socketAddress->address_str() + "' is rejected by IP filter range '" + r->to_string());
164
    else
165
    if( rpc::call_command_value("get_handshake_log") )
166
      m_logComplete.push_front("IP Filter allowed connection with '" + socketAddress->address_str() + "'");
167
  }
168
  return (r==NULL);
169
}
170
171
153
void
172
void
154
Manager::push_log(const char* msg) {
173
Manager::push_log(const char* msg) {
155
  m_logImportant.push_front(msg);
174
  m_logImportant.push_front(msg);
Lines 158-164 Link Here
158
177
159
Manager::Manager() :
178
Manager::Manager() :
160
  m_hashingView(NULL),
179
  m_hashingView(NULL),
161
180
  m_ipFilter(NULL),
162
  m_pollManager(NULL) {
181
  m_pollManager(NULL) {
163
182
164
  m_downloadStore   = new DownloadStore();
183
  m_downloadStore   = new DownloadStore();
Lines 174-179 Link Here
174
  delete m_downloadStore;
193
  delete m_downloadStore;
175
  delete m_httpQueue;
194
  delete m_httpQueue;
176
  delete m_fileStatusCache;
195
  delete m_fileStatusCache;
196
197
  set_ip_filter( NULL );
177
}
198
}
178
199
179
void
200
void
Lines 212-217 Link Here
212
  CurlStack::global_init();
233
  CurlStack::global_init();
213
234
214
  torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log));
235
  torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log));
236
  torrent::connection_manager()->set_filter(sigc::mem_fun(this, &Manager::filter_ip));
215
}
237
}
216
238
217
void
239
void
Lines 546-549 Link Here
546
  }
568
  }
547
}
569
}
548
570
571
void Manager::reload_ip_filter(void) {
572
  if( m_ipFilter ) {
573
    push_log("Reloading IP filter");
574
    m_ipFilter->reload();
575
    std::stringstream logMsg("IpFilter reloaded with "); 
576
    logMsg << m_ipFilter->size() << " ranges total. " << m_ipFilter->get_merges() << " ranges were merged.";
577
    push_log( logMsg.str().c_str() );
549
}
578
}
579
}
580
}
(-)rtorrent-0.8.4/src/core/ip_filter.cc (+166 lines)
Line 0 Link Here
1
#include <sstream>
2
#include <string>
3
#include <map>
4
#include <list>
5
#include <fstream>
6
7
#include "ip_filter.h"
8
9
namespace core {
10
11
int IpFilter::merge_and_insert( range_map* rs, IpRange* r ) {
12
	if( !r || !r->get_from() )
13
		return 0;
14
15
	std::pair<const IpAddress,IpRange::ptr> p( *r->get_from(), IpRange::ptr(r) );
16
	std::pair<range_itr,bool> duo = rs->insert( p );
17
18
	range_itr idx = duo.first;
19
	bool wasInserted = duo.second;
20
	IpRange* curr = NULL;
21
	int mergeCount = 0;
22
23
	if( !wasInserted ) { // exactly the same start address already exists
24
		curr = idx->second;
25
		if( *curr->get_to() < *r->get_to() )
26
			curr->set_to( r->get_to() );
27
		delete r;
28
		r = curr;
29
		mergeCount++;
30
	}
31
	else {
32
		if( idx != rs->begin() ) {
33
			--idx;
34
		curr = idx->second; // previous
35
		if( *r->get_from() <= *curr->get_to() )
36
			r = curr;
37
		else
38
			++idx;
39
		}
40
	}
41
42
	if( idx != rs->end() )
43
		++idx;
44
45
	while( idx != rs->end() ) {
46
		curr = idx->second;
47
		if( *r->get_to() < *curr->get_from() )
48
			break;
49
50
		std::string d = r->get_description();
51
		d += " / " + curr->get_description();
52
		r->set_description( d );
53
		if( *r->get_to() < *curr->get_to() )
54
			r->set_to( curr->get_to() );
55
		rs->erase( idx++ );
56
		delete curr;
57
		mergeCount++;
58
	}
59
	return mergeCount;
60
}
61
62
int IpFilter::add_from_file( const std::string& fileName, range_map* rs, str_list* files ) {
63
	std::ifstream in( fileName.c_str() );
64
	std::string line;
65
	int mergeCount = 0;
66
67
	if( in.fail() || !in.is_open() )
68
		return -1;
69
70
	while( in.good() ) {
71
		std::getline( in, line );
72
		utils::trim( line );
73
74
		if( (line[0] == '#') || (line.length() == 0) || (line[0] == 0) )
75
			continue;
76
77
		IpRange* ir = IpRange::parse( line );
78
		if( !ir || !ir->get_from() || !ir->get_to() )
79
			continue;
80
81
		mergeCount += merge_and_insert( rs, ir );
82
	}
83
	files->push_back( std::string(fileName) );
84
	in.close();
85
86
	m_merges += mergeCount;
87
	return mergeCount;
88
}
89
90
int IpFilter::add_from_file( const std::string& fileName ) {
91
	if( !m_ranges )
92
		m_ranges = new range_map();
93
	if( !m_loadedFiles )
94
		m_loadedFiles = new std::list<std::string>();
95
96
	return add_from_file( fileName, m_ranges, m_loadedFiles );
97
}
98
99
int IpFilter::reload() {
100
	if( !m_loadedFiles || m_loadedFiles->empty() )
101
		return 0;
102
103
	range_map* rs = new range_map();
104
	str_list* files = new str_list();
105
	int mergeCount = 0;
106
	for( str_list::const_iterator it = m_loadedFiles->begin(), end = m_loadedFiles->end(); it != end; it++ )
107
		mergeCount += add_from_file( *it, rs, files );
108
109
	range_map* rsOld = m_ranges;
110
	m_ranges = rs;
111
	if( rsOld ) {
112
		clear( rsOld );
113
		delete rsOld;
114
	}
115
116
	str_list* filesOld = m_loadedFiles;
117
	m_loadedFiles = files;
118
	if( filesOld ) {
119
		clear( filesOld );
120
		delete filesOld;
121
	}
122
123
	m_merges = mergeCount;
124
	return mergeCount;
125
}
126
127
IpRange* IpFilter::find_range( uint32_t ip ) const {
128
	if( (ip >= 0) && m_ranges && !m_ranges->empty() ) {
129
		range_itr idx = m_ranges->upper_bound( ip );
130
		if( idx != m_ranges->begin() )
131
			--idx;
132
		IpRange* curr = idx->second;
133
		if( curr->includes( ip ) )
134
			return curr;
135
	}
136
	return NULL;
137
}
138
139
std::string IpFilter::to_string() const {
140
	std::stringstream result;
141
	if( !m_ranges )
142
		result << "NULL" << std::endl;
143
	else {
144
		for( range_map::const_iterator it = m_ranges->begin() ; it != m_ranges->end(); it++ ) {
145
			const IpAddress a = it->first;
146
			IpRange* ir = it->second;
147
			result << a << ": " << *ir << std::endl;
148
		}
149
	}
150
	return result.str();
151
}
152
153
void IpFilter::clear( range_map* map ) {
154
	if( map ) {
155
		for( range_itr i = map->begin(), j = map->end(); i != j; i++ )
156
			delete i->second;
157
		map->clear();
158
	}
159
}
160
161
void IpFilter::clear( str_list* list ) {
162
	if( list )
163
		list->clear();
164
}
165
166
}
(-)rtorrent-0.8.4/src/core/ip_filter.h (+85 lines)
Line 0 Link Here
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
(-)rtorrent-0.8.4/src/core/printable.h (+16 lines)
Line 0 Link Here
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
(-)rtorrent-0.8.4/src/core/ip_range.cc (+57 lines)
Line 0 Link Here
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
std::string IpRange::to_string() const {
52
	std::stringstream result;
53
	result << m_description << ": [" << m_from->to_string() << " - " << m_to->to_string() << ']';
54
	return result.str();
55
}
56
57
}
(-)rtorrent-0.8.4/src/core/Makefile.am (-1 / +10 lines)
Lines 35-40 Link Here
35
	view.cc \
35
	view.cc \
36
	view.h \
36
	view.h \
37
	view_manager.cc \
37
	view_manager.cc \
38
	view_manager.h
38
	view_manager.h \
39
	ip_address.cc \
40
	ip_address.h \
41
	ip_filter.cc \
42
	ip_filter.h \
43
	ip_range.cc \
44
	ip_range.h \
45
	printable.h \
46
	regex_namespace.h \
47
	ip_filter_statics.cc
39
48
40
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
49
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
(-)rtorrent-0.8.4/src/core/regex_namespace.h (+6 lines)
Line 0 Link Here
1
#ifndef REGEXNAMESPACE_H
2
#define REGEXNAMESPACE_H
3
4
namespace regex = utils;
5
6
#endif
(-)rtorrent-0.8.4/src/utils/pattern.cc (+79 lines)
Line 0 Link Here
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
(-)rtorrent-0.8.4/src/utils/pattern.h (+59 lines)
Line 0 Link Here
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
(-)rtorrent-0.8.4/src/utils/Makefile.am (-1 / +3 lines)
Lines 9-14 Link Here
9
	lockfile.cc \
9
	lockfile.cc \
10
	lockfile.h \
10
	lockfile.h \
11
	socket_fd.cc \
11
	socket_fd.cc \
12
	socket_fd.h
12
	socket_fd.h \
13
	pattern.cc \
14
	pattern.h
13
15
14
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
16
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
(-)rtorrent-0.8.4/src/command_network.cc (+63 lines)
Lines 36-41 Link Here
36
36
37
#include "config.h"
37
#include "config.h"
38
38
39
#include <string>
40
#include <sstream>
41
#include <list>
42
#include <unistd.h>
43
39
#include <functional>
44
#include <functional>
40
#include <rak/address_info.h>
45
#include <rak/address_info.h>
41
#include <rak/path.h>
46
#include <rak/path.h>
Lines 61-66 Link Here
61
#include "control.h"
66
#include "control.h"
62
#include "command_helpers.h"
67
#include "command_helpers.h"
63
68
69
#include "utils/pattern.h" 
70
#include "core/ip_filter.h"
71
72
64
torrent::Object
73
torrent::Object
65
apply_encryption(const torrent::Object& rawArgs) {
74
apply_encryption(const torrent::Object& rawArgs) {
66
  const torrent::Object::list_type& args = rawArgs.as_list();
75
  const torrent::Object::list_type& args = rawArgs.as_list();
Lines 94-99 Link Here
94
}
103
}
95
104
96
torrent::Object
105
torrent::Object
106
apply_ip_filter(const torrent::Object& rawArgs) {
107
  const torrent::Object::list_type& args = rawArgs.as_list();
108
109
  std::list<std::string> files;
110
111
  for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) {
112
    std::string file( itr->as_string() );
113
    utils::trim( file );
114
    if( access(file.c_str(),F_OK | R_OK) ) 
115
      throw torrent::input_error("IpFilter file '" + file + "' does not exist or not readable. Filter could not be loaded");
116
    files.push_back( file );
117
  }
118
119
  std::stringstream logMsg; 
120
  if( files.empty() ) {
121
    logMsg << "IpFilter is empty";
122
    control->core()->push_log( logMsg.str().c_str() );
123
  }
124
  else {
125
    core::IpFilter* f = new core::IpFilter();
126
    logMsg << "IpFilter is initialized with files: ";
127
    int entries = 0;
128
    for( std::list<std::string>::iterator itr = files.begin(); itr != files.end(); itr++) {
129
      std::cout << "Loading IP filters from '" << *itr << "'...";
130
      std::cout.flush();
131
      if( itr != files.begin() )
132
        logMsg << ", ";
133
      logMsg << *itr;
134
      int merges = f->add_from_file( *itr );
135
      if( merges < 0 ) {
136
        std::cout << "error" << std::endl;
137
        std::cout.flush();
138
        throw torrent::input_error("IpFilter could not load file '" + *itr + "'");
139
      }
140
      std::cout << "done. Loaded " << (f->size()-entries) << " ranges. " << merges << " ranges were merged." << std::endl;
141
      std::cout.flush();
142
      entries = f->size();
143
    }
144
    control->core()->push_log( logMsg.str().c_str() );
145
    std::stringstream logMsg2("IpFilter loaded with "); 
146
    logMsg2 << f->size() << " ranges total. " << f->get_merges() << " ranges were merged.";
147
    control->core()->push_log( logMsg2.str().c_str() );
148
    std::cout << logMsg2.str() << std::endl;
149
    std::cout.flush();
150
    control->core()->set_ip_filter( f );
151
  }
152
153
  return torrent::Object();
154
}
155
156
torrent::Object
97
apply_tos(const torrent::Object& rawArg) {
157
apply_tos(const torrent::Object& rawArg) {
98
  rpc::Command::value_type value;
158
  rpc::Command::value_type value;
99
  torrent::ConnectionManager* cm = torrent::connection_manager();
159
  torrent::ConnectionManager* cm = torrent::connection_manager();
Lines 366-371 Link Here
366
426
367
  ADD_VARIABLE_BOOL("peer_exchange", true);
427
  ADD_VARIABLE_BOOL("peer_exchange", true);
368
428
429
  ADD_COMMAND_VOID("reload_ip_filter",          rak::make_mem_fun(control->core(), &core::Manager::reload_ip_filter));
430
  ADD_COMMAND_LIST("ip_filter",          	rak::ptr_fn(&apply_ip_filter));
431
369
  // Not really network stuff:
432
  // Not really network stuff:
370
  ADD_VARIABLE_BOOL("handshake_log", false);
433
  ADD_VARIABLE_BOOL("handshake_log", false);
371
  ADD_VARIABLE_STRING("tracker_dump", "");
434
  ADD_VARIABLE_STRING("tracker_dump", "");

Return to bug 265024