root/trunk/whisperlib/net/base/address.h

Revision 7, 7.0 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: Cosmin Tudorache & Catalin Popescu
31 //
32 #ifndef __NET_BASE_ADDRESS_H__
33 #define __NET_BASE_ADDRESS_H__
34
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <arpa/inet.h>
38 #include <netinet/in.h>
39 #include <string>
40 #include <map>
41 #include <whisperlib/common/base/types.h>
42 #include <whisperlib/common/base/log.h>
43
44 struct in_addr;
45
46 namespace net {
47
48 class IpAddress {
49  public:
50   static const int32 kInvalidIpV4 = 0;
51   static const uint8 kInvalidIpV6[16];
52
53   IpAddress()
54       : is_ipv4_(true) {
55     memset(&addr_, 0, sizeof(&addr_));
56   }
57   //  ip: 4 bytes containing the IP address
58   //      (host byte order: b1.b2.b3.b4 <==> 0xb1b2b3b4)
59   explicit IpAddress(int32 ip)
60       : is_ipv4_(true) {
61     addr_.ipv4_ = ip;
62   }
63   // parsing constructor
64   explicit IpAddress(const char* addr) {
65     bool error = false;
66     if ( strchr(addr, ':') ) {
67       is_ipv4_ = false;
68       //NOTE: inet_pton delivers address in network byte order
69       error = inet_pton(AF_INET6, addr, addr_.ipv6_) <= 0;
70       // we keep addr_.ipv6_ in network byte order
71     } else {
72       is_ipv4_ = true;
73       //NOTE: inet_pton delivers address in network byte order
74       error = inet_pton(AF_INET, addr, &addr_.ipv4_) <= 0;
75       // we keep addr_.ipv4_ in host byte order
76       addr_.ipv4_ = ntohl(addr_.ipv4_);
77       }
78     if ( error ) {
79       memset(&addr_, 0, sizeof(&addr_));
80     }
81   }
82   IpAddress& operator=(const IpAddress& addr) {
83     is_ipv4_ = addr.is_ipv4_;
84     memcpy(&addr_, &addr.addr_, sizeof(addr_));
85     return *this;
86   }
87   IpAddress& operator=(int32 ip) {
88     is_ipv4_ = true;
89     addr_.ipv4_ = ip;
90     return *this;
91   }
92
93   bool IsInvalid() const {
94     if ( is_ipv4_ )
95       return addr_.ipv4_ == kInvalidIpV4;
96     else
97       return (0 == memcmp(addr_.ipv6_, kInvalidIpV6, sizeof(addr_.ipv6_)));
98   }
99   bool is_ipv4() const {
100     return is_ipv4_;
101   }
102   int32 ipv4() const {
103     CHECK(is_ipv4_);
104     return addr_.ipv4_;
105   }
106   void set_ipv4(int32 ip) {
107     is_ipv4_ = true;
108     addr_.ipv4_ = ip;
109   }
110   void set_ipv6(const uint8* ip) {
111     is_ipv4_ = false;
112     memcpy(addr_.ipv6_, ip, 16);
113   }
114
115   // returns the ip address in structure..
116   void Addr(sockaddr_storage* addr) const;
117
118
119   // Generates a text representation of the ip (ex. "10.205.9.85") in
120   // the given "buf". If the buf is too small, it will contain a truncated
121   // string.
122   const char* ToString(char* buf, size_t buf_len) const;
123
124   // Same as above, but returns a string;
125   string ToString() const;
126
127  private:
128   bool is_ipv4_;
129   union {
130     int32 ipv4_;         // "b1.b2.b3.b4" <==> 0xb1b2b3b4 . host byte order
131     uint8 ipv6_[16];     // {b1,b2,b3,..,b16} . network byte order
132   } addr_;
133 };
134
135
136 class HostPort {
137  public:
138   static const uint16 kInvalidPort = 0;
139   HostPort()
140       : ip_(), port_(kInvalidPort) {
141   }
142   HostPort(int32 ip, uint16 port)
143       : ip_(ip), port_(port) {
144   }
145   // Parsing constructor
146   // @example: "10.205.9.85:2345" -> set IP=10.205.9.85 & PORT=2345
147   // @example: "10.205.9.85" -> set only IP=10.205.9.85 & PORT=0
148   explicit HostPort(const char* addr) {
149     Parse(addr, this);
150   }
151   // Parsing constructor (just for the ip)
152   HostPort(const IpAddress& addr, uint16 port)
153       : ip_(addr), port_(port) {
154   }
155   // Parsing constructor (just for the ip)
156   HostPort(const char* addr, uint16 port)
157       : ip_(addr), port_(port) {
158   }
159   // From net order of addr converts to machine order in HostPort
160   explicit HostPort(const struct sockaddr_storage* addr);
161
162   HostPort& operator=(const HostPort& hp) {
163     ip_ = hp.ip_;
164     port_ = hp.port_;
165     return *this;
166   }
167
168   // Accesors / settors
169   const IpAddress& ip_object() const { return ip_; }
170   IpAddress* mutable_ip_object() { return &ip_; }
171
172   // int32 ip() const { return ip_.ip(); }
173   void set_ipv4(int32 ip) { ip_ = ip; }
174
175   void set_ip(const IpAddress& ip) { ip_ = ip; }
176
177   uint16 port() const { return port_; }
178   void set_port(uint16 port) { port_ = port; }
179
180   bool IsInvalid() const {
181     return ip_.IsInvalid() || (port_ == kInvalidPort);
182   }
183
184   // Parses host and port into provided hp structure
185   // @example: "10.205.9.85:2345" -> set IP=10.205.9.85 & PORT=2345
186   // @example: "10.205.9.85" -> set only IP=10.205.9.85 & PORT remains unchanged
187   static void Parse(const char* addr, HostPort* hp);
188
189   // Returns  ip address in network byte order
190   void Addr(sockaddr_storage* addr) const {ip_.Addr(addr); }
191   void SockAddr(struct sockaddr_storage* addr) const;
192
193   // Generates a text representation of the ip (ex. "10.205.9.85")
194   // in the given "buffer". If buffer is too smal, it truncates the
195   // answer
196   const char* ToString(char* buffer, size_t len) const;
197
198   // Same as above, but generates a string
199   string ToString() const;
200
201  private:
202   IpAddress ip_;
203   uint16 port_;
204 };
205
206 inline ostream& operator<<(ostream& os, const IpAddress& ip) {
207   return os << ip.ToString();
208 }
209 inline ostream& operator<<(ostream& os, const HostPort& hp) {
210   return os << hp.ip_object() << ":" << hp.port();
211 }
212
213 // This is a filter of addresses. Add ip strings like "12.23.4.2" or
214 // range specification "192.168.2.23/24" or IPV4Address -es, then
215 // check with a test IP if it matches.
216 class IpV4Filter {
217  public:
218   IpV4Filter() {
219   }
220   ~IpV4Filter() {
221   }
222
223   // Adds an ip or a range to the filter. Returns true on OK
224   bool Add(const char* p);
225   bool Add(const IpAddress& ip, int32 bits = 32);
226
227   // Matching function - returns true if it matches
228   bool Matches(const IpAddress& ip) const;
229
230  private:
231   enum ElemType {
232     MARK_BEGIN = 1,
233     MARK_END = 2,
234     MARK_BOTH = 3,
235   };
236   typedef map<uint32, int32> FilterMap;
237   FilterMap filter_;
238 };
239 }
240
241 #endif  // __NET_BASE_ADDRESS_H__
Note: See TracBrowser for help on using the browser.