Exemple #1
4
bool
ACE_INET_Addr::operator == (const ACE_INET_Addr &sap) const
{
  ACE_TRACE ("ACE_INET_Addr::operator ==");

  if (this->get_type () != sap.get_type ()
      || this->get_size () != sap.get_size ())
    return false;

  return (ACE_OS::memcmp (&this->inet_addr_,
                          &sap.inet_addr_,
                          this->get_size ()) == 0);
}
Exemple #2
0
// Make sure that ACE_Addr::addr_type_ is the same
// as the family of the inet_addr_.
int check_type_consistency (const ACE_INET_Addr &addr)
{
  int family = -1;

  if (addr.get_type () == AF_INET)
    {
      struct sockaddr_in *sa4 = (struct sockaddr_in *)addr.get_addr();
      family = sa4->sin_family;
    }
#if defined (ACE_HAS_IPV6)
  else if (addr.get_type () == AF_INET6)
    {
      struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)addr.get_addr();
      family = sa6->sin6_family;
    }
#endif

  if (addr.get_type () != family)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("Inconsistency between ACE_SOCK::addr_type_ (%d) ")
                  ACE_TEXT ("and the sockaddr family (%d)\n"),
                  addr.get_type (),
                  family));
      return 1;
    }
  return 0;
}
Exemple #3
0
ACE_INET_Addr::ACE_INET_Addr (const ACE_INET_Addr &sa)
  : ACE_Addr (sa.get_type (), sa.get_size())
{
  ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr");
  this->reset ();
  this->set (sa);
}
ssize_t
RtpsUdpSendStrategy::send_single_i(const iovec iov[], int n,
                                   const ACE_INET_Addr& addr)
{
#ifdef ACE_HAS_IPV6
  ACE_SOCK_Dgram& sock = link_->socket_for(addr.get_type());
#define USE_SOCKET sock
#else
#define USE_SOCKET link_->unicast_socket()
#endif
#ifdef ACE_LACKS_SENDMSG
  char buffer[UDP_MAX_MESSAGE_SIZE];
  char *iter = buffer;
  for (int i = 0; i < n; ++i) {
    if (iter - buffer + iov[i].iov_len > UDP_MAX_MESSAGE_SIZE) {
      ACE_ERROR((LM_ERROR, "(%P|%t) RtpsUdpSendStrategy::send_single_i() - "
                 "message too large at index %d size %d\n", i, iov[i].iov_len));
      return -1;
    }
    std::memcpy(iter, iov[i].iov_base, iov[i].iov_len);
    iter += iov[i].iov_len;
  }
  const ssize_t result = USE_SOCKET.send(buffer, iter - buffer, addr);
#else
  const ssize_t result = USE_SOCKET.send(iov, n, addr);
#endif
  if (result < 0) {
    ACE_TCHAR addr_buff[256] = {};
    addr.addr_to_string(addr_buff, 256, 0);
    ACE_ERROR((LM_ERROR, "(%P|%t) RtpsUdpSendStrategy::send_single_i() - "
      "destination %s failed %p\n", addr_buff, ACE_TEXT("send")));
  }
  return result;
}
bool
RtpsUdpTransport::map_ipv4_to_ipv6() const
{
  bool map = false;
  ACE_INET_Addr tmp;
  link_->unicast_socket().get_local_addr(tmp);
  if (tmp.get_type() != AF_INET) {
    map = true;
  }
  return map;
}
Exemple #6
0
int
ACE_INET_Addr::set (const ACE_INET_Addr &sa)
{
  ACE_TRACE ("ACE_INET_Addr::set");

  if (sa.get_type () == AF_ANY)
    // Ugh, this is really a base class, so don't copy it.
    ACE_OS::memset (&this->inet_addr_, 0, sizeof (this->inet_addr_));
  else
    {
      // It's ok to make the copy.
      ACE_OS::memcpy (&this->inet_addr_,
                      &sa.inet_addr_,
                      sa.get_size ());

      this->set_type (sa.get_type());
      this->set_size (sa.get_size());
    }

  return 0;
}
Exemple #7
0
int
TAO_IIOP_Endpoint::set (const ACE_INET_Addr &addr,
                        int use_dotted_decimal_addresses)
{
  char tmp_host[MAXHOSTNAMELEN + 1];

#if defined (ACE_HAS_IPV6)
  this->is_ipv6_decimal_ = false; // Reset
#endif /* ACE_HAS_IPV6 */

  if (use_dotted_decimal_addresses
      || addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
    {
      if (use_dotted_decimal_addresses == 0 && TAO_debug_level > 5)
        {
          TAOLIB_DEBUG ((LM_DEBUG,
                      ACE_TEXT ("TAO (%P|%t) - IIOP_Endpoint::set, ")
                      ACE_TEXT ("%p\n"),
                      ACE_TEXT ("cannot determine hostname")));
        }

      const char *tmp = addr.get_host_addr ();
      if (tmp == 0)
        {
          if (TAO_debug_level > 0)
            {
              TAOLIB_ERROR ((LM_ERROR,
                          ACE_TEXT ("TAO (%P|%t) - IIOP_Endpoint::set, ")
                          ACE_TEXT ("%p\n"),
                          ACE_TEXT ("cannot determine hostname and hostaddr")));
            }
          return -1;
        }
      else
        {
          this->host_ = tmp;
#if defined (ACE_HAS_IPV6)
          if (addr.get_type () == PF_INET6)
            this->is_ipv6_decimal_ = true;
#endif /* ACE_HAS_IPV6 */
        }
    }
  else
    this->host_ = CORBA::string_dup (tmp_host);

  this->port_ = addr.get_port_number();

  return 0;
}
SimpleAddressServer::SimpleAddressServer (const ACE_INET_Addr& address) {
#if defined (ACE_HAS_IPV6)
  if (address.get_type() == PF_INET6)
    {
      RtecUDPAdmin::UDP_Addr_v6 v6;
      sockaddr_in6 *in6 =
        reinterpret_cast<sockaddr_in6 *>(address.get_addr());
      ACE_OS::memcpy (v6.ipaddr,&in6->sin6_addr,16);
      v6.port = address.get_port_number();
      this->address_.v6_addr (v6);
      return;
    }
#endif /* ACE_HAS_IPV6 */
  RtecUDPAdmin::UDP_Addr v4;
  v4.ipaddr = address.get_ip_address ();
  v4.port   = address.get_port_number ();
  this->address_.v4_addr (v4);
}
int
ACE_SOCK_Dgram_Mcast::open (const ACE_INET_Addr &mcast_addr,
                            const ACE_TCHAR *net_if,
                            int reuse_addr)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open");

  // Only perform the <open> initialization if we haven't been opened
  // earlier.
  // No sanity check?  We should probably flag an error if the user
  // makes multiple calls to open().
  if (this->get_handle () != ACE_INVALID_HANDLE)
    return 0;

  // Invoke lower-layer ::open.
  if (ACE_SOCK::open (SOCK_DGRAM,
                      mcast_addr.get_type (),
                      0, // always use 0
                      reuse_addr) == -1)
    return -1;

  return this->open_i (mcast_addr, net_if, reuse_addr);
}
bool
ACE_INET_Addr::is_ip_equal (const ACE_INET_Addr &sap) const
{
    if (this->get_type () != sap.get_type ()
      || this->get_size () != sap.get_size ())
    return false;

#if defined (ACE_HAS_IPV6)
  if (this->get_type () == PF_INET6)
    {
      const unsigned int *addr =
        reinterpret_cast<const unsigned int*>(this->ip_addr_pointer());
      const unsigned int *saddr =
        reinterpret_cast<const unsigned int*>(sap.ip_addr_pointer());
      return (addr[0] == saddr[0] &&
              addr[1] == saddr[1] &&
              addr[2] == saddr[2] &&
              addr[3] == saddr[3]);
    }
  else
#endif /* ACE_HAS_IPV6 */
  return this->get_ip_address () == sap.get_ip_address();
}
Exemple #11
0
int
ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
  ACE_UNUSED_ARG (argc);
  ACE_UNUSED_ARG (argv);

