diff options
author | Steve Huston <shuston@riverace.com> | 2015-03-12 18:37:39 -0400 |
---|---|---|
committer | Steve Huston <shuston@riverace.com> | 2015-03-12 18:37:39 -0400 |
commit | 2090102d827e2010a939d9ececd1118fa816fff9 (patch) | |
tree | bc34c7b8db44b2e7cd6608114d52aedd61b88244 | |
parent | 0fd2998f2484225bbff712fe19d1f9f3593f7e29 (diff) | |
download | ATCD-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.cpp | 40 | ||||
-rw-r--r-- | ACE/ace/INET_Addr.h | 14 |
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 &); |