00001 # if ! defined(TS_IP_MAP_HEADER) 00002 # define TS_IP_MAP_HEADER 00003 00004 # include "ink_platform.h" 00005 # include "ink_defs.h" 00006 # include <ts/ink_inet.h> 00007 # include <ts/IntrusiveDList.h> 00008 # include <ts/ink_assert.h> 00009 00010 /** @file 00011 00012 Map of IP addresses to client data. 00013 00014 @section license License 00015 00016 Licensed to the Apache Software Foundation (ASF) under one 00017 or more contributor license agreements. See the NOTICE file 00018 distributed with this work for additional information 00019 regarding copyright ownership. The ASF licenses this file 00020 to you under the Apache License, Version 2.0 (the 00021 "License"); you may not use this file except in compliance 00022 with the License. You may obtain a copy of the License at 00023 00024 http://www.apache.org/licenses/LICENSE-2.0 00025 00026 Unless required by applicable law or agreed to in writing, software 00027 distributed under the License is distributed on an "AS IS" BASIS, 00028 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00029 See the License for the specific language governing permissions and 00030 limitations under the License. 00031 */ 00032 00033 namespace ts { namespace detail { 00034 00035 /** Interval class. 00036 This holds an interval based on a metric @a T along with 00037 client data. 00038 */ 00039 template < 00040 typename T, ///< Metric for span. 00041 typename A = T const& ///< Argument type. 00042 > struct Interval { 00043 typedef T Metric; ///< Metric (storage) type. 00044 typedef A ArgType; ///< Type used to pass instances of @c Metric. 00045 00046 Interval() {} ///< Default constructor. 00047 /// Construct with values. 00048 Interval( 00049 ArgType min, ///< Minimum value in span. 00050 ArgType max ///< Maximum value in span. 00051 ) : _min(min), _max(max) {} 00052 Metric _min; ///< Minimum value in span. 00053 Metric _max; ///< Maximum value in span. 00054 }; 00055 00056 class Ip4Map; // Forward declare. 00057 class Ip6Map; // Forward declare. 00058 00059 /** A node in a red/black tree. 00060 00061 This class provides only the basic tree operations. The client 00062 must provide the search and decision logic. This enables this 00063 class to be a base class for templated nodes with much less code 00064 duplication. 00065 */ 00066 struct RBNode { 00067 typedef RBNode self; ///< self reference type 00068 00069 /// Node colors 00070 typedef enum { RED, BLACK } Color; 00071 00072 /// Directional constants 00073 typedef enum { NONE, LEFT, RIGHT } Direction; 00074 00075 /// Get a child by direction. 00076 /// @return The child in the direction @a d if it exists, 00077 /// @c NULL if not. 00078 self* getChild( 00079 Direction d //!< The direction of the desired child 00080 ) const; 00081 00082 /** Determine which child a node is 00083 @return @c LEFT if @a n is the left child, 00084 @c RIGHT if @a n is the right child, 00085 @c NONE if @a n is not a child 00086 */ 00087 Direction getChildDirection( 00088 self* const& n //!< The presumed child node 00089 ) const { 00090 return (n == _left) ? LEFT : (n == _right) ? RIGHT : NONE; 00091 } 00092 00093 /** Get the parent node. 00094 @return A Node* to the parent node or a @c nil Node* if no parent. 00095 */ 00096 self* getParent() const { return const_cast<self*>(_parent); } 00097 00098 /// @return The color of the node. 00099 Color getColor() const { return _color; } 00100 00101 /** Reverse a direction 00102 @return @c LEFT if @a d is @c RIGHT, @c RIGHT if @a d is @c LEFT, 00103 @c NONE otherwise. 00104 */ 00105 Direction flip(Direction d) { 00106 return LEFT == d ? RIGHT : RIGHT == d ? LEFT : NONE; 00107 } 00108 00109 /** Perform internal validation checks. 00110 @return 0 on failure, black height of the tree on success. 00111 */ 00112 int validate(); 00113 00114 /// Default constructor. 00115 RBNode() 00116 : _color(RED) 00117 , _parent(0) 00118 , _left(0) 00119 , _right(0) 00120 , _next(0) 00121 , _prev(0) { 00122 } 00123 00124 /// Destructor (force virtual). 00125 virtual ~RBNode() { } 00126 00127 /** Rotate the subtree rooted at this node. 00128 The node is rotated in to the position of one of its children. 00129 Which child is determined by the direction parameter @a d. The 00130 child in the other direction becomes the new root of the subtree. 00131 00132 If the parent pointer is set, then the child pointer of the original 00133 parent is updated so that the tree is left in a consistent state. 00134 00135 @note If there is no child in the other direction, the rotation 00136 fails and the original node is returned. It is @b not required 00137 that a child exist in the direction specified by @a d. 00138 00139 @return The new root node for the subtree. 00140 */ 00141 self* rotate( 00142 Direction d //!< The direction to rotate 00143 ); 00144 00145 /** Set the child node in direction @a d to @a n. 00146 The @a d child is set to the node @a n. The pointers in this 00147 node and @a n are set correctly. This can only be called if 00148 there is no child node already present. 00149 00150 @return @a n. 00151 */ 00152 self* setChild( 00153 self* n, //!< The node to set as the child 00154 Direction d //!< The direction of the child 00155 ); 00156 00157 /** Remove this node from the tree. 00158 The tree is rebalanced after removal. 00159 @return The new root node. 00160 */ 00161 self* remove(); 00162 00163 void clearChild(Direction dir) { 00164 if (LEFT == dir) _left = 0; 00165 else if (RIGHT == dir) _right = 0; 00166 } 00167 00168 /** @name Subclass hook methods */ 00169 //@{ 00170 /** Structural change notification. 00171 This method is called if the structure of the subtree rooted at 00172 this node was changed. 00173 00174 This is intended a hook. The base method is empty so that subclasses 00175 are not required to override. 00176 */ 00177 virtual void structureFixup() {} 00178 00179 /** Called from @c validate to perform any additional validation checks. 00180 Clients should chain this if they wish to perform additional checks. 00181 @return @c true if the validation is successful, @c false otherwise. 00182 @note The base method simply returns @c true. 00183 */ 00184 virtual bool structureValidate() { return true; } 00185 //@} 00186 00187 /** Replace this node with another node. 00188 This is presumed to be non-order modifying so the next reference 00189 is @b not updated. 00190 */ 00191 void replaceWith( 00192 self* n //!< Node to put in place of this node. 00193 ); 00194 00195 //! Rebalance the tree starting at this node 00196 /** The tree is rebalanced so that all of the invariants are 00197 true. The (potentially new) root of the tree is returned. 00198 00199 @return The root node of the tree after the rebalance. 00200 */ 00201 self* rebalanceAfterInsert(); 00202 00203 /** Rebalance the tree after a deletion. 00204 Called on the lowest modified node. 00205 @return The new root of the tree. 00206 */ 00207 self* rebalanceAfterRemove( 00208 Color c, //!< The color of the removed node. 00209 Direction d //!< Direction of removed node from parent 00210 ); 00211 00212 //! Invoke @c structure_fixup() on this node and all of its ancestors. 00213 self* rippleStructureFixup(); 00214 00215 Color _color; ///< node color 00216 self* _parent; ///< parent node (needed for rotations) 00217 self* _left; ///< left child 00218 self* _right; ///< right child 00219 self* _next; ///< Next node. 00220 self* _prev; ///< Previous node. 00221 }; 00222 00223 }} // namespace ts::detail 00224 00225 /** Map from IP addresses to client data. 00226 00227 Conceptually this class maps the entire space of IP addresses to 00228 client data. Client data is stored as a @c (void*). Memory 00229 management of the data is left to the client. The interface 00230 supports marking ranges of addresses with a specific client 00231 data. Marking takes a painter's algorithm approach -- any marking 00232 overwrites any previous marking on an address. Details of marking 00233 calls are discarded and only the final results are kept. That is, 00234 a client cannot unmark expliticly any previous marking. Only a 00235 specific range of addresses can be unmarked. 00236 00237 Both IPv4 and IPv6 are supported in the same map. Mixed ranges are 00238 not supported (any particular range of addresses must be a single 00239 protocol but ranges of both types can be in the map). 00240 00241 Use @c mark to mark / set / add addresses to the map. 00242 Use @c unmark to unset addresses (setting the client data to 0 does 00243 @b not remove the address -- this is for the convenience of clients 00244 that do not need data, only membership). @c contains tests for 00245 membership and retrieves the client data. 00246 00247 Ranges can be marked and unmarked arbitrarily. The internal 00248 representation keeps a minimal set of ranges to describe the 00249 current addresses. Search time is O(log n) where n is the number 00250 of disjoint ranges. Marking and unmarking can take O(log n) and 00251 may require memory allocation / deallocation although this is 00252 minimized. 00253 */ 00254 00255 class IpMap { 00256 public: 00257 typedef IpMap self; ///< Self reference type. 00258 00259 class iterator; // forward declare. 00260 00261 /** Public API for intervals in the map. 00262 */ 00263 class Node : protected ts::detail::RBNode { 00264 friend class iterator; 00265 friend class IpMap; 00266 public: 00267 typedef Node self; ///< Self reference type. 00268 /// Default constructor. 00269 Node() : _data(0) {} 00270 /// Construct with @a data. 00271 Node(void* data) : _data(data) {} 00272 /// @return Client data for the node. 00273 virtual void* data() { return _data; } 00274 /// Set client data. 00275 virtual self& setData( 00276 void* data ///< Client data pointer to store. 00277 ) { 00278 _data = data; 00279 return *this; 00280 } 00281 /// @return Minimum value of the interval. 00282 virtual sockaddr const* min() const = 0; 00283 /// @return Maximum value of the interval. 00284 virtual sockaddr const* max() const = 0; 00285 protected: 00286 void* _data; ///< Client data. 00287 }; 00288 00289 /** Iterator over nodes / intervals. 00290 00291 The iteration is over all nodes, regardless of which node is 00292 used to create the iterator. The node passed to the constructor 00293 just sets the current location. 00294 */ 00295 class iterator { 00296 friend class IpMap; 00297 public: 00298 typedef iterator self; ///< Self reference type. 00299 typedef Node value_type; ///< Referenced type for iterator. 00300 typedef int difference_type; ///< Distance type. 00301 typedef Node* pointer; ///< Pointer to referent. 00302 typedef Node& reference; ///< Reference to referent. 00303 typedef std::bidirectional_iterator_tag iterator_category; 00304 /// Default constructor. 00305 iterator() : _tree(0), _node(0) {} 00306 00307 reference operator* () const; //!< value operator 00308 pointer operator -> () const; //!< dereference operator 00309 self& operator++(); //!< next node (prefix) 00310 self operator++(int); //!< next node (postfix) 00311 self& operator--(); ///< previous node (prefix) 00312 self operator--(int); ///< next node (postfix) 00313 00314 /** Equality. 00315 @return @c true if the iterators refer to the same node. 00316 */ 00317 bool operator==(self const& that) const; 00318 /** Inequality. 00319 @return @c true if the iterators refer to different nodes. 00320 */ 00321 bool operator!=(self const& that) const { return ! (*this == that); } 00322 private: 00323 /// Construct a valid iterator. 00324 iterator(IpMap const* tree, Node* node) : _tree(tree), _node(node) {} 00325 IpMap const* _tree; ///< Container. 00326 Node* _node; //!< Current node. 00327 }; 00328 00329 IpMap(); ///< Default constructor. 00330 ~IpMap(); ///< Destructor. 00331 00332 /** Mark a range. 00333 All addresses in the range [ @a min , @a max ] are marked with @a data. 00334 @return This object. 00335 */ 00336 self& mark( 00337 sockaddr const* min, ///< Minimum value in range. 00338 sockaddr const* max, ///< Maximum value in range. 00339 void* data = 0 ///< Client data payload. 00340 ); 00341 00342 /** Mark a range. 00343 All addresses in the range [ @a min , @a max ] are marked with @a data. 00344 @note Convenience overload for IPv4 addresses. 00345 @return This object. 00346 */ 00347 self& mark( 00348 in_addr_t min, ///< Minimum address (network order). 00349 in_addr_t max, ///< Maximum address (network order). 00350 void* data = 0 ///< Client data. 00351 ); 00352 00353 /** Mark a range. 00354 All addresses in the range [ @a min , @a max ] are marked with @a data. 00355 @note Convenience overload for IPv4 addresses. 00356 @return This object. 00357 */ 00358 self& mark( 00359 IpAddr const& min, ///< Minimum address (network order). 00360 IpAddr const& max, ///< Maximum address (network order). 00361 void* data = 0 ///< Client data. 00362 ); 00363 00364 /** Mark an IPv4 address @a addr with @a data. 00365 This is equivalent to calling @c mark(addr, addr, data). 00366 @note Convenience overload for IPv4 addresses. 00367 @return This object. 00368 */ 00369 self& mark( 00370 in_addr_t addr, ///< Address (network order). 00371 void* data = 0 ///< Client data. 00372 ); 00373 00374 /** Mark a range. 00375 All addresses in the range [ @a min , @a max ] are marked with @a data. 00376 @note Convenience overload. 00377 @return This object. 00378 */ 00379 self& mark( 00380 IpEndpoint const* min, ///< Minimum address (network order). 00381 IpEndpoint const* max, ///< Maximum address (network order). 00382 void* data = 0 ///< Client data. 00383 ); 00384 00385 /** Mark an address @a addr with @a data. 00386 This is equivalent to calling @c mark(addr, addr, data). 00387 @note Convenience overload. 00388 @return This object. 00389 */ 00390 self& mark( 00391 IpEndpoint const* addr, ///< Address (network order). 00392 void* data = 0 ///< Client data. 00393 ); 00394 00395 /** Unmark addresses. 00396 00397 All addresses in the range [ @a min , @a max ] are cleared 00398 (removed from the map), no longer marked. 00399 00400 @return This object. 00401 */ 00402 self& unmark( 00403 sockaddr const* min, ///< Minimum value. 00404 sockaddr const* max ///< Maximum value. 00405 ); 00406 /// Unmark addresses (overload). 00407 self& unmark( 00408 IpEndpoint const* min, 00409 IpEndpoint const* max 00410 ); 00411 /// Unmark overload. 00412 self& unmark( 00413 in_addr_t min, ///< Minimum of range to unmark. 00414 in_addr_t max ///< Maximum of range to unmark. 00415 ); 00416 00417 /** Fill addresses. 00418 00419 This background fills using the range. All addresses in the 00420 range that are @b not present in the map are added. No 00421 previously present address is changed. 00422 00423 @note This is useful for filling in first match tables because @a data for already present 00424 addresses is not changed. 00425 00426 @return This object. 00427 */ 00428 self& fill( 00429 sockaddr const* min, 00430 sockaddr const* max, 00431 void* data = 0 00432 ); 00433 /// Fill addresses (overload). 00434 self& fill( 00435 IpEndpoint const* min, 00436 IpEndpoint const* max, 00437 void* data = 0 00438 ); 00439 /// Fill addresses (overload). 00440 self& fill( 00441 in_addr_t min, 00442 in_addr_t max, 00443 void* data = 0 00444 ); 00445 00446 /** Test for membership. 00447 00448 @return @c true if the address is in the map, @c false if not. 00449 If the address is in the map and @a ptr is not @c NULL, @c *ptr 00450 is set to the client data for the address. 00451 */ 00452 bool contains( 00453 sockaddr const* target, ///< Search target (network order). 00454 void **ptr = 0 ///< Client data return. 00455 ) const; 00456 00457 /** Test for membership. 00458 00459 @note Covenience overload for IPv4. 00460 00461 @return @c true if the address is in the map, @c false if not. 00462 If the address is in the map and @a ptr is not @c NULL, @c *ptr 00463 is set to the client data for the address. 00464 */ 00465 bool contains( 00466 in_addr_t target, ///< Search target (network order). 00467 void **ptr = 0 ///< Client data return. 00468 ) const; 00469 00470 /** Test for membership. 00471 00472 @note Convenience overload for @c IpEndpoint. 00473 00474 @return @c true if the address is in the map, @c false if not. 00475 If the address is in the map and @a ptr is not @c NULL, @c *ptr 00476 is set to the client data for the address. 00477 */ 00478 bool contains( 00479 IpEndpoint const* target, ///< Search target (network order). 00480 void **ptr = 0 ///< Client data return. 00481 ) const; 00482 00483 /** Test for membership. 00484 00485 @note Convenience overload for @c IpAddr. 00486 00487 @return @c true if the address is in the map, @c false if not. 00488 If the address is in the map and @a ptr is not @c NULL, @c *ptr 00489 is set to the client data for the address. 00490 */ 00491 bool contains( 00492 IpAddr const& target, ///< Search target (network order). 00493 void **ptr = 0 ///< Client data return. 00494 ) const; 00495 00496 /** Remove all addresses from the map. 00497 00498 @note This is much faster than @c unmark. 00499 @return This object. 00500 */ 00501 self& clear(); 00502 00503 /// Iterator for first element. 00504 iterator begin() const; 00505 /// Iterator past last element. 00506 iterator end() const; 00507 /// @return Number of distinct ranges in the map. 00508 size_t getCount() const; 00509 00510 /** Validate internal data structures. 00511 @note Intended for debugging, not general client use. 00512 */ 00513 void validate(); 00514 00515 /// Print all spans. 00516 /// @return This map. 00517 // self& print(); 00518 00519 protected: 00520 /// Force the IPv4 map to exist. 00521 /// @return The IPv4 map. 00522 ts::detail::Ip4Map* force4(); 00523 /// Force the IPv6 map to exist. 00524 /// @return The IPv6 map. 00525 ts::detail::Ip6Map* force6(); 00526 00527 ts::detail::Ip4Map* _m4; ///< Map of IPv4 addresses. 00528 ts::detail::Ip6Map* _m6; ///< Map of IPv6 addresses. 00529 00530 }; 00531 00532 inline IpMap& IpMap::mark(in_addr_t addr, void* data) { 00533 return this->mark(addr, addr, data); 00534 } 00535 00536 inline IpMap& IpMap::mark(IpAddr const& min, IpAddr const& max, void* data) { 00537 IpEndpoint x,y; 00538 x.assign(min); 00539 y.assign(max); 00540 return this->mark(&x.sa, &y.sa, data); 00541 } 00542 00543 inline IpMap& IpMap::mark(IpEndpoint const* addr, void* data) { 00544 return this->mark(&addr->sa, &addr->sa, data); 00545 } 00546 00547 inline IpMap& IpMap::mark(IpEndpoint const* min, IpEndpoint const* max, void* data) { 00548 return this->mark(&min->sa, &max->sa, data); 00549 } 00550 00551 inline IpMap& IpMap::unmark(IpEndpoint const* min, IpEndpoint const* max) { 00552 return this->unmark(&min->sa, &max->sa); 00553 } 00554 00555 inline IpMap& IpMap::fill(IpEndpoint const* min, IpEndpoint const* max, void* data) { 00556 return this->fill(&min->sa, &max->sa, data); 00557 } 00558 00559 inline bool IpMap::contains(IpEndpoint const* target, void** ptr) const { 00560 return this->contains(&target->sa, ptr); 00561 } 00562 00563 inline bool 00564 IpMap::contains(IpAddr const& addr, void** ptr) const { 00565 IpEndpoint ip; 00566 ip.assign(addr); 00567 return this->contains(&ip.sa, ptr); 00568 } 00569 00570 inline IpMap::iterator 00571 IpMap::end() const { 00572 return iterator(this, 0); 00573 } 00574 00575 inline IpMap::iterator 00576 IpMap::iterator::operator ++ (int) { 00577 iterator old(*this); 00578 ++*this; 00579 return old; 00580 } 00581 00582 inline IpMap::iterator 00583 IpMap::iterator::operator--(int) { 00584 self tmp(*this); 00585 --*this; 00586 return tmp; 00587 } 00588 00589 inline bool 00590 IpMap::iterator::operator == (iterator const& that) const { 00591 return _tree == that._tree && _node == that._node; 00592 } 00593 00594 inline IpMap::iterator::reference 00595 IpMap::iterator::operator * () const { 00596 return *_node; 00597 } 00598 00599 inline IpMap::iterator::pointer 00600 IpMap::iterator::operator -> () const { 00601 return _node; 00602 } 00603 00604 inline IpMap::IpMap() : _m4(0), _m6(0) {} 00605 00606 # endif // TS_IP_MAP_HEADER