#if defined (ACE_HAS_IPV6)
  int def_type = AF_UNSPEC;
#endif /* ACE_HAS_IPV6 */

  // network interfaces.
  ACE_INET_Addr *if_addrs = 0;
  size_t if_cnt = 0;

  if (ACE::get_ip_interfaces (if_cnt,
                              if_addrs) != 0
      && errno != ENOTSUP)
    {
      // In the case where errno == ENOTSUP, if_cnt and if_addrs will
      // not be modified, and will each remain equal to zero.  This
      // causes the default interface to be used.
      return -1;
    }

  if (if_cnt == 0 || if_addrs == 0)
    {
      ACE_DEBUG ((LM_WARNING,
                  ACE_TEXT ("TAO (%P|%t) Unable to probe network ")
                  ACE_TEXT ("interfaces.  Using default.\n")));

      if_cnt = 1; // Force the network interface count to be one.
      delete [] if_addrs;
      ACE_NEW_RETURN (if_addrs,
                      ACE_INET_Addr[if_cnt],
                      -1);
    }

  // Scan for the loopback interface since it shouldn't be included in
  // the list of cached hostnames unless it is the only interface.
  size_t lo_cnt = 0;  // Loopback interface count
  for (size_t j = 0; j < if_cnt; ++j)
    if (if_addrs[j].is_loopback ())
      ++lo_cnt;

#if defined (ACE_HAS_IPV6)
  size_t ipv4_cnt = 0;
  size_t ipv4_lo_cnt = 0;
  size_t ipv6_ll = 0;
  bool ipv6_non_ll = false;
  // Scan for IPv4 interfaces since these should not be included
  // when IPv6-only is selected.
  for (size_t j = 0; j < if_cnt; ++j)
    if (if_addrs[j].get_type () != AF_INET6 ||
        if_addrs[j].is_ipv4_mapped_ipv6 ())
      {
        ++ipv4_cnt;
        if (if_addrs[j].is_loopback ())
          ++ipv4_lo_cnt;  // keep track of IPv4 loopback ifs
      }
    else if (!if_addrs[j].is_linklocal () &&
             !if_addrs[j].is_loopback())
      {
        ipv6_non_ll = true; // we have at least 1 non-local IPv6 if
      }
    else if (// !orb_core->orb_params ()->use_ipv6_link_local () &&
             if_addrs[j].is_linklocal ())
      {
        ++ipv6_ll;  // count link local addrs to exclude them afterwards
      }
#endif /* ACE_HAS_IPV6 */

  ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_if_addrs (if_addrs);

#if defined (ACE_HAS_IPV6)
  bool ipv4_only = def_type == AF_INET;
  bool ipv6_only = (def_type == AF_INET6); // ||
  //    orb_core->orb_params ()->connect_ipv6_only ();
#if defined (ACE_WIN32)
  if (default_address.get_type () == AF_INET)
    ipv4_only = true;
  else
    ipv6_only = true;
#endif /* ACE_WIN32 */
  // If the loopback interface is the only interface then include it
  // in the list of interfaces to query for a hostname, otherwise
  // exclude it from the list.
  bool ignore_lo;
  if (ipv6_only)
    // only exclude loopback if non-local if exists
    ignore_lo = ipv6_non_ll;
  else if (ipv4_only)
    ignore_lo = ipv4_cnt != ipv4_lo_cnt;
  else
    ignore_lo = if_cnt != lo_cnt;

  // Adjust counts for IPv6 only if required
  size_t if_ok_cnt = if_cnt;
  if (ipv6_only)
    {
      if_ok_cnt -= ipv4_cnt;
      lo_cnt -= ipv4_lo_cnt;
      ipv4_lo_cnt = 0;
    }
  else if (ipv4_only)
    {
      if_ok_cnt = ipv4_cnt;
      lo_cnt = ipv4_lo_cnt;
      ipv6_ll = 0;
    }

  // In case there are no non-local IPv6 ifs in the list only exclude
  // IPv4 loopback.
  // IPv6 loopback will be needed to successfully connect IPv6 clients
  // in a localhost environment.
  if (!ipv4_only && !ipv6_non_ll)
    lo_cnt = ipv4_lo_cnt;
#else /* ACE_HAS_IPV6 */
  // If the loopback interface is the only interface then include it
  // in the list of interfaces to query for a hostname, otherwise
  // exclude it from the list.
  bool ignore_lo;
  ignore_lo = if_cnt != lo_cnt;
