You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2014/09/22 19:44:20 UTC
git commit: TS-3093: More funcationlity for IpAddr.
Repository: trafficserver
Updated Branches:
refs/heads/master 05cfba6a7 -> 2f6d6e0d0
TS-3093: More funcationlity for IpAddr.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/2f6d6e0d
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/2f6d6e0d
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/2f6d6e0d
Branch: refs/heads/master
Commit: 2f6d6e0d0e1dc4104912ec5f051922f0df2414d0
Parents: 05cfba6
Author: Alan M. Carroll <am...@network-geographics.com>
Authored: Mon Sep 22 12:43:56 2014 -0500
Committer: Alan M. Carroll <am...@network-geographics.com>
Committed: Mon Sep 22 12:43:56 2014 -0500
----------------------------------------------------------------------
lib/ts/ink_inet.cc | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/ts/ink_inet.h | 58 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2f6d6e0d/lib/ts/ink_inet.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_inet.cc b/lib/ts/ink_inet.cc
index da01ddb..b20633b 100644
--- a/lib/ts/ink_inet.cc
+++ b/lib/ts/ink_inet.cc
@@ -338,6 +338,15 @@ IpAddr::load(char const* text) {
return zret;
}
+int
+IpAddr::load(ts::ConstBuffer const& text)
+{
+ IpEndpoint ip;
+ int zret = ats_ip_pton(text, &ip.sa);
+ this->assign(&ip.sa);
+ return zret;
+}
+
char*
IpAddr::toString(char* dest, size_t len) const {
IpEndpoint ip;
@@ -368,6 +377,61 @@ operator == (IpAddr const& lhs, sockaddr const* rhs) {
return zret;
}
+/** Compare two IP addresses.
+ This is useful for IPv4, IPv6, and the unspecified address type.
+ If the addresses are of different types they are ordered
+
+ Non-IP < IPv4 < IPv6
+
+ - all non-IP addresses are the same ( including @c AF_UNSPEC )
+ - IPv4 addresses are compared numerically (host order)
+ - IPv6 addresses are compared byte wise in network order (MSB to LSB)
+
+ @return
+ - -1 if @a lhs is less than @a rhs.
+ - 0 if @a lhs is identical to @a rhs.
+ - 1 if @a lhs is greater than @a rhs.
+
+ @internal This looks like a lot of code for an inline but I think it
+ should compile down to something reasonable.
+*/
+inline int
+IpAddr::cmp(self const& that) const {
+ int zret = 0;
+ uint16_t rtype = that._family;
+ uint16_t ltype = _family;
+
+ // We lump all non-IP addresses into a single equivalence class
+ // that is less than an IP address. This includes AF_UNSPEC.
+ if (AF_INET == ltype) {
+ if (AF_INET == rtype) {
+ in_addr_t la = ntohl(_addr._ip4);
+ in_addr_t ra = ntohl(that._addr._ip4);
+ if (la < ra) zret = -1;
+ else if (la > ra) zret = 1;
+ else zret = 0;
+ } else if (AF_INET6 == rtype) { // IPv4 < IPv6
+ zret = -1;
+ } else { // IP > not IP
+ zret = 1;
+ }
+ } else if (AF_INET6 == ltype) {
+ if (AF_INET6 == rtype) {
+ zret = memcmp(&_addr._ip6, &that._addr._ip6, TS_IP6_SIZE);
+ } else {
+ zret = 1; // IPv6 greater than any other type.
+ }
+ } else if (AF_INET == rtype || AF_INET6 == rtype) {
+ // ltype is non-IP so it's less than either IP type.
+ zret = -1;
+ } else {
+ // Both types are non-IP so they're equal.
+ zret = 0;
+ }
+
+ return zret;
+}
+
int
ats_ip_getbestaddrinfo(char const* host,
IpEndpoint* ip4,
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2f6d6e0d/lib/ts/ink_inet.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_inet.h b/lib/ts/ink_inet.h
index c5cd248..6c21e74 100644
--- a/lib/ts/ink_inet.h
+++ b/lib/ts/ink_inet.h
@@ -1103,6 +1103,16 @@ struct IpAddr {
int load(
char const* str ///< Nul terminated input string.
);
+
+ /** Load from string.
+ The address is copied to this object if the conversion is successful,
+ otherwise this object is invalidated.
+ @return 0 on success, non-zero on failure.
+ */
+ int load(
+ ts::ConstBuffer const& str ///< Text of IP address.
+ );
+
/** Output to a string.
@return The string @a dest.
*/
@@ -1128,6 +1138,25 @@ struct IpAddr {
return ! (*this == that);
}
+ /// Generic compare.
+ int cmp(self const& that) const;
+
+ /** Return a normalized hash value.
+ - Ipv4: the address in host order.
+ - Ipv6: folded 32 bit of the address.
+ - Else: 0.
+ */
+ uint32_t hash() const;
+
+ /** The hashing function embedded in a functor.
+ @see hash
+ */
+ struct Hasher {
+ uint32_t operator() (self const& ip) const {
+ return ip.hash();
+ }
+ };
+
/// Test for same address family.
/// @c return @c true if @a that is the same address family as @a this.
bool isCompatibleWith(self const& that);
@@ -1153,6 +1182,8 @@ struct IpAddr {
in_addr_t _ip4; ///< IPv4 address storage.
in6_addr _ip6; ///< IPv6 address storage.
uint8_t _byte[TS_IP6_SIZE]; ///< As raw bytes.
+ uint32_t _u32[TS_IP6_SIZE/(sizeof(uint32_t)/sizeof(uint8_t))]; ///< As 32 bit chunks.
+ uint64_t _u64[TS_IP6_SIZE/(sizeof(uint64_t)/sizeof(uint8_t))]; ///< As 64 bit chunks.
} _addr;
///< Pre-constructed invalid instance.
@@ -1224,6 +1255,33 @@ inline bool operator != (IpEndpoint const& lhs, IpAddr const& rhs) {
return ! (rhs == &lhs.sa);
}
+inline bool operator < (IpAddr const& lhs, IpAddr const& rhs) {
+ return -1 == lhs.cmp(rhs);
+}
+
+inline bool operator >= (IpAddr const& lhs, IpAddr const& rhs) {
+ return lhs.cmp(rhs) >= 0;
+}
+
+inline bool operator > (IpAddr const& lhs, IpAddr const& rhs) {
+ return 1 == lhs.cmp(rhs);
+}
+
+inline bool operator <= (IpAddr const& lhs, IpAddr const& rhs) {
+ return lhs.cmp(rhs) <= 0;
+}
+
+inline uint32_t
+IpAddr::hash() const {
+ uint32_t zret = 0;
+ if (this->isIp4()) {
+ zret = ntohl(_addr._ip4);
+ } else if (this->isIp6()) {
+ zret = _addr._u32[0] ^ _addr._u32[1] ^ _addr._u32[2] ^ _addr._u32[3];
+ }
+ return zret;
+}
+
/// Write IP @a addr to storage @a dst.
/// @return @s dst.
sockaddr* ats_ip_set(