Public Member Functions | Public Attributes | Private Member Functions | Private Attributes

ACE_SOCK_Dgram_Bcast Class Reference

Defines the member functions for the ACE_SOCK datagram abstraction. More...

#include <SOCK_Dgram_Bcast.h>

Inheritance diagram for ACE_SOCK_Dgram_Bcast:
Inheritance graph
[legend]
Collaboration diagram for ACE_SOCK_Dgram_Bcast:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ACE_SOCK_Dgram_Bcast (void)
 Default constructor.
 ACE_SOCK_Dgram_Bcast (const ACE_Addr &local, int protocol_family=PF_INET, int protocol=0, int reuse_addr=0, const ACE_TCHAR *host_name=0)
 ~ACE_SOCK_Dgram_Bcast (void)
 Default dtor.
int open (const ACE_Addr &local, int protocol_family=PF_INET, int protocol=0, int reuse_addr=0, const ACE_TCHAR *host_name=0)
 Initiate a connectionless datagram broadcast endpoint.
int close (void)
 Close up and release dynamically allocated resources.
ssize_t send (const void *buf, size_t n, u_short portnum, int flags=0) const
ssize_t send (const iovec iov[], int n, u_short portnum, int flags=0) const
ssize_t send (const void *buf, size_t n, const ACE_Addr &addr, int flags=0) const
ssize_t send (const iovec iov[], int n, const ACE_Addr &addr, int flags=0) const
void dump (void) const
 Dump the state of an object.

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.

Private Member Functions

int mk_broadcast (const ACE_TCHAR *host_name)
 Make broadcast available for Datagram socket.
int get_remote_addr (ACE_Addr &) const
 Do not allow this function to percolate up to this interface...

Private Attributes

ACE_Bcast_Nodeif_list_
 Points to the head of the list of broadcast interfaces.

Detailed Description

Defines the member functions for the ACE_SOCK datagram abstraction.

Definition at line 57 of file SOCK_Dgram_Bcast.h.


Constructor & Destructor Documentation

ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast ( void   ) 

Default constructor.

Definition at line 63 of file SOCK_Dgram_Bcast.cpp.

  : if_list_ (0)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast");
}

ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast ( const ACE_Addr local,
int  protocol_family = PF_INET,
int  protocol = 0,
int  reuse_addr = 0,
const ACE_TCHAR host_name = 0 
)

Definition at line 72 of file SOCK_Dgram_Bcast.cpp.

  : ACE_SOCK_Dgram (local, protocol_family, protocol, reuse_addr),
    if_list_ (0)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast");

  if (this->mk_broadcast (host_name) == -1)
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("%p\n"),
                ACE_TEXT ("ACE_SOCK_Dgram_Bcast")));
}

ACE_SOCK_Dgram_Bcast::~ACE_SOCK_Dgram_Bcast ( void   ) 

Default dtor.

Definition at line 15 of file SOCK_Dgram_Bcast.inl.

{
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::~ACE_SOCK_Dgram_Bcast");
}


Member Function Documentation

int ACE_SOCK_Dgram_Bcast::close ( void   ) 

Close up and release dynamically allocated resources.

Reimplemented from ACE_SOCK.

Definition at line 41 of file SOCK_Dgram_Bcast.cpp.

{
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::close");

  ACE_Bcast_Node *temp = this->if_list_;
  this->if_list_ = 0;

  // Release the dynamically allocated memory.

  while (temp != 0)
    {
      ACE_Bcast_Node *hold = temp->next_;
      delete temp;
      temp = hold;
    }

  // Shut down the descriptor.
  return ACE_SOCK::close ();
}

void ACE_SOCK_Dgram_Bcast::dump ( void   )  const

Dump the state of an object.

Reimplemented from ACE_SOCK_Dgram.

Definition at line 31 of file SOCK_Dgram_Bcast.cpp.

{
#if defined (ACE_HAS_DUMP)
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::dump");
#endif /* ACE_HAS_DUMP */
}

int ACE_SOCK_Dgram_Bcast::get_remote_addr ( ACE_Addr  )  const [private]

Do not allow this function to percolate up to this interface...

Reimplemented from ACE_SOCK_Dgram.

int ACE_SOCK_Dgram_Bcast::mk_broadcast ( const ACE_TCHAR host_name  )  [private]

Make broadcast available for Datagram socket.

Definition at line 109 of file SOCK_Dgram_Bcast.cpp.

{
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::mk_broadcast");

  int one = 1;

  if (ACE_OS::setsockopt (this->get_handle (),
                          SOL_SOCKET,
                          SO_BROADCAST,
                          (char *) &one,
                          sizeof one) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT("%p\n"),
                      ACE_TEXT("ACE_SOCK_Dgram_Bcast::mk_broadcast: setsockopt failed")),
                      -1);

