Author: amc
Date: Thu Oct 13 19:45:59 2011
New Revision: 1183051

URL: http://svn.apache.org/viewvc?rev=1183051&view=rev
Log:
TS-963: Fix ip_allow to be first match.

Added:
    trafficserver/traffic/trunk/lib/ts/IpMapTest.cc
Modified:
    trafficserver/traffic/trunk/CHANGES
    trafficserver/traffic/trunk/lib/ts/IpMap.cc
    trafficserver/traffic/trunk/lib/ts/IpMap.h
    trafficserver/traffic/trunk/lib/ts/Makefile.am
    trafficserver/traffic/trunk/proxy/IPAllow.cc
    trafficserver/traffic/trunk/proxy/config/ip_allow.config.default

Modified: trafficserver/traffic/trunk/CHANGES
URL: 
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/CHANGES?rev=1183051&r1=1183050&r2=1183051&view=diff
==============================================================================
--- trafficserver/traffic/trunk/CHANGES (original)
+++ trafficserver/traffic/trunk/CHANGES Thu Oct 13 19:45:59 2011
@@ -1,5 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 3.1.1
+
+  *) [TS-963] Change the way ip_allow is parsed to be consistent with
+   earlier versions (first match). Added default IPv6 allow. Added
+   regression tests for the underlying IpMap class.
+
   *) [TS-948] Don't reload or load a broken remap.config.
 
   *) [TS-824] Range requests that result in cache refresh give 200 status

Modified: trafficserver/traffic/trunk/lib/ts/IpMap.cc
URL: 
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/IpMap.cc?rev=1183051&r1=1183050&r2=1183051&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/IpMap.cc (original)
+++ trafficserver/traffic/trunk/lib/ts/IpMap.cc Thu Oct 13 19:45:59 2011
@@ -381,7 +381,7 @@ template <
   typedef typename N::Metric Metric;   ///< Import type.g482
 
   IpMapBase() : _root(0) {}
-  ~IpMapBase() { this->erase(); }
+  ~IpMapBase() { this->clear(); }
 
   /** Mark a range.
       All addresses in the range [ @a min , @a max ] are marked with @a data.
@@ -404,6 +404,22 @@ template <
     ArgType max
   );
 
+  /** Fill addresses.
+
+      This background fills using the range. All addresses in the
+      range that are @b not present in the map are added. No
+      previously present address is changed.
+
+      @note This is useful for filling in first match tables.
+
+      @return This object.
+  */
+  self& fill(
+    ArgType min,
+    ArgType max,
+    void* data = 0
+  );
+
   /** Test for membership.
 
       @return @c true if the address is in the map, @c false if not.
@@ -415,16 +431,14 @@ template <
     void **ptr = 0 ///< Client data return.
   ) const;
 
-  /** Erase entire map.
-
-      All addresses are discarded.
+  /** Remove all addresses in the map.
 
       @note This is much faster than using @c unmark with a range of
       all addresses.
 
-      @return This map.
+      @return This object.
   */
