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

(-)a/configure.ac (+1 lines)
Lines 4-9 Link Here
4
AM_CONFIG_HEADER(config.h)
4
AM_CONFIG_HEADER(config.h)
5
AM_PATH_CPPUNIT(1.9.6)
5
AM_PATH_CPPUNIT(1.9.6)
6
6
7
AC_CHECK_FUNCS(getline)
7
AC_PROG_CXX
8
AC_PROG_CXX
8
AC_PROG_LIBTOOL
9
AC_PROG_LIBTOOL
9
10
(-)a/src/command_network.cc (+65 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 <fstream>
45
#include <fstream>
41
#include <cstdio>
46
#include <cstdio>
Lines 65-70 Link Here
65
#include "control.h"
70
#include "control.h"
66
#include "command_helpers.h"
71
#include "command_helpers.h"
67
72
73
#include "utils/pattern.h" 
74
#include "core/ip_filter.h"
75
76
68
torrent::Object
77
torrent::Object
69
apply_throttle(const torrent::Object::list_type& args, bool up) {
78
apply_throttle(const torrent::Object::list_type& args, bool up) {
70
  torrent::Object::list_const_iterator argItr = args.begin();
79
  torrent::Object::list_const_iterator argItr = args.begin();
Lines 206-211 Link Here
206
  return torrent::Object();
215
  return torrent::Object();
207
}
216
}
208
217
218
 torrent::Object
219
apply_ip_filter(const torrent::Object::list_type& args) {
220
221
  std::list<std::string> files;
222
223
  for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) {
224
    std::string file( itr->as_string() );
225
    utils::trim( file );
226
    if( access(file.c_str(),F_OK | R_OK) ) 
227
      throw torrent::input_error("IpFilter file '" + file + "' does not exist or not readable. Filter could not be loaded");
228
    files.push_back( file );
229
  }
230
231
  std::stringstream logMsg; 
232
  if( files.empty() ) {
233
    logMsg << "IpFilter is empty";
234
    control->core()->push_log( logMsg.str().c_str() );
235
  }
236
  else {
237
    core::IpFilter* f = new core::IpFilter();
238
    logMsg << "IpFilter is initialized with files: ";
239
    int entries = 0;
240
    clock_t time_start = clock();
241
    for( std::list<std::string>::iterator itr = files.begin(); itr != files.end(); itr++) {
242
      std::cout << "Loading IP filters from '" << *itr << "'...";
243
      std::cout.flush();
244
      if( itr != files.begin() )
245
        logMsg << ", ";
246
      logMsg << *itr;
247
      int merges = f->add_from_file( *itr );
248
      if( merges < 0 ) {
249
        std::cout << "error" << std::endl;
250
        std::cout.flush();
251
        throw torrent::input_error("IpFilter could not load file '" + *itr + "'");
252
      }
253
      std::cout << "done. Loaded " << (f->size()-entries) << " ranges. " << merges << " ranges were merged." << std::endl;
254
      std::cout.flush();
255
      entries = f->size();
256
    }
257
    control->core()->push_log( logMsg.str().c_str() );
258
    std::stringstream logMsg2("IpFilter loaded with "); 
259
    logMsg2 << f->size() << " ranges total. " << f->get_merges() << " ranges were merged.";
260
    control->core()->push_log( logMsg2.str().c_str() );
261
    std::cout << logMsg2.str() << std::endl;
262
    std::cout << "IP_Filters loaded in " << (double)(clock()-time_start)/CLOCKS_PER_SEC << " seconds" << std::endl;
263
    std::cout.flush();
264
    control->core()->set_ip_filter( f );
265
  }
266
267
  return torrent::Object();
268
}
269
209
torrent::Object
270
torrent::Object
210
apply_tos(const torrent::Object::string_type& arg) {
271
apply_tos(const torrent::Object::string_type& arg) {
211
  rpc::command_base::value_type value;
272
  rpc::command_base::value_type value;
Lines 615-620 Link Here
615
  torrent::FileManager* fileManager = torrent::file_manager();
676
  torrent::FileManager* fileManager = torrent::file_manager();
616
  core::CurlStack* httpStack = control->core()->http_stack();
677
  core::CurlStack* httpStack = control->core()->http_stack();
617
678
679
  CMD2_ANY_V       ("reload_ip_filter", std::tr1::bind(&core::Manager::reload_ip_filter, control->core()));
680
  CMD2_ANY_LIST    ("ip_filter",        std::tr1::bind(&apply_ip_filter, std::tr1::placeholders::_2));
681
682
  
618
  CMD2_VAR_BOOL    ("log.handshake", false);
683
  CMD2_VAR_BOOL    ("log.handshake", false);
619
  CMD2_VAR_STRING  ("log.tracker",   "");
684
  CMD2_VAR_STRING  ("log.tracker",   "");
(-)a/src/core/getline.cc (+117 lines)
Line 0 Link Here
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
}
(-)a/src/core/getline.h (+25 lines)
Line 0 Link Here
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
}
(-)a/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
}
(-)a/src/core/ip_address.h (+65 lines)
Line 0 Link Here
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
(-)a/src/core/ip_filter.cc (+175 lines)
Line 0 Link Here
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
}
(-)a/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
(-)a/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
}
(-)a/src/core/ip_range.cc (+112 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
//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
}
(-)a/src/core/ip_range.h (+67 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
		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
(-)a/src/core/Makefile.am (-1 / +12 lines)
Lines 36-41 Link Here
36
	view.cc \
36
	view.cc \
37
	view.h \
37
	view.h \
38
	view_manager.cc \
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
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
52
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
(-)a/src/core/Makefile.in (-2 / +22 lines)
Lines 63-69 Link Here
63
	manager.$(OBJEXT) poll_manager.$(OBJEXT) \
63
	manager.$(OBJEXT) poll_manager.$(OBJEXT) \
64
	poll_manager_epoll.$(OBJEXT) poll_manager_kqueue.$(OBJEXT) \
64
	poll_manager_epoll.$(OBJEXT) poll_manager_kqueue.$(OBJEXT) \
65
	poll_manager_select.$(OBJEXT) view.$(OBJEXT) \
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
libsub_core_a_OBJECTS = $(am_libsub_core_a_OBJECTS)
72
libsub_core_a_OBJECTS = $(am_libsub_core_a_OBJECTS)
68
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
73
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
69
depcomp = $(SHELL) $(top_srcdir)/depcomp
74
depcomp = $(SHELL) $(top_srcdir)/depcomp
Lines 259-265 Link Here
259
	view.cc \
264
	view.cc \
260
	view.h \
265
	view.h \
261
	view_manager.cc \
266
	view_manager.cc \
262
	view_manager.h
267
	view_manager.h \
268
	ip_address.cc \
269
	ip_address.h \
270
	ip_filter.cc \
271
	ip_filter.h \
272
	ip_range.cc \
273
	ip_range.h \
274
	printable.h \
275
	regex_namespace.h \
276
	ip_filter_statics.cc \
277
	getline.cc \
278
	getline.h
263
279
264
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
280
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
265
all: all-am
281
all: all-am
Lines 327-332 Link Here
327
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll_manager_select.Po@am__quote@
343
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll_manager_select.Po@am__quote@
328
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view.Po@am__quote@
344
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view.Po@am__quote@
329
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view_manager.Po@am__quote@
345
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view_manager.Po@am__quote@
346
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_address.Po@am__quote@
347
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_range.Po@am__quote@
348
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_filter_statics.Po@am__quote@  
349
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getline.Po@am__quote@
330
350
331
.cc.o:
351
.cc.o:
332
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
352
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
(-)a/src/core/manager.cc (-1 / +33 lines)
Lines 153-158 Link Here
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
void
174
void
157
Manager::push_log(const char* msg) {
175
Manager::push_log(const char* msg) {
158
  m_logImportant.push_front(msg);
176
  m_logImportant.push_front(msg);
Lines 160-166 Link Here
160
}
178
}
161
179
162
Manager::Manager() :
180
Manager::Manager() :
163
  m_hashingView(NULL)
181
  m_hashingView(NULL),
182
  m_ipFilter(NULL)
164
//   m_pollManager(NULL) {
183
//   m_pollManager(NULL) {
165
{
184
{
166
  m_downloadStore   = new DownloadStore();
185
  m_downloadStore   = new DownloadStore();
Lines 181-186 Link Here
181
  delete m_downloadStore;
200
  delete m_downloadStore;
182
  delete m_httpQueue;
201
  delete m_httpQueue;
183
  delete m_fileStatusCache;
202
  delete m_fileStatusCache;
203
204
  set_ip_filter( NULL );
184
}
205
}
185
206
186
void
207
void
Lines 226-231 Link Here
226
  CurlStack::global_init();
247
  CurlStack::global_init();
227
248
228
  torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log));
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
void
253
void
Lines 585-588 Link Here
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
}
(-)a/src/core/manager.h (+13 lines)
Lines 47-52 Link Here
47
#include "range_map.h"
47
#include "range_map.h"
48
#include "log.h"
48
#include "log.h"
49
49
50
#include "ip_filter.h"
51
50
namespace torrent {
52
namespace torrent {
51
  class Bencode;
53
  class Bencode;
52
}
54
}
Lines 118-123 Link Here
118
120
119
  void                handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash);
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
  static const int create_start    = 0x1;