#endif /* !ACE_HAS_IPV6 */

  // The number of hosts/interfaces we want to cache may not be the
  // same as the number of detected interfaces so keep a separate
  // count.
  size_t host_cnt = 0;

  for (size_t i = 0; i < if_cnt; ++i)
    {
#if defined (ACE_HAS_IPV6)
      // Ignore any loopback interface if there are other
      // non-loopback interfaces.
      if (ignore_lo &&
          if_addrs[i].is_loopback () &&
          (ipv4_only ||
           ipv6_non_ll ||
           if_addrs[i].get_type () != AF_INET6))
        continue;

      // Ignore any non-IPv4 interfaces when so required.
      if (ipv4_only &&
          (if_addrs[i].get_type () != AF_INET))
        continue;

      // Ignore any non-IPv6 interfaces when so required.
      if (ipv6_only &&
          (if_addrs[i].get_type () != AF_INET6 ||
           if_addrs[i].is_ipv4_mapped_ipv6 ()))
        continue;

      // Ignore all IPv6 link local interfaces when so required.
      if (// !orb_core->orb_params ()->use_ipv6_link_local () &&
          if_addrs[i].is_linklocal ())
        continue;
#else /* ACE_HAS_IPV6 */
      // Ignore any loopback interface if there are other
      // non-loopback interfaces.
      if (ignore_lo &&
          if_addrs[i].is_loopback ())
        continue;
#endif /* !ACE_HAS_IPV6 */

      // Print the address as a string.
      ACE_OS::printf ("%s\n", if_addrs[i].get_host_addr());

      ++host_cnt;
    }

  return 0;
}
int
ACE_SOCK_Dgram_Mcast::open_i (const ACE_INET_Addr &mcast_addr,
                              const ACE_TCHAR *net_if,
                              int reuse_addr)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open_i");
  // ACE_SOCK::open calls this if reuse_addr is set, so we only need to
  // process port reuse option.
  if (reuse_addr)
    {
#if defined (SO_REUSEPORT)
      int one = 1;
      if (this->ACE_SOCK::set_option (SOL_SOCKET,
                                      SO_REUSEPORT,
                                      &one,
                                      sizeof one) == -1)
        return -1;
#endif /* SO_REUSEPORT */
    }

  // Create an address/port# to bind the socket to. Use mcast_addr to
  // initialize bind_addy to pick up the correct protocol family. If
  // OPT_BINDADDR_YES is set, then we're done. Else use mcast_addr's
  // port number and use the "any" address.
  ACE_INET_Addr bind_addy (mcast_addr);
  if (ACE_BIT_DISABLED (this->opts_, OPT_BINDADDR_YES))
    {
#if defined (ACE_HAS_IPV6)
      if (mcast_addr.get_type () == PF_INET6)
        {
          if (bind_addy.set (mcast_addr.get_port_number (), "::",
                             1, AF_INET6) == -1)
            return -1;
        }
      else
        // Bind to "any" address and explicit port#.
        if (bind_addy.set (mcast_addr.get_port_number ()) == -1)
          return -1;
#else
      // Bind to "any" address and explicit port#.
      if (bind_addy.set (mcast_addr.get_port_number ()) == -1)
        return -1;
#endif /* ACE_HAS_IPV6 */
    }

  // Bind to the address (which may be INADDR_ANY) and port# (which may be 0)
  if (ACE_SOCK_Dgram::shared_open (bind_addy, bind_addy.get_type ()) == -1)
    return -1;

  // Cache the actual bound address (which may be INADDR_ANY)
  // and the actual bound port# (which will be a valid, non-zero port#).
  ACE_INET_Addr bound_addy;
  if (this->get_local_addr (bound_addy) == -1)
    {
      // (Unexpected failure - should be bound to something)
      if (bound_addy.set (bind_addy) == -1)
        {
          // (Shouldn't happen - bind_addy is a valid addy; punt.)
          return -1;
        }
    }

  this->send_addr_ = mcast_addr;
  this->send_addr_.set_port_number (bound_addy.get_port_number ());
  if (net_if)
    {
#if defined (IP_MULTICAST_IF) && (IP_MULTICAST_IF != 0)
#if defined (__linux__) && defined (ACE_HAS_IPV6)
      if (mcast_addr.get_type () == AF_INET6)
        {
          ipv6_mreq send_mreq;
          if (this->make_multicast_ifaddr6 (&send_mreq,
                                           mcast_addr,
                                           net_if) == -1)
            return -1;
          if (this->ACE_SOCK::set_option
                              (IPPROTO_IPV6, IPV6_MULTICAST_IF,
                               &(send_mreq.ipv6mr_interface),
                               sizeof send_mreq.ipv6mr_interface) == -1)
            return -1;
        }
      else
        {
          ip_mreq  send_mreq;
          if (this->make_multicast_ifaddr (&send_mreq,
                                           mcast_addr,
                                           net_if) == -1)
            return -1;
          if (this->ACE_SOCK::set_option (IPPROTO_IP,
                                          IP_MULTICAST_IF,
                                          &(send_mreq.imr_interface),
                                          sizeof send_mreq.imr_interface) == -1)
            return -1;
        }
#else
      ip_mreq  send_mreq;
      if (this->make_multicast_ifaddr (&send_mreq,
                                       mcast_addr,
                                       net_if) == -1)
        return -1;
      if (this->ACE_SOCK::set_option (IPPROTO_IP,
                                      IP_MULTICAST_IF,
                                      &(send_mreq.imr_interface),
                                      sizeof send_mreq.imr_interface) == -1)
        return -1;
#endif /* __linux__ && ACE_HAS_IPV6 */
      this->send_net_if_ = new ACE_TCHAR[ACE_OS::strlen (net_if) + 1];
      ACE_OS::strcpy (this->send_net_if_, net_if);
#else
      // Send interface option not supported - ignore it.
      // (We may have been invoked by ::subscribe, so we have to allow
      // a non-null interface parameter in this function.)
      ACE_DEBUG ((LM_DEBUG,
                  ACE_LIB_TEXT ("Send interface specification not ")
                  ACE_LIB_TEXT ("supported - IGNORED.\n")));
#endif // IP_MULTICAST_IF
    }

  return 0;
}
int
ACE_SOCK_Dgram_Mcast::subscribe_ifs (const ACE_INET_Addr &mcast_addr,
                                     const ACE_TCHAR *net_if,
                                     int reuse_addr)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_ifs");

  if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL)
      && net_if == 0)
    {
#if defined (__linux__) && defined (ACE_HAS_IPV6)
      if (mcast_addr.get_type () == AF_INET6)
        {
          struct if_nameindex *intf;

          intf = ACE_OS::if_nameindex ();

          if (intf == 0)
            return -1;

          size_t nr_subscribed = 0;
          int index = 0;

          while (intf[index].if_index != 0 || intf[index].if_name != 0)
            {
              if (this->join (mcast_addr, reuse_addr,
                              ACE_TEXT_CHAR_TO_TCHAR(intf[index].if_name)) == 0)
                ++nr_subscribed;

              ++index;
            }

          ACE_OS::if_freenameindex (intf);

          if (nr_subscribed == 0)
            {
              errno = ENODEV;
              return -1;
            }

          return 1;
        }
        else
          {
            // Subscribe on all local multicast-capable network interfaces, by
            // doing recursive calls with specific interfaces.

            ACE_INET_Addr *if_addrs = 0;
            size_t if_cnt;

            if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
              return -1;

            size_t nr_subscribed = 0;

            if (if_cnt < 2)
              {
                if (this->subscribe (mcast_addr,
                                     reuse_addr,
                                     ACE_LIB_TEXT ("0.0.0.0")) == 0)
                  ++nr_subscribed;
              }
            else
              {
                // Iterate through all the interfaces, figure out which ones
                // offer multicast service, and subscribe to them.
                while (if_cnt > 0)
                  {
                    --if_cnt;

                    // Convert to 0-based for indexing, next loop check.
                    if (if_addrs[if_cnt].get_ip_address () == INADDR_LOOPBACK)
                      continue;
                    if (this->subscribe (mcast_addr,
                                         reuse_addr,
                                         ACE_TEXT_CHAR_TO_TCHAR
                                     (if_addrs[if_cnt].get_host_addr ())) == 0)
                      ++nr_subscribed;
                  }
              }

            delete [] if_addrs;

            if (nr_subscribed == 0)
              {
                errno = ENODEV;
                return -1;
              }

            // 1 indicates a "short-circuit" return.  This handles the
            // recursive behavior of checking all the interfaces.
            return 1;

          }
#else
      // Subscribe on all local multicast-capable network interfaces, by
      // doing recursive calls with specific interfaces.

      ACE_INET_Addr *if_addrs = 0;
      size_t if_cnt;

      if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
        return -1;

      size_t nr_subscribed = 0;

      if (if_cnt < 2)
        {
          if (this->subscribe (mcast_addr,
                               reuse_addr,
                               ACE_LIB_TEXT ("0.0.0.0")) == 0)
            ++nr_subscribed;
        }
      else
        {
          // Iterate through all the interfaces, figure out which ones
          // offer multicast service, and subscribe to them.
          while (if_cnt > 0)
            {
              --if_cnt;

              // Convert to 0-based for indexing, next loop check.
              if (if_addrs[if_cnt].get_ip_address () == INADDR_LOOPBACK)
                continue;
              if (this->subscribe (mcast_addr,
                                   reuse_addr,
                                   ACE_TEXT_CHAR_TO_TCHAR
                                     (if_addrs[if_cnt].get_host_addr ())) == 0)
                ++nr_subscribed;
            }
        }

      delete [] if_addrs;

      if (nr_subscribed == 0)
        {
          errno = ENODEV;
          return -1;
        }

      // 1 indicates a "short-circuit" return.  This handles the
      // recursive behavior of checking all the interfaces.
      return 1;
#endif /* __linux__ && ACE_HAS_IPV6 */
    }

