root/trunk/whisperlib/net/util/ipclassifier.h

Revision 7, 7.4 kB (checked in by whispercastorg, 2 years ago)

version 0.2.0

Line 
1 // Copyright (c) 2009, Whispersoft s.r.l.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Whispersoft s.r.l. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Catalin Popescu
31 //
32 // This defines a way to classify an IP address (a more intricated way
33 // of ip filtering). You normally specify a classifier in a string:
34 //
35 // <classifier spec> := <classifier name>"("<argument>")"
36 //
37 // Where name:
38 //  "AND" -> IpAndClassifier - makes an AND on the classifiers found in argument
39 //       <argument> := <classifier spec>[","<classifier spec>]*
40 //
41 //  "OR" -> IpOrlassifier - makes an OR on the classifiers found in argument
42 //       <argument> := <classifier spec>[","<classifier spec>]*
43 //
44 //  "NOT" -> IpNotClassifier - return the NOT  on the classifier in argument
45 //       <argument> := <classifier spec>
46 //
47 //  "IPLOC" -> IpLocationClassifier - is in the class if we are in the location
48 //       specified in argument
49 //      <argument> := <location spec>[","<location spec>]*
50 //      <location spec> := "C:"<country> |
51 //                         "CS:"<country short> |
52 //                         "REG:"<region> |
53 //                         "CITY:"<city> |
54 //                         "ISP:"<isp>
55 //
56 //  "IPFILTER" -> IpFilterStringClassifier - filters an IP that matches a
57 //      ip filter specification:
58 //     <argument> := <filter spec>[","<filter spec>]*
59 //     <filter spec> := <ip spec> | <ip range spec>
60 //     <ip spec> := <uint8>"."<uint8>"."<uint8>"."<uint8>
61 //     <ip range spec> := <uint8>"."<uint8>"."<uint8>"."<uint8>"/"<uint8>
62 //
63 //  "IPFILTERFILE" -> IpFilterFileClassifier - same as IpFilterStringClassifier,
64 //     but the filter specifications are given in a file (one per line).
65 //     <argument> := <filename>
66 //     content of <filename> := <filter spec>["\n"<filter spec>]*
67 //
68 // A specification like:
69 //
70 //  OR(IPLOC(CITY:BUCHAREST,CITY:PLOIESTI,ISP:EVOLVA),IPFILTER(171.1.2.0/24),
71 //     AND(IPFILTER(201.1.2.240/26), NOT(IPLOC(CITY:PITESTI))))
72 //
73 // will make a class that has ips in:
74 //   - city of BUCHAREST or PLOIEST and isp w/ Evolva
75 //  OR
76 //   - under ip mask 171.1.2.0/24
77 //  OR
78 //   - under ip mask 201.1.2.240/26
79 //     AND not in PITESTI
80 //
81 #ifndef __NET_UTIL_IPCLASSIFIER_H__
82 #define __NET_UTIL_IPCLASSIFIER_H__
83
84 #include <vector>
85 #include <set>
86 #include <whisperlib/common/base/types.h>
87 #include <whisperlib/net/util/ip2location.h>
88 #include <whisperlib/net/base/address.h>
89
90 namespace net {
91
92 class IpClassifier {
93  public:
94   IpClassifier() {}
95   virtual ~IpClassifier() {}
96   virtual bool IsInClass(const IpAddress& ip) const = 0;
97
98   // Factory method:
99   static IpClassifier* CreateClassifier(const string& spec);
100  private:
101   DISALLOW_EVIL_CONSTRUCTORS(IpClassifier);
102 };
103
104 //////////////////////////////////////////////////////////////////////
105
106 class IpNoneClassifier : public IpClassifier {
107  public:
108   IpNoneClassifier() : IpClassifier() {}
109   virtual ~IpNoneClassifier() {}
110   virtual bool IsInClass(const IpAddress& ip) const {
111     return false;
112   }
113  private:
114   DISALLOW_EVIL_CONSTRUCTORS(IpNoneClassifier);
115 };
116
117
118 class IpOrClassifier : public IpClassifier {
119  public:
120   IpOrClassifier() : IpClassifier() {}
121   IpOrClassifier(const string& members);
122   virtual ~IpOrClassifier() {
123     for ( int i = 0; i < members_.size(); ++i ) {
124       delete members_[i];
125     }
126   }
127   virtual bool IsInClass(const IpAddress& ip) const {
128     for ( int i = 0; i < members_.size(); ++i ) {
129       if ( members_[i]->IsInClass(ip) )
130         return true;
131     }
132     return false;
133   }
134   void Add(IpClassifier* member) {
135     members_.push_back(member);
136   }
137  private:
138   vector<IpClassifier*> members_;
139   DISALLOW_EVIL_CONSTRUCTORS(IpOrClassifier);
140 };
141
142 class IpAndClassifier : public IpClassifier  {
143  public:
144   IpAndClassifier() : IpClassifier() {}
145   IpAndClassifier(const string& members);
146   virtual ~IpAndClassifier() {
147     for ( int i = 0; i < members_.size(); ++i ) {
148       delete members_[i];
149     }
150   }
151   virtual bool IsInClass(const IpAddress& ip) const {
152     for ( int i = 0; i < members_.size(); ++i ) {
153       if ( !members_[i]->IsInClass(ip) )
154         return false;
155     }
156     return true;
157   }
158   void Add(IpClassifier* member) {
159     members_.push_back(member);
160   }
161  private:
162   vector<IpClassifier*> members_;
163   DISALLOW_EVIL_CONSTRUCTORS(IpAndClassifier);
164 };
165
166 class IpNotClassifier : public IpClassifier  {
167  public:
168   IpNotClassifier()
169       : IpClassifier(), member_(NULL) {}
170   IpNotClassifier(const string& member);
171   virtual ~IpNotClassifier() {
172     delete member_;
173   }
174   virtual bool IsInClass(const IpAddress& ip) const {
175     CHECK(member_);
176     return !member_->IsInClass(ip);
177   }
178  private:
179   IpClassifier* member_;
180   DISALLOW_EVIL_CONSTRUCTORS(IpNotClassifier);
181 };
182
183 //////////////////////////////////////////////////////////////////////
184
185 class IpLocationClassifier : public IpClassifier  {
186  public:
187   IpLocationClassifier() : IpClassifier() {}
188   IpLocationClassifier(const string& spec);
189
190   virtual bool IsInClass(const IpAddress& ip) const;
191
192  private:
193   static void InitResolver();
194   // we do an AND on all features
195   set<string> countries_short_;  // and OR inside each field
196   set<string> countries_;
197   set<string> regions_;
198   set<string> cities_;
199   set<string> isps_;
200
201   static net::Ip2Location* resolver_;
202   DISALLOW_EVIL_CONSTRUCTORS(IpLocationClassifier);
203 };
204
205 //////////////////////////////////////////////////////////////////////
206
207 class IpFilterStringClassifier : public IpClassifier  {
208  public:
209   IpFilterStringClassifier() : IpClassifier() {}
210   IpFilterStringClassifier(const string& spec);
211
212   virtual bool IsInClass(const IpAddress& ip) const {
213     return filter_.Matches(ip);
214   }
215
216  private:
217   IpV4Filter filter_;
218   DISALLOW_EVIL_CONSTRUCTORS(IpFilterStringClassifier);
219 };
220
221 class IpFilterFileClassifier : public IpClassifier  {
222  public:
223   IpFilterFileClassifier() : IpClassifier() {}
224   IpFilterFileClassifier(const string& spec);
225
226   virtual bool IsInClass(const IpAddress& ip) const {
227     return filter_.Matches(ip);
228   }
229
230  private:
231   IpV4Filter filter_;
232   DISALLOW_EVIL_CONSTRUCTORS(IpFilterFileClassifier);
233 };
234
235 //////////////////////////////////////////////////////////////////////
236 }
237
238 #endif  //  __NET_UTIL_IPCLASSIFIER_H__
Note: See TracBrowser for help on using the browser.