132
  static const int create_start    = 0x1;
122
  static const int create_tied     = 0x2;
133
  static const int create_tied     = 0x2;
123
  static const int create_quiet    = 0x4;
134
  static const int create_quiet    = 0x4;
Lines 154-159 Link Here
154
165
155
  Log                 m_logImportant;
166
  Log                 m_logImportant;
156
  Log                 m_logComplete;
167
  Log                 m_logComplete;
168
169
  IpFilter*           m_ipFilter;
157
};
170
};
158
171
159
// Meh, cleanup.
172
// Meh, cleanup.
(-)a/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
(-)a/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
(-)a/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)
(-)a/src/utils/Makefile.in (-2 / +5 lines)
Lines 58-64 Link Here
58
libsub_utils_a_LIBADD =
58
libsub_utils_a_LIBADD =
59
am_libsub_utils_a_OBJECTS = directory.$(OBJEXT) \
59
am_libsub_utils_a_OBJECTS = directory.$(OBJEXT) \
60
	file_status_cache.$(OBJEXT) lockfile.$(OBJEXT) \
60
	file_status_cache.$(OBJEXT) lockfile.$(OBJEXT) \
61
	socket_fd.$(OBJEXT)
61
	socket_fd.$(OBJEXT) pattern.$(OBJEXT)
62
libsub_utils_a_OBJECTS = $(am_libsub_utils_a_OBJECTS)
62
libsub_utils_a_OBJECTS = $(am_libsub_utils_a_OBJECTS)
63
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
63
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
64
depcomp = $(SHELL) $(top_srcdir)/depcomp
64
depcomp = $(SHELL) $(top_srcdir)/depcomp
Lines 227-233 Link Here
227
	lockfile.cc \
227
	lockfile.cc \
228
	lockfile.h \
228
	lockfile.h \
229
	socket_fd.cc \
229
	socket_fd.cc \
230
	socket_fd.h
230
	socket_fd.h \
231
	pattern.cc \
232
	pattern.h
231
233
232
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
234
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
233
all: all-am
235
all: all-am
Lines 282-287 Link Here
282
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_status_cache.Po@am__quote@
284
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_status_cache.Po@am__quote@
283
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockfile.Po@am__quote@
285
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockfile.Po@am__quote@
284
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_fd.Po@am__quote@
286
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_fd.Po@am__quote@
287
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pattern.Po@am__quote@
285
288
286
.cc.o:
289
.cc.o:
287
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
290
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
(-)a/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
(-)a/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

Return to bug 265024