#if defined (__linux__) && defined (ACE_HAS_IPV6)
  if (mcast_addr.get_type () == AF_INET6)
    {
      if (this->make_multicast_ifaddr6 (0, mcast_addr, net_if) == -1)
        return -1;
    }
  else
    {
      // Validate passed multicast addr and iface specifications.
      if (this->make_multicast_ifaddr (0,
                                       mcast_addr,
                                       net_if) == -1)
        return -1;
    }
#else
    // Validate passed multicast addr and iface specifications.
    if (this->make_multicast_ifaddr (0,
                                     mcast_addr,
                                     net_if) == -1)
      return -1;
#endif /* __linux__ && ACE_HAS_IPV6 */

  return 0;

}
// Attempt subscribe and return status.
int
ACE_SOCK_Dgram_Mcast::subscribe_i (const ACE_INET_Addr &mcast_addr,
                                   int reuse_addr,
                                   const ACE_TCHAR *net_if)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_i");
  ip_mreq  mreq;
#if defined (__linux__) && defined (ACE_HAS_IPV6)
  ipv6_mreq mreq6;
#endif /* __linux__ && ACE_HAS_IPV6 */

  // Open the socket IFF this is the first ::subscribe and ::open
  // was not explicitly invoked.
  if (this->open (mcast_addr,
                  net_if,
                  reuse_addr) == -1)
    return -1;

  // Only do this if net_if == 0, i.e., INADDR_ANY
  if (net_if == 0)
    {
      int result = this->subscribe_ifs (mcast_addr,
                                        net_if,
                                        reuse_addr);
      // Check for error or "short-circuit" return.
      if (result != 0)
        return result;
    }

#if defined (__linux__) && defined (ACE_HAS_IPV6)
  if (mcast_addr.get_type () == AF_INET6)
    {
      if (this->make_multicast_ifaddr6 (&mreq6, mcast_addr, net_if) == -1)
        return -1;
      // Tell IP stack to pass messages sent to this group.
      else if (this->ACE_SOCK::set_option (IPPROTO_IPV6,
                                           IPV6_JOIN_GROUP,
                                           &mreq6,
                                           sizeof mreq6) == -1)
        return -1;
    }
  else
    {
      // Create multicast addr/if struct.
      if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
        return -1;
      // Tell IP stack to pass messages sent to this group.
      else if (this->ACE_SOCK::set_option (IPPROTO_IP,
                                           IP_ADD_MEMBERSHIP,
                                           &mreq,
                                           sizeof mreq) == -1)
        return -1;

    }
#else
  if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
    return -1;
  // Tell IP stack to pass messages sent to this group.
  // Note, this is not IPv6 compliant.
  else if (this->ACE_SOCK::set_option (IPPROTO_IP,
                                       IP_ADD_MEMBERSHIP,
                                       &mreq,
                                       sizeof mreq) == -1)
    return -1;