-  self& erase();
+  self& clear();
 
   /** Lower bound for @a target.  @return The node whose minimum value
       is the largest that is not greater than @a target, or @c NULL if
@@ -508,7 +522,7 @@ IpMapBase<N>::lowerBound(ArgType target)
 }
 
 template < typename N > IpMapBase<N>&
-IpMapBase<N>::erase() {
+IpMapBase<N>::clear() {
   // Delete everything.
   N* n = static_cast<N*>(_list.getHead());
   while (n) {
@@ -522,10 +536,114 @@ IpMapBase<N>::erase() {
 }
 
 template < typename N > IpMapBase<N>&
+IpMapBase<N>::fill(ArgType rmin, ArgType rmax, void* payload) {
+  // Leftmost node of interest with n->_min <= min.
+  N* n = this->lowerBound(rmin);
+  N* x = 0; // New node (if any).
+  // Need copies because we will modify these.
+  Metric min = N::deref(rmin);
+  Metric max = N::deref(rmax);
+
+  // Handle cases involving a node of interest to the left of the
+  // range.
+  if (n) {
+    Metric min_1 = min;
+    N::dec(min_1);
+    if (n->_max < min_1) { // no overlap, move on to next node.
+      n = next(n);
+    } else if (n->_max >= max) { // incoming range is covered, just discard.
+      return *this;
+    } else if (n->_data != payload) { // different payload, clip range on left.
+      min = n->_max;
+      N::inc(min);
+      n = next(n);
+    } else { // skew overlap with same payload, use node and continue.
+      x = n;
+      n = next(n);
+    }
+  } else {
+    n = this->getHead();
+  }
+
+  // Work through the rest of the nodes of interest.
+  // Invariant: n->_min >= min
+  Metric max_plus1 = max;
+  N::inc(max_plus1);
+  /* Notes:
+     - max (and thence max_plus1) never change during the loop.
+     - we must have either x != 0 or adjust min but not both.
+  */
+  while (n) {
+    if (n->_data == payload) {
+      if (x) {
+        if (n->_min <= max_plus1) { // overlap so extend x and drop n.
+          x->setMax(n->_max);
+          this->remove(n);
+          if (x->_max >= max) return *this; // all done.
+          n = next(x);
+        } else {
+          // have the space to finish off the range.
+          x->setMax(max);
+          return *this;
+        }
+      } else { // not carrying a span.
+        if (n->_min <= max_plus1) { // overlap, extend and continue.
+          x = n;
+          x->setMin(min);
+          if (n->_max >= max) return *this; // extend n covers range.
+          n = next(n);
+        } else { // no overlap, space to complete range.
+          N* y = new N(min, max, payload);
+          this->insertBefore(n, y);
+          return *this;
+        }
+      }
+    } else { // different payload
+      if (x) {
+        if (max < n->_min) { // range ends before n starts, done.
+          x->setMax(max);
+          return *this;
+        } else if (max <= n->_max) { // range ends before n, done.
+          x->setMaxMinusOne(n->_min);
+          return *this;
+        } else { // n is contained in range, skip over it.
+          x->setMaxMinusOne(n->_min);
+          x = 0;
+          min = n->_max;
+          N::inc(min);
+          n = next(n);
+        }
+      } else {
+        if (min < n->_min) { // Need a span before n.
+          N* y = new N(min, n->_min, payload);
+          y->decrementMax();
+          this->insertBefore(n, y);
+        }
+        if (max <= n->_max) return *this;
+        min = n->_max;
+        N::inc(min);
+        n = next(n);
+      }
+    }
+  }
+  // Invariant: min is larger than any existing range maximum.
+  if (x) {
+    x->setMax(max);
+  } else {
+    this->append(new N(min, max, payload));
+  }
+  return *this;
+}
+
+template < typename N > IpMapBase<N>&
 IpMapBase<N>::mark(ArgType min, ArgType max, void* payload) {
   N* n = this->lowerBound(min); // current node.
   N* x = 0; // New node, gets set if we re-use an existing one.
 
+  // Several places it is handy to have max+1.
+  Metric max_plus = N::deref(max);
+  N::inc(max_plus);
+
   /* Some subtlety - for IPv6 we overload the compare operators to do
      the right thing, but we can't overload pointer
      comparisons. Therefore we carefully never compare pointers in
@@ -559,8 +677,6 @@ IpMapBase<N>::mark(ArgType min, ArgType 
       } else if (n->_data == payload) {
         return *this; // request is covered by existing span with the same data
       } else {
-        Metric max_plus = N::deref(max);
-        N::inc(max_plus);
         // request span is covered by existing span.
         x = new N(min, max, payload); //
         n->setMin(max_plus); // clip existing.
@@ -586,8 +702,6 @@ IpMapBase<N>::mark(ArgType min, ArgType 
       // Existing span covers new span but with a different payload.
       // We split it, put the new span in between and we're done.
       N* r;
-      Metric max_plus = N::deref(max);
-      N::inc(max_plus);
       x = new N(min, max, payload);
       r = new N(max_plus, n->_max, n->_data);
       n->setMax(min_1);
@@ -601,28 +715,44 @@ IpMapBase<N>::mark(ArgType min, ArgType 
       if (n) this->insertBefore(n, x);
       else this->append(x); // note that since n == 0 we'll just return.
     }
+  } else if (0 != (n = this->getHead()) &&
+    n->_data == payload &&
+    n->_min <= max_plus
+  ) {
+    // Same payload with overlap, re-use.
+    x = n;
+    n = next(n);
+    x->setMin(min);
+    if (x->_max < max) x->setMax(max);
   } else {
     x = new N(min, max, payload);
     this->prepend(x);
-    n = next(x);
   }
 
   // At this point, @a x has the node for this span and all existing spans of
   // interest start at or past this span.
   while (n) {
-    if (n->_max <= max) {
-      x = n;
-      n = next(n);
-      this->remove(x);
-    } else if (n->_min > max) {
-      // no overlap so we're done.
-      break;
-    } else {
-      Metric max_plus = N::deref(max);
-      // just right overlap, clip and we're done.
-      N::inc(max_plus);
+    if (n->_data == payload) {
+      if (n->_max <= max_plus) { // completely covered, drop span, continue
+        N* r = next(n);
+        this->remove(n);
+        n = r;
+      } else if (n->_min <= max_plus) {// skew overlap on the right.
+        x->setMax(n->_max);
+        this->remove(n);
+        break;
+      } else { // no overlap, done
+        break;
+      }
+    } else if (n->_max <= max) { // covered, discard and continue.
+      N* r = next(n);
+      this->remove(n);
+      n = r;
+    } else if (n->_min <= max) { // skew overlap, clip and done.
       n->setMin(max_plus);
       break;
+    } else { // no overlap, done.
+      break;
     }
   }
 
@@ -820,6 +950,31 @@ protected:
     return *this;
   }
   
+  /** Set the maximum value to one less than @a max.
+      @return This object.
+  */
+  self& setMaxMinusOne(
+    ArgType max ///< One more than maximum value.
+  ) {
+    this->setMax(max);
+    dec(_max);
+    return *this;
+  }
+  /** Set the minimum value to one more than @a min.
+      @return This object.
+  */
+  self& setMinPlusOne(
+    ArgType min ///< One less than minimum value.
+  ) {
+    this->setMin(min);
+    inc(_max);
+    return *this;
+  }
+  /** Decremement the maximum value in place.
+      @return This object.
+  */
+  self& decrementMax() { dec(_max); return *this; }
+
   /// Increment a metric.
   static void inc(
     Metric& m ///< Incremented in place.
@@ -937,6 +1092,30 @@ protected:
   ) {
     return this->setMax(&max);
   }
+  /** Set the maximum value to one less than @a max.
+      @return This object.
+  */
+  self& setMaxMinusOne(
+    Metric const& max ///< One more than maximum value.
+  ) {
+    this->setMax(max);
+    dec(_max);
+    return *this;
+  }
+  /** Set the minimum value to one more than @a min.
+      @return This object.
+  */
+  self& setMinPlusOne(
+    Metric const& min ///< One less than minimum value.
+  ) {
+    this->setMin(min);
+    inc(_max);
+    return *this;
+  }
+  /** Decremement the maximum value in place.
+      @return This object.
+  */
+  self& decrementMax() { dec(_max); return *this; }
   
   /// Increment a metric.
   static void inc(
@@ -944,6 +1123,8 @@ protected:
   ) {
     uint8_t* addr = m.sin6_addr.s6_addr;
     uint8_t* b = addr + INK_IP6_SIZE;
+    // Ripple carry. Walk up the address incrementing until we don't
+    // have a carry.
     do {
       ++*--b;
     } while (b > addr && 0 == *b);
@@ -955,6 +1136,8 @@ protected:
   ) {
     uint8_t* addr = m.sin6_addr.s6_addr;
     uint8_t* b = addr + INK_IP6_SIZE;
+    // Ripple borrow. Walk up the address decrementing until we don't
+    // have a borrow.
     do {
       --*--b;
     } while (b > addr && static_cast<uint8_t>(0xFF) == *b);
@@ -975,6 +1158,9 @@ inline int cmp(sockaddr_in6 const& lhs, 
 // Helper functions
 
 /// Less than.
+inline bool operator<(sockaddr_in6 const& lhs, sockaddr_in6 const& rhs) {
+  return -1 == ts::detail::cmp(lhs, rhs);
+}
 inline bool operator<(sockaddr_in6 const* lhs, sockaddr_in6 const& rhs) {
   return -1 == ts::detail::cmp(*lhs, rhs);
 }
@@ -998,6 +1184,10 @@ inline bool operator==(sockaddr_in6 cons
 inline bool operator<=(sockaddr_in6 const& lhs, sockaddr_in6 const* rhs) {
   return 1 != ts::detail::cmp(lhs, *rhs);
 }
+/// Less than or equal.
+inline bool operator<=(sockaddr_in6 const& lhs, sockaddr_in6 const& rhs) {
+  return 1 != ts::detail::cmp(lhs, rhs);
+}
 /// Greater than or equal.
 inline bool operator>=(sockaddr_in6 const& lhs, sockaddr_in6 const& rhs) {
   return -1 != ts::detail::cmp(lhs, rhs);
@@ -1031,24 +1221,26 @@ IpMap::force4() {
   return _m4;
 }
 
+inline ts::detail::Ip6Map*
+IpMap::force6() {
+  if (!_m6) _m6 = new ts::detail::Ip6Map;
+  return _m6;
+}
+
 bool
 IpMap::contains(sockaddr const* target, void** ptr) const {
   bool zret = false;
   if (AF_INET == target->sa_family) {
-    if (_m4) {
-      zret = _m4->contains(ntohl(ink_inet_ip4_addr_cast(target)), ptr);
-    }
+    zret = _m4 && _m4->contains(ntohl(ink_inet_ip4_addr_cast(target)), ptr);
   } else if (AF_INET6 == target->sa_family) {
-    if (_m6) {
-      zret = _m6->contains(ink_inet_ip6_cast(target), ptr);
-    }
+    zret = _m6 && _m6->contains(ink_inet_ip6_cast(target), ptr);
   }
   return zret;
 }
 
 bool
 IpMap::contains(in_addr_t target, void** ptr) const {
-  return _m4->contains(ntohl(target), ptr);
+  return _m4 && _m4->contains(ntohl(target), ptr);
 }
 
 IpMap&
@@ -1065,15 +1257,14 @@ IpMap::mark(
       data
     );
   } else if (AF_INET6 == min->sa_family) {
-    if (!_m6) _m6 = new ts::detail::Ip6Map;
-    _m6->mark(ink_inet_ip6_cast(min), ink_inet_ip6_cast(max), data);
+    this->force6()->mark(ink_inet_ip6_cast(min), ink_inet_ip6_cast(max), data);
   }
   return *this;
 }
 
 IpMap&
 IpMap::mark(in_addr_t min, in_addr_t max, void* data) {
-  this->force4()->mark(min, max, data);
+  this->force4()->mark(ntohl(min), ntohl(max), data);
   return *this;
 }
 
@@ -1084,13 +1275,48 @@ IpMap::unmark(
 ) {
   ink_assert(min->sa_family == max->sa_family);
   if (AF_INET == min->sa_family) {
-    if (_m4) _m4->unmark(ink_inet_ip4_addr_cast(min), 
ink_inet_ip4_addr_cast(max));
+    if (_m4)
+      _m4->unmark(
+        ntohl(ink_inet_ip4_addr_cast(min)),
+        ntohl(ink_inet_ip4_addr_cast(max))
+      );
   } else if (AF_INET6 == min->sa_family) {
     if (_m6) _m6->unmark(ink_inet_ip6_cast(min), ink_inet_ip6_cast(max));
   }
   return *this;
 }
 
+IpMap&
+IpMap::unmark(in_addr_t min, in_addr_t max) {
+  if (_m4) _m4->unmark(ntohl(min), ntohl(max));
+  return *this;
+}
+
+IpMap&
+IpMap::fill(
+  sockaddr const* min,
+  sockaddr const* max,
+  void* data
+) {
+  ink_assert(min->sa_family == max->sa_family);
+  if (AF_INET == min->sa_family) {
+    this->force4()->fill(
+      ntohl(ink_inet_ip4_addr_cast(min)),
+      ntohl(ink_inet_ip4_addr_cast(max)),
+      data
+    );
+  } else if (AF_INET6 == min->sa_family) {
+    this->force6()->fill(ink_inet_ip6_cast(min), ink_inet_ip6_cast(max), data);
+  }
+  return *this;
+}
+
+IpMap&
+IpMap::fill(in_addr_t min, in_addr_t max, void* data) {
+  this->force4()->fill(ntohl(min), ntohl(max), data);
+  return *this;
+}
+
 size_t
 IpMap::getCount() const {
   size_t zret = 0;
@@ -1099,6 +1325,13 @@ IpMap::getCount() const {
   return zret;
 }
 
+IpMap&
+IpMap::clear() {
+  if (_m4) _m4->clear();
+  if (_m6) _m6->clear();
+  return *this;
+}
+
 IpMap::iterator
 IpMap::begin() {
   Node* x = 0;

Modified: trafficserver/traffic/trunk/lib/ts/IpMap.h
URL: 
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/IpMap.h?rev=1183051&r1=1183050&r2=1183051&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/IpMap.h (original)
+++ trafficserver/traffic/trunk/lib/ts/IpMap.h Thu Oct 13 19:45:59 2011
@@ -393,6 +393,39 @@ public:
     sockaddr const* min, ///< Minimum value.
     sockaddr const* max  ///< Maximum value.
   );
+  /// Unmark overload.
+  self& unmark(
+    in_addr_t min, ///< Minimum of range to unmark.
+    in_addr_t max  ///< Maximum of range to unmark.
+  );
+
+  /** Fill addresses.
+
+      This background fills using the range. All addresses in the
+      range that are @b not present in the map are added. No
+      previously present address is changed.
+
+      @note This is useful for filling in first match tables.
+
+      @return This object.
+  */
+  self& fill(
+    sockaddr const* min,
+    sockaddr const* max,
+    void* data = 0
+  );
+  /// Fill addresses (overload).
+  self& fill(
+    ts_ip_endpoint const* min,
+    ts_ip_endpoint const* max,
+    void* data = 0
+  );
+  /// Fill addresses (overload).
+  self& fill(
+    in_addr_t min,
+    in_addr_t max,
+    void* data = 0
+  );
 
   /** Test for membership.
 
@@ -423,6 +456,13 @@ public:
     void **ptr = 0 ///< Client data return.
   ) const;
 
+  /** Remove all addresses from the map.
+
+      @note This is much faster than @c unmark.
+      @return This object.
+  */
+  self& clear();
+
   /// Iterator for first element.
   iterator begin();
   /// Iterator past last element.
@@ -443,6 +483,9 @@ protected:
   /// Force the IPv4 map to exist.
   /// @return The IPv4 map.
   ts::detail::Ip4Map* force4();
+  /// Force the IPv6 map to exist.
+  /// @return The IPv6 map.
+  ts::detail::Ip6Map* force6();
   
   ts::detail::Ip4Map* _m4; ///< Map of IPv4 addresses.
   ts::detail::Ip6Map* _m6; ///< Map of IPv6 addresses.
@@ -461,6 +504,10 @@ inline IpMap& IpMap::mark(ts_ip_endpoint
   return this->mark(&min->sa, &max->sa, data);
 }
 
+inline IpMap& IpMap::fill(ts_ip_endpoint const* min, ts_ip_endpoint const* 
max, void* data) {
+  return this->fill(&min->sa, &max->sa, data);
+}
+
 inline bool IpMap::contains(ts_ip_endpoint const* target, void** ptr) const {
   return this->contains(&target->sa, ptr);
 }

Added: trafficserver/traffic/trunk/lib/ts/IpMapTest.cc
URL: 
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/IpMapTest.cc?rev=1183051&view=auto
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/IpMapTest.cc (added)
+++ trafficserver/traffic/trunk/lib/ts/IpMapTest.cc Thu Oct 13 19:45:59 2011
@@ -0,0 +1,110 @@
+# include "IpMap.h"
+# include "Regression.h"
+
+inline bool check(RegressionTest* t, int* pstatus, bool test, char const* fmt, 
...) {
+  if (!test) {
+    static size_t const N = 1<<16;
+    char buffer[N]; // just stack, go big.
+    va_list ap;
+    va_start(ap, fmt);
+    vsnprintf(buffer, N, fmt, ap);
+    va_end(ap);
+    rprintf(t, "%s\n", buffer);
+    *pstatus = REGRESSION_TEST_FAILED;
+  }
+  return test;
+}
+
+REGRESSION_TEST(IpMap_Test_Basic)(RegressionTest* t, int atype, int* pstatus) {
+  IpMap map;
+  void* const markA = reinterpret_cast<void*>(1);
+  void* const markB = reinterpret_cast<void*>(2);
+  void* const markC = reinterpret_cast<void*>(3);
+  void* mark; // for retrieval
+
+  in_addr_t ip5 = htonl(5), ip9 = htonl(9);
+  in_addr_t ip10 = htonl(10), ip15 = htonl(15), ip20 = htonl(20);
+  in_addr_t ip50 = htonl(50), ip60 = htonl(60);
+  in_addr_t ip100 = htonl(100), ip120 = htonl(120), ip140 = htonl(140);
+  in_addr_t ip150 = htonl(150), ip160 = htonl(160);
+  in_addr_t ip200 = htonl(200);
+
+  *pstatus = REGRESSION_TEST_PASSED;
+
+  map.mark(ip10,ip20,markA);
+  map.mark(ip5, ip9, markA);
+  check(t, pstatus, map.getCount() == 1, "Coalesce failed");
+  check(t, pstatus, map.contains(ip9), "Range max not found.");
+  check(t, pstatus, map.contains(ip10, &mark), "Span min not found.");
+  check(t, pstatus, mark == markA, "Mark not preserved.");
+
+  map.fill(ip15, ip100, markB);
+  check(t, pstatus, map.getCount() == 2, "Fill failed.");
+  check(t, pstatus, map.contains(ip50, &mark), "Fill interior missing.");
+  check(t, pstatus, mark == markB, "Fill mark not preserved.");
+  check(t, pstatus, !map.contains(ip200), "Span min not found.");
+  check(t, pstatus, map.contains(ip15, &mark), "Old span interior not found.");
+  check(t, pstatus, mark == markA, "Fill overwrote mark.");
+
+  map.clear();
+  check(t, pstatus, map.getCount() == 0, "Clear failed.");
+
+  map.mark(ip20, ip50, markA);
+  map.mark(ip100, ip150, markB);
+  map.fill(ip10, ip200, markC);
+  check(t, pstatus, map.getCount() == 5, "Test 3 failed [expected 5, got 
%d].", map.getCount());
+  check(t, pstatus, map.contains(ip15, &mark), "Test 3 - left span missing.");
+  check(t, pstatus, map.contains(ip60, &mark), "Test 3 - middle span 
missing.");
+  check(t, pstatus, mark == markC, "Test 3 - fill mark wrong.");
+  check(t, pstatus, map.contains(ip160), "Test 3 - right span missing.");
+  check(t, pstatus, map.contains(ip120, &mark), "Test 3 - right mark span 
missing.");
+  check(t, pstatus, mark == markB, "Test 3 - wrong data on right mark span.");
+  map.unmark(ip140, ip160);
+  check(t, pstatus, map.getCount() == 5, "Test 3 unmark failed [expected 5, 
got %d].", map.getCount());
+  check(t, pstatus, !map.contains(ip140), "Test 3 - unmark left edge still 
there.");
+  check(t, pstatus, !map.contains(ip150), "Test 3 - unmark middle still 
there.");
+  check(t, pstatus, !map.contains(ip160), "Test 3 - unmark right edge still 
there.");
+}
+
+REGRESSION_TEST(IpMap_Test_Sample)(RegressionTest* t, int atype, int* pstatus) 
{
+  IpMap map;
+  void* const allow = reinterpret_cast<void*>(1);
+  void* const deny = reinterpret_cast<void*>(2); 
+  void* mark; // for retrieval
+
+  ts_ip_endpoint a1,a2,a3,a4,a5,a6, a7, a8;
+  ts_ip_endpoint target;
+  ts_ip_endpoint t6;
+
+  *pstatus = REGRESSION_TEST_PASSED;
+
+  ink_inet_pton("10.28.56.0", &a1);
+  ink_inet_pton("10.28.56.255", &a2);
+  ink_inet_pton("0.0.0.0", &a3);
+  ink_inet_pton("255.255.255.255", &a4);
+  ink_inet_pton("::", &a5);
+  ink_inet_pton("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &a6);
+  ink_inet_pton("fe80::221:9bff:fe10:9d90", &a7);
+  ink_inet_pton("fe80::221:9bff:fe10:9d9d", &a8);
+  ink_inet_pton("10.28.56.4", &target);
+  ink_inet_pton("fe80::221:9bff:fe10:9d95", &t6);
+
+  map.fill(&a1,&a2,deny);
+  map.fill(&a3,&a4,allow);
+  map.fill(&a5,&a6,allow);
+  map.fill(&a7,&a8,deny);
+
+  check(t, pstatus, map.contains(&target,&mark), "IpMap Sample: Target not 
found.");
+  check(t, pstatus, mark == deny, "IpMap Sample: Bad target value. Expected 
deny, got allow.");
+  check(t, pstatus, map.contains(&t6,&mark), "IpMap Sample: T6 not found.");
+  check(t, pstatus, mark == allow, "IpMap Sample: Bad T6 value. Expected 
allow, got deny.");
+
+  map.clear();
+  map.fill(&a1,&a2,deny);
+  map.fill(&a7,&a8,deny);
+  map.fill(&a3,&a4,allow);
+  map.fill(&a5,&a6,allow);
+  check(t, pstatus, map.contains(&t6,&mark), "IpMap Sample: T6 not found.");
+  check(t, pstatus, mark == deny, "IpMap Sample: Bad T6 value. Expected deny, 
got allow.");
+
+}

Modified: trafficserver/traffic/trunk/lib/ts/Makefile.am
URL: 
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/Makefile.am?rev=1183051&r1=1183050&r2=1183051&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/Makefile.am (original)
+++ trafficserver/traffic/trunk/lib/ts/Makefile.am Thu Oct 13 19:45:59 2011
@@ -125,7 +125,7 @@ libtsutil_la_SOURCES = \
   lockfile.cc \
   I_Layout.h \
   IntrusiveDList.h \
-  IpMap.h IpMap.cc IpMapConf.h IpMapConf.cc \
+  IpMap.h IpMap.cc IpMapConf.h IpMapConf.cc IpMapTest.cc \
   Layout.cc \
   MatcherUtils.cc \
   MatcherUtils.h \

Modified: trafficserver/traffic/trunk/proxy/IPAllow.cc
URL: 
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/IPAllow.cc?rev=1183051&r1=1183050&r2=1183051&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/IPAllow.cc (original)
+++ trafficserver/traffic/trunk/proxy/IPAllow.cc Thu Oct 13 19:45:59 2011
@@ -260,8 +260,8 @@ IpAllow::BuildTable()
                 _acls.push_back(AclRecord(op, line_num));
                 // Color with index because at this point the address
                 // is volatile.
-                _map.mark(
-                  &addr1.sa, &addr2.sa,
+                _map.fill(
+                  &addr1, &addr2,
                   reinterpret_cast<void*>(_acls.size()-1)
                 );
               } else {

Modified: trafficserver/traffic/trunk/proxy/config/ip_allow.config.default
URL: 
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/config/ip_allow.config.default?rev=1183051&r1=1183050&r2=1183051&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/config/ip_allow.config.default (original)
+++ trafficserver/traffic/trunk/proxy/config/ip_allow.config.default Thu Oct 13 
19:45:59 2011
@@ -7,3 +7,4 @@
 # Rules are applied in the order listed starting from the top.
 #
 src_ip=0.0.0.0-255.255.255.255         action=ip_allow
+src_ip=::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff action=ip_allow


Reply via email to