#if !defined (ACE_WIN32) && !defined(__INTERIX)
  ACE_HANDLE s = this->get_handle ();

  char buf[BUFSIZ];
  struct ifconf ifc;

  ifc.ifc_len = sizeof buf;
  ifc.ifc_buf = buf;

  // Get interface structure and initialize the addresses using UNIX
  // techniques.
  if (ACE_OS::ioctl (s,
                     SIOCGIFCONF,
                     (char *) &ifc) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT("%p\n"),
                      ACE_TEXT("ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface configuration)")),
                      ACE_INVALID_HANDLE);

  struct ifreq *ifr = ifc.ifc_req;

  struct sockaddr_in host_addr;

  // Get host ip address
  if (host_name)
    {
      hostent *hp = ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR (host_name));

      if (hp == 0)
        return -1;
      else
#if defined(_UNICOS)
        {
          ACE_UINT64 haddr;  // a place to put the address
          char * haddrp = (char *) &haddr;  // convert to char pointer
          ACE_OS::memcpy(haddrp,(char *) hp->h_addr,hp->h_length);
          host_addr.sin_addr.s_addr = haddr;
        }
#else /* ! _UNICOS */
        ACE_OS::memcpy ((char *) &host_addr.sin_addr.s_addr,
                        (char *) hp->h_addr,
                        hp->h_length);
#endif /* ! _UNICOS */
    }


#if !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_VXWORKS) && !defined(__APPLE__)
  for (int n = ifc.ifc_len / sizeof (struct ifreq) ; n > 0;
       n--, ifr++)
#else
  /*
     There are addresses longer than sizeof (struct sockaddr) eg. IPv6
     or QNX::links. In this case address does not fit into struct ifreq.
     The code below could be applied everywhere, but not every system
         provides sockaddr.sa_len field.
   */
  for (int nbytes = ifc.ifc_len; nbytes >= (int) sizeof (struct ifreq) &&
        ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ?
          (nbytes >= (int) sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len) : 1);
        ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ?
          (nbytes -= sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len,
            ifr = (struct ifreq *)
              ((caddr_t) &ifr->ifr_addr + ifr->ifr_addr.sa_len)) :
          (nbytes -= sizeof (struct ifreq), ifr++)))
#endif /* !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_VXWORKS) && !defined(__APPLE__) */
    {
#if defined (__QNX__) || defined (ACE_VXWORKS)
      // Silently skip link interfaces
      if (ifr->ifr_addr.sa_family == AF_LINK)
        continue;
#endif /* __QNX__ */
      // Compare host ip address with interface ip address.
      if (host_name)
        {
          struct sockaddr_in if_addr;

          ACE_OS::memcpy (&if_addr,
                          &ifr->ifr_addr,
                          sizeof if_addr);

          if (host_addr.sin_addr.s_addr != if_addr.sin_addr.s_addr)
            continue;
        }

      if (ifr->ifr_addr.sa_family != AF_INET)
        {
          // Note that some systems seem to generate 0 (AF_UNDEF) for
          // the sa_family, even when there are no errors!  Thus, we
          // only print an error if this is not the case, or if we're
          // in "debugging" mode.
          if (ifr->ifr_addr.sa_family != 0
              || ACE::debug ())
          ACE_DEBUG ((LM_DEBUG,
                      ACE_TEXT("warning %p: sa_family: %d\n"),
                      ACE_TEXT("ACE_SOCK_Dgram_Bcast::mk_broadcast: Not AF_INET"),
                      ifr->ifr_addr.sa_family));
          continue;
        }

      struct ifreq flags = *ifr;
      struct ifreq if_req = *ifr;

      if (ACE_OS::ioctl (s,
                         SIOCGIFFLAGS,
                         (char *) &flags) == -1)
        {
          ACE_ERROR ((LM_ERROR, ACE_TEXT("%p [%s]\n"),
                     ACE_TEXT("ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface flags)"),
                     flags.ifr_name));
          continue;
        }

      if (ACE_BIT_ENABLED (flags.ifr_flags,
                           IFF_UP) == 0)
        {
          ACE_ERROR ((LM_ERROR, ACE_TEXT("%p [%s]\n"),
                     ACE_TEXT("ACE_SOCK_Dgram_Bcast::mk_broadcast: Network interface is not up"),
                     flags.ifr_name));
          continue;
        }

      if (ACE_BIT_ENABLED (flags.ifr_flags,
                           IFF_LOOPBACK))
        continue;

      if (ACE_BIT_ENABLED (flags.ifr_flags,
                           IFF_BROADCAST))
        {
          if (ACE_OS::ioctl (s,
                             SIOCGIFBRDADDR,
                             (char *) &if_req) == -1)
            ACE_ERROR ((LM_ERROR, ACE_TEXT("%p [%s]\n"),
                       ACE_TEXT("ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get broadaddr)"),
                       flags.ifr_name));
          else
            {
              ACE_INET_Addr addr (reinterpret_cast <sockaddr_in *>
                                                   (&if_req.ifr_broadaddr),
                                  sizeof if_req.ifr_broadaddr);
              ACE_NEW_RETURN (this->if_list_,
                              ACE_Bcast_Node (addr,
                                              this->if_list_),
                              -1);
            }
        }
      else
        {
          if (host_name != 0)
            ACE_ERROR ((LM_ERROR, ACE_TEXT("%p [%s]\n"),
                        ACE_TEXT("ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not enable for this interface."),
                        flags.ifr_name));
        }
    }