#endif /* __linux__ && ACE_HAS_IPV6 */

  return 0;
}
int
ACE_SOCK_Dgram_Mcast::unsubscribe_ifs (const ACE_INET_Addr &mcast_addr,
                                       const ACE_TCHAR *net_if)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_ifs");


  if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL)
      && net_if == 0)
    {
#if defined (__linux__) && defined (ACE_HAS_IPV6)
      if (mcast_addr.get_type () == AF_INET6)
        {
          struct if_nameindex *intf;

          intf = ACE_OS::if_nameindex ();

          if (intf == 0)
            return -1;

          size_t nr_unsubscribed = 0;
          int index = 0;

          while (intf[index].if_index != 0 || intf[index].if_name != 0)
            {
              if (this->leave (mcast_addr, ACE_TEXT_CHAR_TO_TCHAR(intf[index].if_name)) == 0)
                ++nr_unsubscribed;

              ++index;
            }

          ACE_OS::if_freenameindex (intf);

          if (nr_unsubscribed == 0)
            {
              errno = ENODEV;
              return -1;
            }

          return 1;


        }
      else
        {
          // Unsubscribe on all local multicast-capable network interfaces, by
          // doing recursive calls with specific interfaces.

          ACE_INET_Addr *if_addrs = 0;
          size_t if_cnt;

          // NOTE - <get_ip_interfaces> doesn't always get all of the
          // interfaces.  In particular, it may not get a PPP interface.  This
          // is a limitation of the way <get_ip_interfaces> works with
          // old versions of MSVC.  The reliable way of getting the interface
          // list is available only with MSVC 5 and newer.
          if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
            return -1;

          size_t nr_unsubscribed = 0;

          if (if_cnt < 2)
            {
              if (this->leave (mcast_addr,
                               ACE_LIB_TEXT ("0.0.0.0")) == 0)
                ++nr_unsubscribed;
            }
          else
            {
              while (if_cnt > 0)
                {
                  --if_cnt;
                  // Convert to 0-based for indexing, next loop check
                  if (if_addrs[if_cnt].get_ip_address () == INADDR_LOOPBACK)
                    continue;
                  if (this->leave (mcast_addr,
                                   ACE_TEXT_CHAR_TO_TCHAR
                                   (if_addrs[if_cnt].get_host_addr ())) == 0)
                    ++nr_unsubscribed;
                }
            }

          delete [] if_addrs;

          if (nr_unsubscribed == 0)
            {
              errno = ENODEV;
              return -1;
            }

          return 1;

        }
#else
      // Unsubscribe on all local multicast-capable network interfaces, by
      // doing recursive calls with specific interfaces.

      ACE_INET_Addr *if_addrs = 0;
      size_t if_cnt;

      // NOTE - <get_ip_interfaces> doesn't always get all of the
      // interfaces.  In particular, it may not get a PPP interface.  This
      // is a limitation of the way <get_ip_interfaces> works with
      // old versions of MSVC.  The reliable way of getting the interface list
      // is available only with MSVC 5 and newer.
      if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
        return -1;

      size_t nr_unsubscribed = 0;

      if (if_cnt < 2)
        {
          if (this->leave (mcast_addr,
                           ACE_LIB_TEXT ("0.0.0.0")) == 0)
            ++nr_unsubscribed;
        }
      else
        {
          while (if_cnt > 0)
            {
              --if_cnt;
              // Convert to 0-based for indexing, next loop check
              if (if_addrs[if_cnt].get_ip_address () == INADDR_LOOPBACK)
                continue;
              if (this->leave (mcast_addr,
                               ACE_TEXT_CHAR_TO_TCHAR
                               (if_addrs[if_cnt].get_host_addr ())) == 0)
                ++nr_unsubscribed;
            }
        }

      delete [] if_addrs;

      if (nr_unsubscribed == 0)
        {
          errno = ENODEV;
          return -1;
        }

      return 1;
#endif /* __linux__ && ACE_HAS_IPV6 */
    }

  return 0;
}
template <class HANDLER> int
ACE_Asynch_Acceptor<HANDLER>::open (const ACE_INET_Addr &address,
                                    size_t bytes_to_read,
                                    bool pass_addresses,
                                    int backlog,
                                    int reuse_addr,
                                    ACE_Proactor *proactor,
                                    bool validate_new_connection,
                                    int reissue_accept,
                                    int number_of_initial_accepts)
{
  ACE_TRACE ("ACE_Asynch_Acceptor<>::open");

  this->proactor (proactor);
  this->pass_addresses_ = pass_addresses;
  this->bytes_to_read_ = bytes_to_read;
  this->validate_new_connection_ = validate_new_connection;
  this->reissue_accept_ = reissue_accept;
  this->addr_family_ = address.get_type ();

  // Create the listener socket
  this->listen_handle_ = ACE_OS::socket (address.get_type (), SOCK_STREAM, 0);
  if (this->listen_handle_ == ACE_INVALID_HANDLE)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("%p\n"),
                       ACE_TEXT ("ACE_OS::socket")),
                      -1);
  // Initialize the ACE_Asynch_Accept
  if (this->asynch_accept_.open (*this,
                                 this->listen_handle_,
                                 0,
                                 this->proactor ()) == -1)
    {
      ACE_Errno_Guard g (errno);
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("%p\n"),
                  ACE_TEXT ("ACE_Asynch_Accept::open")));
      ACE_OS::closesocket (this->listen_handle_);
      this->listen_handle_ = ACE_INVALID_HANDLE;
      return -1;
    }

  if (reuse_addr)
    {
      // Reuse the address
      int one = 1;
      if (ACE_OS::setsockopt (this->listen_handle_,
                              SOL_SOCKET,
                              SO_REUSEADDR,
                              (const char*) &one,
                              sizeof one) == -1)
        {
          ACE_Errno_Guard g (errno);
          ACE_ERROR ((LM_ERROR,
                      ACE_TEXT ("%p\n"),
                      ACE_TEXT ("ACE_OS::setsockopt")));
          ACE_OS::closesocket (this->listen_handle_);
          this->listen_handle_ = ACE_INVALID_HANDLE;
          return -1;
        }
    }

  // If port is not specified, bind to any port.
  static ACE_INET_Addr sa (ACE_sap_any_cast (const ACE_INET_Addr &));

  if (address == sa &&
      ACE::bind_port (this->listen_handle_,
                      INADDR_ANY,
                      address.get_type()) == -1)
    {
      ACE_Errno_Guard g (errno);
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("%p\n"),
                  ACE_TEXT ("ACE::bind_port")));
      ACE_OS::closesocket (this->listen_handle_);
      this->listen_handle_ = ACE_INVALID_HANDLE;
      return -1;
    }

  // Bind to the specified port.
  if (ACE_OS::bind (this->listen_handle_,
                    reinterpret_cast<sockaddr *> (address.get_addr ()),
                    address.get_size ()) == -1)
    {
      ACE_Errno_Guard g (errno);
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("%p\n"),
                  ACE_TEXT ("ACE_OS::bind")));
      ACE_OS::closesocket (this->listen_handle_);
      this->listen_handle_ = ACE_INVALID_HANDLE;
      return -1;
    }

  // Start listening.
  if (ACE_OS::listen (this->listen_handle_, backlog) == -1)
    {
      ACE_Errno_Guard g (errno);
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("%p\n"),
                  ACE_TEXT ("ACE_OS::listen")));
      ACE_OS::closesocket (this->listen_handle_);
      this->listen_handle_ = ACE_INVALID_HANDLE;
      return -1;
    }

  // For the number of <intial_accepts>.
  if (number_of_initial_accepts == -1)
    number_of_initial_accepts = backlog;

  for (int i = 0; i < number_of_initial_accepts; i++)
    {
      // Initiate accepts.
      if (this->accept (bytes_to_read) == -1)
        {
          ACE_Errno_Guard g (errno);
          ACE_ERROR ((LM_ERROR,
                      ACE_TEXT ("%p\n"),
                      ACE_TEXT ("ACE_Asynch_Acceptor::accept")));
          ACE_OS::closesocket (this->listen_handle_);
          this->listen_handle_ = ACE_INVALID_HANDLE;
          return -1;
        }
    }

  return 0;
}
Exemple #17
0
int
run_main (int argc, ACE_TCHAR *argv[])
{
  ACE_START_TEST (ACE_TEXT ("TP_Reactor_Test"));

#if defined(ACE_HAS_THREADS)
  if (::parse_args (argc, argv) == -1)
    return -1;

  ::disable_signal (SIGPIPE, SIGPIPE);

  MyTask    task1;
  Acceptor  acceptor;
  Connector connector;

  if (task1.start (threads) == 0)
    {
      int rc = 0;

      ACE_INET_Addr addr (port);
      if (both != 0 || host == 0) // Acceptor
        rc += acceptor.start (addr);

      if (both != 0 || host != 0)
        {
          if (host == 0)
            host = ACE_LOCALHOST;

          if (addr.set (port, host, 1, addr.get_type ()) == -1)
            ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), host));
          rc += connector.start (addr, senders);

        }

      if (rc > 0)
        ACE_OS::sleep (seconds);
    }

  task1.stop ();

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("\nNumber of Receivers objects = %d\n")
              ACE_TEXT ("\nNumber of Sender objects = %d\n"),
              acceptor.get_number_sessions (),
              connector.get_number_sessions ()));

  // As Reactor event loop now is inactive it is safe to destroy all
  // senders

  connector.stop ();
  acceptor.stop ();

  //Print statistic
  ACE_TCHAR bufs [256];
  ACE_TCHAR bufr [256];

  ACE_OS::sprintf ( bufs , ACE_TEXT ("%ld(%ld)"),
                    connector.get_total_snd(),
                    connector.get_total_w() );

  ACE_OS::sprintf ( bufr , ACE_TEXT ("%ld(%ld)"),
                    connector.get_total_rcv(),
                    connector.get_total_r() );

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Connector/Senders  total bytes: snd=%s rcv=%s\n"),
              bufs,
              bufr
            ));

  ACE_OS::sprintf ( bufs , ACE_TEXT ("%ld(%ld)"),
                    acceptor.get_total_snd(),
                    acceptor.get_total_w() );

  ACE_OS::sprintf ( bufr , ACE_TEXT ("%ld(%ld)"),
                    acceptor.get_total_rcv(),
                    acceptor.get_total_r() );

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Acceptor/Receivers total bytes: snd=%s rcv=%s\n"),
              bufs,
              bufr
            ));

