mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
331 lines
9.8 KiB
C++
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
|