A couple of the bugs fixed.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/c3673da9 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/c3673da9 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/c3673da9 Branch: refs/heads/master Commit: c3673da95974d01b5223d13883c69a84a66e734a Parents: 2cebb26 Author: Alan M. Carroll <[email protected]> Authored: Fri Mar 16 21:58:54 2012 -0500 Committer: Alan M. Carroll <[email protected]> Committed: Fri Mar 16 21:58:54 2012 -0500 ---------------------------------------------------------------------- lib/ts/IpMap.cc | 28 +++++++++++----- lib/ts/IpMap.h | 6 ++-- lib/ts/IpMapTest.cc | 76 +++++++++++++++++++++++++++++++++------------- lib/ts/ink_inet.h | 4 +- 4 files changed, 79 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c3673da9/lib/ts/IpMap.cc ---------------------------------------------------------------------- diff --git a/lib/ts/IpMap.cc b/lib/ts/IpMap.cc index 7c2b157..41d79bd 100644 --- a/lib/ts/IpMap.cc +++ b/lib/ts/IpMap.cc @@ -588,7 +588,7 @@ IpMapBase<N>::clear() { template < typename N > IpMapBase<N>& IpMapBase<N>::fill(ArgType rmin, ArgType rmax, void* payload) { - // Leftmost node of interest with n->_min <= min. + // Rightmost 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. @@ -598,9 +598,15 @@ IpMapBase<N>::fill(ArgType rmin, ArgType rmax, void* payload) { // 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. + Metric min_1; + /* Tricky bit here when min is zero and we can't decrement it. If + it's strictly greater than the node min then it's not zero and + we can check against a decremented value. Moreover, if the node + min isn't less than the range min the node max isn't less + than range min - 1. + */ + if (n->_min < min && (min_1 = min, N::dec(min_1), 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; @@ -665,7 +671,11 @@ IpMapBase<N>::fill(ArgType rmin, ArgType rmax, void* payload) { n = next(n); } } else { - if (min < n->_min) { // Need a span before n. + if (max < n->_min) { // entirely before next span. + this->insertBefore(n, new N(min, max, payload)); + return *this; // done + } else if (min < n->_min) { + // overlap on the right, so make a span to take up the slack. N* y = new N(min, n->_min, payload); y->decrementMax(); this->insertBefore(n, y); @@ -965,11 +975,11 @@ public: ats_ip4_set(ats_ip_sa_cast(&_sa._max), htonl(max)); } /// @return The minimum value of the interval. - virtual sockaddr const* min() { + virtual sockaddr const* min() const { return ats_ip_sa_cast(&_sa._min); } /// @return The maximum value of the interval. - virtual sockaddr const* max() { + virtual sockaddr const* max() const { return ats_ip_sa_cast(&_sa._max); } /// Set the client data. @@ -1092,11 +1102,11 @@ public: ) : Node(data), Ip6Span(min, max) { } /// @return The minimum value of the interval. - virtual sockaddr const* min() { + virtual sockaddr const* min() const { return ats_ip_sa_cast(&_min); } /// @return The maximum value of the interval. - virtual sockaddr const* max() { + virtual sockaddr const* max() const { return ats_ip_sa_cast(&_max); } /// Set the client data. http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c3673da9/lib/ts/IpMap.h ---------------------------------------------------------------------- diff --git a/lib/ts/IpMap.h b/lib/ts/IpMap.h index 9357512..5efbc74 100644 --- a/lib/ts/IpMap.h +++ b/lib/ts/IpMap.h @@ -280,9 +280,9 @@ public: return *this; } /// @return Minimum value of the interval. - virtual sockaddr const* min() = 0; + virtual sockaddr const* min() const = 0; /// @return Maximum value of the interval. - virtual sockaddr const* max() = 0; + virtual sockaddr const* max() const = 0; protected: void* _data; ///< Client data. }; @@ -477,7 +477,7 @@ public: /// Print all spans. /// @return This map. - self& print(); + // self& print(); protected: /// Force the IPv4 map to exist. http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c3673da9/lib/ts/IpMapTest.cc ---------------------------------------------------------------------- diff --git a/lib/ts/IpMapTest.cc b/lib/ts/IpMapTest.cc index 5b034b7..693998c 100644 --- a/lib/ts/IpMapTest.cc +++ b/lib/ts/IpMapTest.cc @@ -38,7 +38,22 @@ inline bool check(RegressionTest* t, int* pstatus, bool test, char const* fmt, . return test; } -REGRESSION_TEST(IpMap_Test_Basic)(RegressionTest* t, int atype, int* pstatus) { + +void +IpMapTestPrint(IpMap& map) { + printf("IpMap Dump\n"); + for ( IpMap::iterator spot(map.begin()), limit(map.end()) + ; spot != limit + ; ++spot + ) { + ip_text_buffer ipb1, ipb2; + + printf("%s - %s : %p\n", ats_ip_ntop(spot->min(), ipb1, sizeof ipb1), ats_ip_ntop(spot->max(), ipb2, sizeof(ipb2)), spot->data()); + } + printf("\n"); +} + +REGRESSION_TEST(IpMap_Basic)(RegressionTest* t, int atype, int* pstatus) { IpMap map; void* const markA = reinterpret_cast<void*>(1); void* const markB = reinterpret_cast<void*>(2); @@ -98,23 +113,29 @@ REGRESSION_TEST(IpMap_Test_Basic)(RegressionTest* t, int atype, int* pstatus) { } -REGRESSION_TEST(IpMap_Test_Fill)(RegressionTest* t, int atype, int* pstatus) { +REGRESSION_TEST(IpMap_Fill)(RegressionTest* t, int atype, int* pstatus) { IpMap map; ip_text_buffer ipb1, ipb2; - void* const allow = reinterpret_cast<void*>(1); - void* const deny = reinterpret_cast<void*>(2); + void* const allow = reinterpret_cast<void*>(0); + void* const deny = reinterpret_cast<void*>(~0); + 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 - IpEndpoint a1,a2,a3,a4,a5,a6, a7, a8; - IpEndpoint target, a_loopback; + IpEndpoint a0,a_10_28_56_0,a_10_28_56_255,a3,a4,a5,a6, a7,a8; + IpEndpoint target, a_max, a_loopback, a_loopback2; IpEndpoint t6; + IpEndpoint a_63_128_1_12; *pstatus = REGRESSION_TEST_PASSED; - ats_ip_pton("10.28.56.0", &a1); - ats_ip_pton("10.28.56.255", &a2); - ats_ip_pton("0.0.0.0", &a3); - ats_ip_pton("255.255.255.255", &a4); + ats_ip_pton("0.0.0.0", &a0); + ats_ip_pton("255.255.255.255", &a_max); + ats_ip_pton("10.28.56.0", &a_10_28_56_0); + ats_ip_pton("10.28.56.255", &a_10_28_56_255); + ats_ip_pton("192.168.1.0", &a3); + ats_ip_pton("192.168.1.255", &a4); ats_ip_pton("::", &a5); ats_ip_pton("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &a6); ats_ip_pton("fe80::221:9bff:fe10:9d90", &a7); @@ -122,9 +143,11 @@ REGRESSION_TEST(IpMap_Test_Fill)(RegressionTest* t, int atype, int* pstatus) { ats_ip_pton("10.28.56.4", &target); ats_ip_pton("fe80::221:9bff:fe10:9d95", &t6); ats_ip_pton("127.0.0.1", &a_loopback); + ats_ip_pton("127.0.0.255", &a_loopback2); + ats_ip_pton("63.128.1.12", &a_63_128_1_12); - map.fill(&a1,&a2,deny); - map.fill(&a3,&a4,allow); + map.fill(&a_10_28_56_0,&a_10_28_56_255,deny); + map.fill(&a0,&a_max,allow); map.fill(&a5,&a6,allow); map.fill(&a7,&a8,deny); @@ -134,24 +157,35 @@ REGRESSION_TEST(IpMap_Test_Fill)(RegressionTest* t, int atype, int* pstatus) { check(t, pstatus, mark == allow, "IpMap Sample: Bad T6 value. Expected allow, got deny."); map.clear(); - map.fill(&a1,&a2,deny); + map.fill(&a_10_28_56_0,&a_10_28_56_255,deny); map.fill(&a7,&a8,deny); - map.fill(&a3,&a4,allow); + map.fill(&a0,&a_max,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."); map.clear(); map.fill(&a_loopback, &a_loopback, allow); - check(t, pstatus, map.contains(&a_loopback), "Map fill: singleton not marked."); - map.fill(&a3, &a4, deny); + check(t, pstatus, map.contains(&a_loopback), "IpMap fill: singleton not marked."); + map.fill(&a0, &a_max, deny); mark=0; - check(t, pstatus, map.contains(&a_loopback, &mark), "Map fill: singleton marking lost."); - check(t, pstatus, mark == allow, "Map fill: overwrote existing singleton mark."); - if (check(t, pstatus, map.begin() != map.end(), "Map fill: map is empty.")) { - if (check(t, pstatus, ++(map.begin()) != map.end(), "Map fill: only one range.")) { - check(t, pstatus, -1 == ats_ip_addr_cmp(map.begin()->max(), (++map.begin())->min()), "Map fill: ranges not disjoint [%s < %s].", ats_ip_ntop(map.begin()->max(), ipb1, sizeof(ipb1)), ats_ip_ntop((++map.begin())->min(), ipb2, sizeof(ipb2))); + check(t, pstatus, map.contains(&a_loopback, &mark), "IpMap fill: singleton marking lost."); + check(t, pstatus, mark == allow, "IpMap fill: overwrote existing singleton mark."); + if (check(t, pstatus, map.begin() != map.end(), "IpMap fill: map is empty.")) { + if (check(t, pstatus, ++(map.begin()) != map.end(), "IpMap fill: only one range.")) { + check(t, pstatus, -1 == ats_ip_addr_cmp(map.begin()->max(), (++map.begin())->min()), "IpMap fill: ranges not disjoint [%s < %s].", ats_ip_ntop(map.begin()->max(), ipb1, sizeof(ipb1)), ats_ip_ntop((++map.begin())->min(), ipb2, sizeof(ipb2))); } } + + map.clear(); + map.fill(&a_loopback, &a_loopback2, markA); + map.fill(&a_10_28_56_0, &a_10_28_56_255, markB); + check(t, pstatus, !map.contains(&a_63_128_1_12, &mark), "IpMap fill[2]: over extended range."); + map.fill(&a0, &a_max, deny); + check(t, pstatus, map.getCount() == 5, "IpMap[2]: Fill failed."); + if (check(t, pstatus, map.contains(&a_63_128_1_12, &mark), "IpMap fill[2]: missing mark")) { + check(t, pstatus, mark == deny, "IpMap fill[2]: missing range"); + } +// IpMapTestPrint(map); } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c3673da9/lib/ts/ink_inet.h ---------------------------------------------------------------------- diff --git a/lib/ts/ink_inet.h b/lib/ts/ink_inet.h index 9c5ab5f..bee7b12 100644 --- a/lib/ts/ink_inet.h +++ b/lib/ts/ink_inet.h @@ -256,8 +256,8 @@ inline sockaddr const* ats_ip_sa_cast(sockaddr_storage const* a) { inline sockaddr* ats_ip_sa_cast(sockaddr_in* a) { return static_cast<sockaddr*>(static_cast<void*>(a)); } -inline sockaddr_storage const* ats_ip_sa_cast(sockaddr_in const* a) { - return static_cast<sockaddr_storage const*>(static_cast<void const*>(a)); +inline sockaddr const* ats_ip_sa_cast(sockaddr_in const* a) { + return static_cast<sockaddr const*>(static_cast<void const*>(a)); } inline sockaddr* ats_ip_sa_cast(sockaddr_in6* a) {