#else /* ACE_HAS_THREADS */
   ACE_UNUSED_ARG( argc );
   ACE_UNUSED_ARG( argv );
#endif /* ACE_HAS_THREADS */

  ACE_END_TEST;

  return 0;
}
int
ACE_SOCK_Dgram_Mcast::subscribe_ifs (const ACE_INET_Addr &mcast_addr,
                                     const ACE_TCHAR *net_if,
                                     int reuse_addr)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_ifs");

  if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL)
      && net_if == 0)
    {
#if defined (ACE_HAS_IPV6)
      if (mcast_addr.get_type () == AF_INET6)
        {
          size_t nr_subscribed = 0;
# if defined(__linux__)
          struct if_nameindex *intf;

          intf = ACE_OS::if_nameindex ();

          if (intf == 0)
            return -1;

          int index = 0;
          while (intf[index].if_index != 0 || intf[index].if_name != 0)
            {
              if (this->join (mcast_addr, reuse_addr,
                              ACE_TEXT_CHAR_TO_TCHAR(intf[index].if_name)) == 0)
                ++nr_subscribed;

              ++index;
            }

          ACE_OS::if_freenameindex (intf);

# elif defined (ACE_WIN32)

          IP_ADAPTER_ADDRESSES tmp_addrs;
          // Initial call to determine actual memory size needed
          DWORD dwRetVal;
          ULONG bufLen = 0;
          if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6,
                                                  0,
                                                  0,
                                                  &tmp_addrs,
                                                  &bufLen)) != ERROR_BUFFER_OVERFLOW)
            return -1; // With output bufferlength 0 this can't be right.

          // Get required output buffer and retrieve info for real.
          PIP_ADAPTER_ADDRESSES pAddrs;
          char *buf;
          ACE_NEW_RETURN (buf,
                          char[bufLen],
                          -1);
          pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf);
          if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6,
                                                  0,
                                                  0,
                                                  pAddrs,
                                                  &bufLen)) != NO_ERROR)
            {
              delete[] buf; // clean up
              return -1;
            }

          while (pAddrs)
            {
              if (this->join (mcast_addr, reuse_addr,
                              ACE_TEXT_CHAR_TO_TCHAR(pAddrs->AdapterName)) == 0)
                ++nr_subscribed;

              pAddrs = pAddrs->Next;
            }

          delete[] buf; // clean up