#else
  ACE_UNUSED_ARG (host_name);

  ACE_INET_Addr addr (u_short (0),
                      ACE_UINT32 (INADDR_BROADCAST));
  ACE_NEW_RETURN (this->if_list_,
                  ACE_Bcast_Node (addr,
                                  this->if_list_),
                  -1);
#endif /* !ACE_WIN32 && !__INTERIX */
  if (this->if_list_ == 0)
    {
      errno = ENXIO;
      return -1;
    }
  else
    return 0;
}

int ACE_SOCK_Dgram_Bcast::open ( const ACE_Addr local,
int  protocol_family = PF_INET,
int  protocol = 0,
int  reuse_addr = 0,
const ACE_TCHAR host_name = 0 
)

Initiate a connectionless datagram broadcast endpoint.

Definition at line 91 of file SOCK_Dgram_Bcast.cpp.

{
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::open");

  if (this->ACE_SOCK_Dgram::open (local, protocol_family,
                                  protocol, reuse_addr) == -1)
    return -1;

  return this->mk_broadcast (host_name);
}

ssize_t ACE_SOCK_Dgram_Bcast::send ( const void *  buf,
size_t  n,
const ACE_Addr addr,
int  flags = 0 
) const

Broadcast an N byte datagram to ADDR (note that addr must be preassigned to the broadcast address of the subnet...).

Reimplemented from ACE_SOCK_Dgram.

Definition at line 24 of file SOCK_Dgram_Bcast.inl.

{
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send");

  sockaddr *saddr = (sockaddr *) addr.get_addr ();
  int len = addr.get_size ();
  return ACE_OS::sendto (this->get_handle (), (const char *) buf, n, flags,
                         (struct sockaddr *) saddr, len);
}

ssize_t ACE_SOCK_Dgram_Bcast::send ( const iovec  iov[],
int  n,
u_short  portnum,
int  flags = 0 
) const

Broadcast the iov datagrams to every interface. Returns the average number of bytes sent.

ssize_t ACE_SOCK_Dgram_Bcast::send ( const iovec  iov[],
int  n,
const ACE_Addr addr,
int  flags = 0 
) const

Broadcast an iovec of size n to addr as a datagram (note that addr must be preassigned to the broadcast address of the subnet...)

Reimplemented from ACE_SOCK_Dgram.

ssize_t ACE_SOCK_Dgram_Bcast::send ( const void *  buf,
size_t  n,
u_short  portnum,
int  flags = 0 
) const

Broadcast the datagram to every interface. Returns the average number of bytes sent.

Definition at line 299 of file SOCK_Dgram_Bcast.cpp.

{
  ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send");
  ssize_t iterations = 0;
  ssize_t total_bytes = 0;

  if (this->if_list_ == 0)
    return -1;

  for (ACE_Bcast_Node *temp = this->if_list_;
       temp != 0;
       temp = temp->next_)
    {
      temp->bcast_addr_.set_port_number (port_number);

      ssize_t bytes_sent = ACE_SOCK_Dgram::send (buf,
                                                 n,
                                                 temp->bcast_addr_,
                                                 flags);

      if (bytes_sent == -1)
        return -1;
      else
        total_bytes += bytes_sent;

      iterations++;
    }

  return iterations == 0 ? 0 : total_bytes / iterations;
}


Member Data Documentation

Declare the dynamic allocation hooks.

Reimplemented from ACE_SOCK_Dgram.

Definition at line 120 of file SOCK_Dgram_Bcast.h.

Points to the head of the list of broadcast interfaces.

Definition at line 127 of file SOCK_Dgram_Bcast.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines