server/dep/acelite/ace/Multihomed_INET_Addr.cpp
2020-02-16 01:55:18 +00:00

331 lines
9.8 KiB
C++

// Extends ACE_INET_Addr with support for multi-homed addresses.
#include "ace/Multihomed_INET_Addr.h"
#include "ace/Log_Category.h"
#if !defined (__ACE_INLINE__)
# include "ace/Multihomed_INET_Addr.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_Multihomed_INET_Addr)
// Default constructor
ACE_Multihomed_INET_Addr::ACE_Multihomed_INET_Addr (void)
: secondaries_ (0)
{
ACE_TRACE ("ACE_Multihomed_INET_Addr::ACE_Multihomed_INET_Addr");
}
ACE_Multihomed_INET_Addr::ACE_Multihomed_INET_Addr (const char address[])
: ACE_INET_Addr (address),
secondaries_ (0)
{
}
ACE_Multihomed_INET_Addr::ACE_Multihomed_INET_Addr(u_short port_number,
const char host_name[],
int encode,
int address_family,
const char *(secondary_host_names[]),
size_t size){
// Initialize the primary INET addr
ACE_INET_Addr::set(port_number, host_name, encode, address_family);
// check for secondary INET addrs
if (secondary_host_names && size){
// we have a non-zero pointer and size
this->secondaries_.size(size); // size the array
size_t next_empty_slot = 0;
for (size_t i = 0; i < size; ++i) {
int ret = this->secondaries_[next_empty_slot].set(port_number,
secondary_host_names[i],
encode,
address_family);
if (ret) {
ACELIB_DEBUG ((LM_DEBUG,
ACE_TEXT ("Invalid INET addr (%C:%u) will be ignored\n"),
secondary_host_names[i], port_number));
this->secondaries_.size(this->secondaries_.size() - 1);
}
else
++next_empty_slot;
}
}
return;
}
#if defined (ACE_HAS_WCHAR)
ACE_Multihomed_INET_Addr::ACE_Multihomed_INET_Addr(u_short port_number,
const wchar_t host_name[],
int encode,
int address_family,
const wchar_t *(secondary_host_names[]),
size_t size){
// Initialize the primary INET addr
ACE_INET_Addr::set(port_number, host_name, encode, address_family);
// check for secondary INET addrs
if (secondary_host_names && size){
// we have a non-zero pointer and size
this->secondaries_.size(size); // size the array
size_t next_empty_slot = 0;
for (size_t i = 0; i < size; ++i) {
int ret = this->secondaries_[next_empty_slot].set(port_number,
secondary_host_names[i],
encode,
address_family);
if (ret) {
ACELIB_DEBUG ((LM_DEBUG,
ACE_TEXT ("Invalid INET addr (%s:%u) will be ignored\n"),
ACE_TEXT_WCHAR_TO_TCHAR (secondary_host_names[i]), port_number));
this->secondaries_.size(this->secondaries_.size() - 1);
}
else
++next_empty_slot;
}
}
return;
}
#endif /* ACE_HAS_WCHAR */
ACE_Multihomed_INET_Addr::ACE_Multihomed_INET_Addr(u_short port_number,
ACE_UINT32 primary_ip_addr,
int encode,
const ACE_UINT32 *secondary_ip_addrs,
size_t size){
// Initialize the primary INET addr
ACE_INET_Addr::set(port_number, primary_ip_addr, encode);
// check for secondary INET addrs
if (secondary_ip_addrs && size){
// we have a non-zero pointer and size
this->secondaries_.size(size); // size the array
size_t next_empty_slot = 0;
for (size_t i = 0; i < size; ++i) {
int const ret = this->secondaries_[next_empty_slot].set(port_number,
secondary_ip_addrs[i],
encode);
if (ret) {
ACELIB_DEBUG ((LM_DEBUG,
"Invalid INET addr (%u:%u) will be ignored\n",
secondary_ip_addrs[i], port_number));
this->secondaries_.size(this->secondaries_.size() - 1);
}
else
++next_empty_slot;
}
}
return;
}
// Set implementations (NEED BETTER COMMENT HERE)
int
ACE_Multihomed_INET_Addr::set (u_short port_number,
const char host_name[],
int encode,
int address_family,
const char *(secondary_host_names[]),
size_t size)
{
this->secondaries_.size(size);
for (size_t i = 0; i < size; ++i) {
int const ret = this->secondaries_[i].set(port_number,
secondary_host_names[i],
encode,
address_family);
if (ret) {
return ret;
}
}
return ACE_INET_Addr::set(port_number, host_name, encode, address_family);
}
#if defined (ACE_HAS_WCHAR)
//
// WCHAR version of ::set
//
int
ACE_Multihomed_INET_Addr::set (u_short port_number,
const wchar_t host_name[],
int encode,
int address_family,
const wchar_t *(secondary_host_names[]),
size_t size)
{
this->secondaries_.size(size);
for (size_t i = 0; i < size; ++i) {
int ret = this->secondaries_[i].set(port_number,
secondary_host_names[i],
encode,
address_family);
if (ret) {
return ret;
}
}
return ACE_INET_Addr::set(port_number, host_name, encode, address_family);
}
#endif /* ACE_HAS_WCHAR */
int
ACE_Multihomed_INET_Addr::set (u_short port_number,
ACE_UINT32 primary_ip_addr,
int encode,
const ACE_UINT32 *secondary_ip_addrs,
size_t size)
{
this->secondaries_.size(size);
for (size_t i = 0; i < size; ++i) {
int ret = this->secondaries_[i].set(port_number,
secondary_ip_addrs[i],
encode);
if (ret) {
return ret;
}
}
return ACE_INET_Addr::set(port_number, primary_ip_addr, encode);
}
void
ACE_Multihomed_INET_Addr::set_port_number (u_short port_number, int encode)
{
size_t i = 0;
while (i < secondaries_.size())
secondaries_[i++].set_port_number(port_number, encode);
this->ACE_INET_Addr::set_port_number(port_number, encode);
}
int
ACE_Multihomed_INET_Addr::get_secondary_addresses(ACE_INET_Addr *secondary_addrs,
size_t size) const
{
size_t top =
size < this->secondaries_.size() ?
size : this->secondaries_.size();
for (size_t i = 0; i < top; ++i)
{
int ret =
secondary_addrs[i].set (this->secondaries_[i]);
if (ret)
return ret;
}
return 0;
}
void
ACE_Multihomed_INET_Addr::get_addresses(sockaddr_in *addrs,
size_t size) const
{
if (size == 0)
return;
// Copy primary address(es) to the first slot(s) of the user-supplied array
ACE_INET_Addr me (*this);
size_t i = 0;
for (i = 0; i < size; ++i)
{
sockaddr_in *in4 = reinterpret_cast<sockaddr_in*> (me.get_addr ());
if (in4->sin_family == AF_INET)
{
addrs[i] = *in4;
++i;
}
if (!me.next ())
break;
}
// Copy secondary addresses to remaining slots of the user-supplied
// array. Secondary address [i] is copied to slot [i+1]
for (size_t j = 0; j < this->secondaries_.size (); ++j)
{
ACE_INET_Addr copy (this->secondaries_[j]);
for (; i < size; ++i)
{
sockaddr_in *in4 = reinterpret_cast<sockaddr_in*> (copy.get_addr ());
if (in4->sin_family == AF_INET)
{
addrs[i] = *in4;
++i;
}
if (!copy.next ())
break;
}
}
}
#if defined (ACE_HAS_IPV6)
void
ACE_Multihomed_INET_Addr::get_addresses(sockaddr_in6 *addrs,
size_t size) const
{
if (size == 0)
return;
// Copy primary address(es) to the first slot(s) of the user-supplied array
ACE_INET_Addr me (*this);
size_t i = 0;
for (i = 0; i < size; ++i)
{
sockaddr_in6 *in6 = reinterpret_cast<sockaddr_in6*> (me.get_addr ());
if (in6->sin6_family == AF_INET6)
{
addrs[i] = *in6;
++i;
}
if (!me.next ())
break;
}
// Copy secondary addresses to remaining slots of the user-supplied
// array. Secondary address [i] is copied to slot [i+1]
for (size_t j = 0; j < this->secondaries_.size (); ++j)
{
ACE_INET_Addr copy (this->secondaries_[j]);
for (; i < size; ++i)
{
sockaddr_in6 *in6 =
reinterpret_cast<sockaddr_in6*> (copy.get_addr ());
if (in6->sin6_family == AF_INET6)
{
addrs[i] = *in6;
++i;
}
if (!copy.next ())
break;
}
}
}
#endif /* ACE_HAS_IPV6 */
ACE_Multihomed_INET_Addr::~ACE_Multihomed_INET_Addr (void)
{
}
ACE_END_VERSIONED_NAMESPACE_DECL