# endif /* ACE_WIN32 */

          if (nr_subscribed == 0)
            {
              errno = ENODEV;
              return -1;
            }

          return 1;
        }
      else
        {
// Attempt unsubscribe and return status.
int
ACE_SOCK_Dgram_Mcast::unsubscribe_i (const ACE_INET_Addr &mcast_addr,
                                     const ACE_TCHAR *net_if)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_i");

  int result = this->unsubscribe_ifs (mcast_addr,
                                      net_if);

  // Check for error or "short-circuit" return.
  if (result != 0)
    return result;

#if defined (__linux__) && defined (ACE_HAS_IPV6)
  if (mcast_addr.get_type () == AF_INET6)
    {
      // Validate addr/if specifications and create addr/if struct.
      ipv6_mreq  mreq;
      if (this->make_multicast_ifaddr6 (&mreq, mcast_addr, net_if) == -1)
        {
          return -1;
        }
      // Tell network device driver to stop reading datagrams with the
      // <mcast_addr>.
      else if (ACE_SOCK::set_option (IPPROTO_IPV6,
                                     IPV6_LEAVE_GROUP,
                                     &mreq,
                                     sizeof mreq) == -1)
        {
          return -1;
        }

    }
  else  // IPv4
    {
      // Validate addr/if specifications and create addr/if struct.
      ip_mreq  mreq;
      if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
        {
          return -1;
        }
      // Tell network device driver to stop reading datagrams with the
      // <mcast_addr>.
      else if (ACE_SOCK::set_option (IPPROTO_IP,
                                     IP_DROP_MEMBERSHIP,
                                     &mreq,
                                 sizeof mreq) == -1)
        {
          return -1;
        }

    }
#else
  // Validate addr/if specifications and create addr/if struct.
  ip_mreq  mreq;
  if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
    {
      return -1;
    }
  // Tell network device driver to stop reading datagrams with the
  // <mcast_addr>.
  // Note, this is not IPv6 friendly...
  else if (ACE_SOCK::set_option (IPPROTO_IP,
                                 IP_DROP_MEMBERSHIP,
                                 &mreq,
                                 sizeof mreq) == -1)
    {
      return -1;
    }
#endif /* __linux__ && ACE_HAS_IPV6 */

  return 0;
}
int
ACE_SOCK_Dgram_Mcast::open_i (const ACE_INET_Addr &mcast_addr,
                              const ACE_TCHAR *net_if,
                              int reuse_addr)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open_i");
  // ACE_SOCK::open calls this if reuse_addr is set, so we only need to
  // process port reuse option.
  if (reuse_addr)
    {
#if defined (SO_REUSEPORT)
      int one = 1;
      if (this->ACE_SOCK::set_option (SOL_SOCKET,
                                      SO_REUSEPORT,
                                      &one,
                                      sizeof one) == -1)
        return -1;
#endif /* SO_REUSEPORT */
    }

  // Create an address/port# to bind the socket to. Use mcast_addr to
  // initialize bind_addy to pick up the correct protocol family. If
  // OPT_BINDADDR_YES is set, then we're done. Else use mcast_addr's
  // port number and use the "any" address.
  ACE_INET_Addr bind_addy (mcast_addr);
  if (ACE_BIT_DISABLED (this->opts_, OPT_BINDADDR_YES))
    {
#if defined (ACE_HAS_IPV6)
      if (mcast_addr.get_type () == PF_INET6)
        {
          if (bind_addy.set (mcast_addr.get_port_number (), "::",
                             1, AF_INET6) == -1)
            return -1;
        }
      else
        // Bind to "any" address and explicit port#.
        if (bind_addy.set (mcast_addr.get_port_number ()) == -1)
          return -1;
#else
      // Bind to "any" address and explicit port#.
      if (bind_addy.set (mcast_addr.get_port_number ()) == -1)
        return -1;
#endif /* ACE_HAS_IPV6 */
    }

  // Bind to the address (which may be INADDR_ANY) and port# (which may be 0)
  if (ACE_SOCK_Dgram::shared_open (bind_addy, bind_addy.get_type ()) == -1)
    return -1;

  // Cache the actual bound address (which may be INADDR_ANY)
  // and the actual bound port# (which will be a valid, non-zero port#).
  ACE_INET_Addr bound_addy;
  if (this->get_local_addr (bound_addy) == -1)
    {
      // (Unexpected failure - should be bound to something)
      if (bound_addy.set (bind_addy) == -1)
        {
          // (Shouldn't happen - bind_addy is a valid addy; punt.)
          return -1;
        }
    }

  this->send_addr_ = mcast_addr;
  this->send_addr_.set_port_number (bound_addy.get_port_number ());
  if (net_if)
    {
      if (this->set_nic (net_if, mcast_addr.get_type ()))
        return -1;

      this->send_net_if_ = new ACE_TCHAR[ACE_OS::strlen (net_if) + 1];
      ACE_OS::strcpy (this->send_net_if_, net_if);
    }

  return 0;
}
Exemple #21
0
void
DSession::handle_write_dgram(const TRB_Asynch_Write_Dgram::Result &result)
{
  {
    ACE_GUARD (ACE_SYNCH_MUTEX, monitor, this->lock_);

    this->io_count_w_--;

    int loglevel = cfg.loglevel();

    ACE_Message_Block *mb = result.message_block ();
    size_t xfer_bytes = result.bytes_transferred();
    char * last  = mb->rd_ptr();
    char * first = last - xfer_bytes; 

    u_long error = result.error ();

    const ACE_Addr  & addr = result.remote_address ();

    ACE_INET_Addr peerAddr ((u_short)0);
    
    if (addr.get_type () == peerAddr.get_type ())
      { // copy the remote_address_ into addr

        peerAddr.set_addr (addr.get_addr(),
                           addr.get_size());
        
      }

    if (cfg.loglevel () == 0)
      {
        LogLocker log_lock;

        //mb.rd_ptr () [0] = '\0';
        mb->rd_ptr (mb->rd_ptr () - result.bytes_transferred ());

        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("(%t) **** %s=%d handle_write_dgram() ****\n"),
                    this->get_name(),
                    this->index()));

        this->print_address (result.remote_address());

        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("%s = %d\n"),
                    ACE_TEXT ("bytes_to_write"),
                    result.bytes_to_write ()));
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("%s = %d\n"),
                    ACE_TEXT ("handle"),
                    result.handle ()));

        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("%s = %d\n"),
                    ACE_TEXT ("bytes_transfered"),
                    result.bytes_transferred ()));

        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("%s = %d\n"),
                    ACE_TEXT ("error"),
                    error));

        ACE_DEBUG ((LM_DEBUG,
            ACE_TEXT ("message_block:\n")));

        ACE_HEX_DUMP ((LM_DEBUG, first, xfer_bytes));

        ACE_DEBUG ((LM_DEBUG,
            ACE_TEXT ("**** end of message ****************\n")));
      }
    else if (error != 0)
      {
        LogLocker log_lock;

        this->print_address (result.remote_address());

        ACE_OS::last_error (error);
        ACE_Log_Msg::instance ()->errnum (error);
        ACE_Log_Msg::instance ()->log (LM_ERROR,
                                       ACE_TEXT ("(%t) %s=%d WRITE ERROR=%d %p\n"),
                                       this->get_name (),
                                       this->index (),
                                       error,
                                       ACE_TEXT (":"));
      }
    else if (loglevel == 1)
      {
         LogLocker log_lock;
         this->print_address (result.remote_address());

         ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("(%t) %s=%d WRITE=%d bytes ok\n"),
                    this->get_name (),
                    this->index (),
                    result.bytes_transferred ()));
      }

    if (error == 0 && result.bytes_transferred () > 0)
      {
        this->total_snd_ += result.bytes_transferred ();
      }
    else
      {
        mb->msg_type (ACE_Message_Block::MB_ERROR);
        mb->wr_ptr (mb->rd_ptr());
      }

    this->on_data_sent (*mb, peerAddr);

 
    if (this->io_count_r_ != 0 || 
        this->io_count_w_ != 0 ||
        this->post_count_ != 0 )
      return;
  }
  delete this;
}
int
ACE_SOCK_Dgram_Mcast::subscribe_ifs (const ACE_INET_Addr &mcast_addr,
                                     const ACE_TCHAR *net_if,
                                     int reuse_addr)
{
  ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_ifs");

  if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL)
      && net_if == 0)
    {
      int family = mcast_addr.get_type ();
      size_t nr_subscribed = 0;

#if defined (ACE_HAS_GETIFADDRS)

      // Take advantage of the BSD getifaddrs function that simplifies
      // access to connected interfaces.
      struct ifaddrs *ifap = 0;
      struct ifaddrs *p_if = 0;

      if (::getifaddrs (&ifap) != 0)
        return -1;

      // Not every interface is for IP, and not all are up and multicast.
      for (p_if = ifap;
           p_if != 0;
           p_if = p_if->ifa_next)
        {
          // Some OSes can return interfaces with no ifa_addr if the
          // interface has no assigned address.
          // If there is an address but it's not the family we want, ignore it.
          if (p_if->ifa_addr == 0 || p_if->ifa_addr->sa_family != family)
            continue;

          // Check to see if it's up and supports multicast.
          unsigned int wanted = IFF_UP | IFF_MULTICAST;
          if ((p_if->ifa_flags & wanted) != wanted)
            continue;

          // Sometimes the kernel returns 0.0.0.0 as the interface
          // address, skip those...
          if (p_if->ifa_addr->sa_family == PF_INET)
            {
              struct sockaddr_in *addr =
                reinterpret_cast<sockaddr_in *> (p_if->ifa_addr);

              if (addr->sin_addr.s_addr == INADDR_ANY)
                continue;
            }
#  if defined (ACE_HAS_IPV6)
          else if (p_if->ifa_addr->sa_family == AF_INET6)
            {
              struct sockaddr_in6 *addr =
                reinterpret_cast<sockaddr_in6 *> (p_if->ifa_addr);

              // Skip the ANY address
              if (IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr))
                continue;
            }
#  endif /* ACE_HAS_IPV6 */

          // Ok, now join on this interface.
          if (this->join (mcast_addr,
                          reuse_addr,
                          ACE_TEXT_CHAR_TO_TCHAR(p_if->ifa_name)) == 0)
            ++nr_subscribed;
        }

      ::freeifaddrs (ifap);

# elif defined (ACE_WIN32)

      IP_ADAPTER_ADDRESSES tmp_addrs;
      // Initial call to determine actual memory size needed
      DWORD dwRetVal;
      ULONG bufLen = 0;
      // Note... GetAdaptersAddresses returns different bufLen values depending
      // on how many multicast joins there are on the system. To avoid this,
      // specify that we don't want to know about multicast addresses. This
      // does not avoid multicastable interfaces and makes the size-check
      // more reliable across varying conditions.
      DWORD flags = GAA_FLAG_SKIP_MULTICAST;
      if ((dwRetVal = ::GetAdaptersAddresses (family,
                                              flags,
                                              0,
                                              &tmp_addrs,
                                              &bufLen)) != ERROR_BUFFER_OVERFLOW)
        {
          errno = dwRetVal;
          return -1; // With output bufferlength 0 this can't be right.
        }

      // Get required output buffer and retrieve info for real.
      PIP_ADAPTER_ADDRESSES pAddrs;
      char *buf;
      ACE_NEW_RETURN (buf,
                      char[bufLen],
                      -1);
      pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf);
      if ((dwRetVal = ::GetAdaptersAddresses (family,
                                              flags,
                                              0,
                                              pAddrs,
                                              &bufLen)) != NO_ERROR)
        {
          delete[] buf; // clean up
          errno = dwRetVal;
          return -1;
        }

      for (; pAddrs; pAddrs = pAddrs->Next)
        {
          if (pAddrs->OperStatus != IfOperStatusUp)
            continue;

          // The ACE_SOCK_Dgram::make_multicast_ifaddr (IPv4), called by join(),
          // can only deal with a dotted-decimal address, not an interface name.
          if (family == AF_INET)
            {
              ACE_INET_Addr intf_addr ((sockaddr_in*)(pAddrs->FirstUnicastAddress->Address.lpSockaddr),
                                       pAddrs->FirstUnicastAddress->Address.iSockaddrLength);
              char intf_addr_str[INET_ADDRSTRLEN];
              intf_addr.get_host_addr (intf_addr_str, sizeof (intf_addr_str));
              if (this->join (mcast_addr, reuse_addr,
                              ACE_TEXT_CHAR_TO_TCHAR(intf_addr_str)) == 0)
                ++nr_subscribed;
            }
          else
            {
              if (this->join (mcast_addr, reuse_addr,
                              ACE_TEXT_CHAR_TO_TCHAR(pAddrs->AdapterName)) == 0)
                ++nr_subscribed;
            }
        }

      delete[] buf; // clean up

