summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2015-03-12 18:37:39 -0400
committerSteve Huston <shuston@riverace.com>2015-03-12 18:37:39 -0400
commit2090102d827e2010a939d9ececd1118fa816fff9 (patch)
treebc34c7b8db44b2e7cd6608114d52aedd61b88244
parent0fd2998f2484225bbff712fe19d1f9f3593f7e29 (diff)
downloadATCD-2090102d827e2010a939d9ececd1118fa816fff9.tar.gz
Add ACE_INET_Addr::operator=(const ACE_INET_Addr&) to properly handle ACE_sap_any_cast operations; fix erroneous memset operation in IPv6 case
-rw-r--r--ACE/ace/INET_Addr.cpp40
-rw-r--r--ACE/ace/INET_Addr.h14
2 files changed, 43 insertions, 11 deletions
diff --git a/ACE/ace/INET_Addr.cpp b/ACE/ace/INET_Addr.cpp
index b9186da8c2c..96e26b93dcf 100644
--- a/ACE/ace/INET_Addr.cpp
+++ b/ACE/ace/INET_Addr.cpp
@@ -179,6 +179,13 @@ ACE_INET_Addr::ACE_INET_Addr (void)
this->reset_i ();
}
+ACE_INET_Addr &
+ACE_INET_Addr::operator= (const ACE_INET_Addr& rhs)
+{
+ this->set (rhs);
+ return *this;
+}
+
int
ACE_INET_Addr::set (const ACE_INET_Addr &sa)
{
@@ -380,11 +387,14 @@ ACE_INET_Addr::set (u_short port_number,
for (size_t i = 0; hp->h_addr_list[i]; ++i)
{
union ip46 next_addr;
- struct sockaddr_in6 *next_addr_in6 = (struct sockaddr_in6 *)&next_addr.in6_;
- (void) ACE_OS::memset (&next_addr, sizeof (next_addr), 0);
+ struct sockaddr_in6 *next_addr_in6 = &next_addr.in6_;
+ (void) ACE_OS::memset (&next_addr, 0, sizeof (next_addr));
next_addr_in6->sin6_family = AF_INET6;
next_addr_in6->sin6_port =
encode ? ACE_NTOHS (port_number) : port_number;
+#ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN
+ next_addr_in6_->sin6_len = hp->h_length;
+#endif
(void) ACE_OS::memcpy ((void *) &next_addr_in6->sin6_addr,
hp->h_addr_list[i],
hp->h_length);
@@ -1025,17 +1035,23 @@ int ACE_INET_Addr::set_address (const char *ip_addr,
sizeof (ip6));
return 0;
}
-
- // Build up a 128 bit address. An IPv4-mapped IPv6 address
- // is defined as 0:0:0:0:0:ffff:IPv4_address. This is defined
- // in RFC 1884 */
- ACE_OS::memset (&this->inet_addr_.in6_.sin6_addr, 0, 16);
- this->inet_addr_.in6_.sin6_addr.s6_addr[10] =
- this->inet_addr_.in6_.sin6_addr.s6_addr[11] = 0xff;
- ACE_OS::memcpy
- (&this->inet_addr_.in6_.sin6_addr.s6_addr[12], &ip4, 4);
+ else
+ {
+ // Build up a 128 bit address. An IPv4-mapped IPv6 address
+ // is defined as 0:0:0:0:0:ffff:IPv4_address. This is defined
+ // in RFC 1884 */
+ ACE_OS::memset (&this->inet_addr_.in6_.sin6_addr, 0, 16);
+ this->inet_addr_.in6_.sin6_addr.s6_addr[10] =
+ this->inet_addr_.in6_.sin6_addr.s6_addr[11] = 0xff;
+ ACE_OS::memcpy
+ (&this->inet_addr_.in6_.sin6_addr.s6_addr[12], &ip4, 4);
+ }
}
#endif /* ACE_HAS_IPV6 */
+
+ this->inet_addrs_.clear ();
+ this->inet_addrs_iter_ = this->inet_addrs_.begin ();
+
return 0;
} /* end if (len == 4) */
#if defined (ACE_HAS_IPV6)
@@ -1053,6 +1069,8 @@ int ACE_INET_Addr::set_address (const char *ip_addr,
this->inet_addr_.in6_.sin6_len = sizeof (this->inet_addr_.in6_);
#endif
ACE_OS::memcpy (&this->inet_addr_.in6_.sin6_addr, ip_addr, len);
+ this->inet_addrs_.clear ();
+ this->inet_addrs_iter_ = this->inet_addrs_.begin ();
return 0;
} /* end len == 16 */
diff --git a/ACE/ace/INET_Addr.h b/ACE/ace/INET_Addr.h
index 357eac3f0d2..c1a40553754 100644
--- a/ACE/ace/INET_Addr.h
+++ b/ACE/ace/INET_Addr.h
@@ -113,6 +113,20 @@ public:
// These methods are useful after the object has been constructed.
+ /// Assignment. In a more well-ordered world, member-wise assignment would
+ /// work fine. However, because of the class design feature that all of the
+ /// acceptor/connector-type classes that can be used in the
+ /// Acceptor-Connector framework take ACE_Addr objects instead of the
+ /// addressing class matching the family in use. The mechanism used to
+ /// enable this substitution to the more-appropriate class is
+ /// ACE_sap_any_cast, which casts the ACE_Addr to the more-specific class.
+ /// In this case, casting an ACE_Addr to ACE_INET_Addr then copying it.
+ /// Since adding multiple address support to ACE_INET_Addr, that cast-copy
+ /// operation ends up, in the member-wise case, copying a bogus vector
+ /// and doing lots of random damage. Thus, this operator is used to make
+ /// life ordered in this common scenario.
+ ACE_INET_Addr & operator= (const ACE_INET_Addr &rhs);
+
/// Initializes from another ACE_INET_Addr.
int set (const ACE_INET_Addr &);