# else

      // Subscribe on all local multicast-capable network interfaces, by
      // doing recursive calls with specific interfaces.

      ACE_INET_Addr *if_addrs = 0;
      size_t if_cnt;

      if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
        return -1;

      if (if_cnt < 2)
        {
          if (this->join (mcast_addr,
                          reuse_addr,
                          ACE_TEXT ("0.0.0.0")) == 0)
            ++nr_subscribed;
        }
      else
        {
          // Iterate through all the interfaces, figure out which ones
          // offer multicast service, and subscribe to them.
          while (if_cnt > 0)
            {
              --if_cnt;

              // Convert to 0-based for indexing, next loop check.
              if (if_addrs[if_cnt].get_type () != family || if_addrs[if_cnt].is_loopback ())
                continue;
              char addr_buf[INET6_ADDRSTRLEN];
              if (this->join (mcast_addr,
                              reuse_addr,
                              ACE_TEXT_CHAR_TO_TCHAR
                                     (if_addrs[if_cnt].get_host_addr (addr_buf, INET6_ADDRSTRLEN))) == 0)
                ++nr_subscribed;
            }
        }

      delete [] if_addrs;

# endif /* ACE_WIN32 */

      if (nr_subscribed == 0)
        {
          errno = ENODEV;
          return -1;
        }

      return 1;
    }
int
run_main (int argc, ACE_TCHAR *argv[])
{
  ACE_START_TEST (ACE_TEXT ("Proactor_Scatter_Gather_Test"));

  if (::parse_args (argc, argv) == -1)
    return -1;

  chunk_size = ACE_OS::getpagesize ();

  if (client_only)
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("Running as client only, page size %d\n"),
                chunk_size));
  else if (server_only)
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("Running as server only, page size %d\n"),
                chunk_size));
  else
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("Running as server and client, page size %d\n"),
                chunk_size));

  Acceptor  acceptor;
  Connector connector;
  ACE_INET_Addr addr (port);

  if (!client_only)
    {
      // Simplify, initial read with zero size
      if (-1 == acceptor.open (addr, 0, 1))
        {
          ACE_TEST_ASSERT (0);
          return -1;
        }
    }

  if (!server_only)
    {
      if (-1 == connector.open (1, ACE_Proactor::instance ()))
        {
          ACE_TEST_ASSERT (0);
          return -1;
        }

      // connect to first destination
      if (addr.set (port, host, 1, addr.get_type ()) == -1)
        ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), host), -1);
      connector.set_address (addr);
      if (-1 == connector.connect (addr))
        {
          ACE_TEST_ASSERT (0);
          return -1;
        }
    }

  ACE_Proactor::instance ()->run_event_loop ();

  // As Proactor event loop now is inactive it is safe to destroy all
  // senders

  connector.stop ();
  acceptor.stop ();

  ACE_Proactor::instance()->close_singleton ();

  // now compare the files - available only when on same machine

  int success = 0;
  if (!client_only && !server_only)
    {
      ACE_DEBUG ((LM_INFO,
                  ACE_TEXT ("Comparing the input file and the output file...\n")));

      success = -1;
      // map the two files, then perform memcmp
      {
        ACE_Mem_Map original_file (input_file);
        ACE_Mem_Map reconstructed_file (output_file);

        if (original_file.addr () &&
            original_file.addr () != MAP_FAILED &&
            reconstructed_file.addr () &&
            reconstructed_file.addr () != MAP_FAILED)
          {
            // compare lengths
            if ((original_file.size () == reconstructed_file.size ()) &&
                // and if same size, compare file data
                (0 == ACE_OS::memcmp (original_file.addr (),
                                      reconstructed_file.addr (),
                                      original_file.size ())))
              success = 0;
          }
      }

      if (0 == success)
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("input file and the output file identical!\n")));
      else
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("input file and the output file are different!\n")));
    }

  if (!client_only)
    ACE_OS::unlink (output_file);

  ACE_END_TEST;

  return success;
}
Exemple #24
0
/*
 * Advance the address by 1, e.g., 239.255.0.1 => 239.255.0.2
 * Note that the algorithm is somewhat simplistic, but sufficient for our
 * purpose.
 */
int advance_addr (ACE_INET_Addr &addr)
{
  int a, b, c, d;
  if (addr.get_type () == AF_INET)
    {
      ::sscanf (addr.get_host_addr (), "%d.%d.%d.%d", &a, &b, &c, &d);
      if (d < 255)
        ++d;
      else if (c < 255)
        {
          d = 1;
          ++c;
        }
      else if (b < 255)
        {
          d = 1;
          c = 0;
          ++b;
        }
      else if (a < 239)
        {
          d = 1;
          c = 0;
          b = 0;
          ++a;
        }
      else
        ACE_ERROR_RETURN ((LM_ERROR,
                           ACE_TEXT ("advance_addr - Cannot advance multicast ")
                           ACE_TEXT ("group address past %s\n"),
                           addr.get_host_addr ()),
                          -1);

      ACE_TCHAR buf[MAX_STRING_SIZE];
      ACE_OS::sprintf (buf, ACE_TEXT ("%d.%d.%d.%d:%d"),
                       a, b, c, d, addr.get_port_number ());
      addr.set (buf);
      return 0;
    }
#if defined (ACE_HAS_IPV6)
  else  // assume AF_INET6
    {
      sockaddr_in6 *saddr = reinterpret_cast<sockaddr_in6 *> (addr.get_addr ());
      unsigned char *sin6_addr = reinterpret_cast<unsigned char *> (&saddr->sin6_addr);
      int i = 15;

      // i >= 2 is used here so that the flags and scope for the
      // multicast address are not changed
      while (i >= 2 && sin6_addr[i] == 0xff)
        {
          sin6_addr[i] = 0;
          i--;
        }

      if (i >= 2)
        {
          sin6_addr[i]++;
        }
      else
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             ACE_TEXT ("advance_addr - Cannot advance ")
                             ACE_TEXT ("multicast group address past %s\n"),
                             addr.get_host_addr ()),
                            -1);

        }
    }
#endif /* ACE_HAS_IPV6 */

  return 0;
}