diff options
Diffstat (limited to 'ace/SOCK_Dgram_Mcast.cpp')
-rw-r--r-- | ace/SOCK_Dgram_Mcast.cpp | 406 |
1 files changed, 0 insertions, 406 deletions
diff --git a/ace/SOCK_Dgram_Mcast.cpp b/ace/SOCK_Dgram_Mcast.cpp deleted file mode 100644 index 9ec50735a6d..00000000000 --- a/ace/SOCK_Dgram_Mcast.cpp +++ /dev/null @@ -1,406 +0,0 @@ -// $Id$ - -#include "ace/SOCK_Dgram_Mcast.h" -#include "ace/INET_Addr.h" - -#if defined (ACE_LACKS_INLINE_FUNCTIONS) -#include "ace/SOCK_Dgram_Mcast.i" -#endif /* ACE_LACKS_INLINE_FUNCTIONS */ - -// This is a workaround for platforms with non-standard -// definitions of the ip_mreq structure -#if ! defined (IMR_MULTIADDR) -#define IMR_MULTIADDR imr_multiaddr -#endif /* ! defined (IMR_MULTIADDR) */ - -ACE_RCSID(ace, SOCK_Dgram_Mcast, "$Id$") - -ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Mcast) - -void -ACE_SOCK_Dgram_Mcast::dump (void) const -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::dump"); -} - -// Dummy default constructor... - -ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast (void) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast"); -} - -int -ACE_SOCK_Dgram_Mcast::open (const ACE_Addr &mcast_addr, - int protocol_family, - int protocol, - int reuse_addr) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open"); - - // Make a copy of address to use in the <send> methods. Note: Sun - // C++ 4.2 needs the useless const_cast. - this->mcast_addr_.set (ACE_reinterpret_cast (const ACE_INET_Addr &, - ACE_const_cast (ACE_Addr &, - mcast_addr))); - // Only perform the <open> initialization if we haven't been opened - // earlier. - if (this->get_handle () == ACE_INVALID_HANDLE) - { - if (ACE_SOCK::open (SOCK_DGRAM, - protocol_family, - protocol, - reuse_addr) == -1) - return -1; - - int one = 1; - if (reuse_addr - && this->ACE_SOCK::set_option (SOL_SOCKET, - SO_REUSEADDR, - &one, - sizeof one) == -1) - return -1; -#if defined (SO_REUSEPORT) - else if (this->ACE_SOCK::set_option (SOL_SOCKET, - SO_REUSEPORT, - &one, - sizeof one) == -1) - return -1; -#endif /* SO_REUSEPORT */ - - // Create an address to bind the socket to. - ACE_INET_Addr local; - -#if defined (linux) - local = this->mcast_addr_; -#else /* linux */ - if (local.set (this->mcast_addr_.get_port_number ()) == -1) - return -1; -#endif /* linux */ - - if (ACE_SOCK_Dgram::shared_open (local, - protocol_family) == -1) - return -1; - } - - return 0; -} - -int -ACE_SOCK_Dgram_Mcast::subscribe_ifs (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol, - int reuse_addr) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_ifs"); -#if defined (ACE_WIN32) - // Windows NT's winsock has trouble with multicast subscribes in the - // presence of multiple network interfaces when the IP address is - // given as INADDR_ANY. It will pick the first interface and only - // accept mcast there. So, to work around this, cycle through all - // of the interfaces known and subscribe to all the non-loopback - // ones. - // - // Note that this only needs to be done on NT, but there's no way to - // tell at this point if the code will be running on NT - only if it - // is compiled for NT-only or for NT/95, and that doesn't really - // help us. It doesn't hurt to do this on Win95, it's just a little - // slower than it normally would be. - // - // NOTE - <ACE::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 <ACE::get_ip_interfaces> works with - // MSVC. The reliable way of getting the interface list is - // available only with MSVC 5. - - if (net_if == 0) - { - 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"), - protocol_family, - protocol) == 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()), - protocol_family, - protocol) == 0) - ++nr_subscribed; - } - - delete [] if_addrs; - - if (nr_subscribed == 0) - { - errno = ENODEV; - return -1; - } - else - // 1 indicates a "short-circuit" return. This handles the - // rather bizarre semantics of checking all the interfaces on - // NT. - return 1; - } -#else - ACE_UNUSED_ARG (mcast_addr); - ACE_UNUSED_ARG (protocol_family); - ACE_UNUSED_ARG (protocol); - ACE_UNUSED_ARG (reuse_addr); -#endif /* ACE_WIN32 */ - // Otherwise, do it like everyone else... - - // Create multicast request. - if (this->make_multicast_address (this->mcast_addr_, - net_if) == -1) - return -1; - else - return 0; -} - -int -ACE_SOCK_Dgram_Mcast::subscribe (const ACE_INET_Addr &mcast_addr, - int reuse_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe"); - - if (this->open (mcast_addr, - protocol_family, - protocol, - reuse_addr) == -1) - return -1; - - int result = this->subscribe_ifs (mcast_addr, - net_if, - protocol_family, - protocol, - reuse_addr); - // Check for the "short-circuit" return value of 1 (for NT). This - // handles the rather bizarre semantics of checking all the - // interfaces on NT. - if (result != 0) - return result; - - // Create multicast request. - else if (this->make_multicast_address (this->mcast_addr_, - net_if) == -1) - return -1; - - // Tell network device driver to read datagrams with a - // multicast_address IP interface. - else if (this->ACE_SOCK::set_option (IPPROTO_IP, - IP_ADD_MEMBERSHIP, - &this->mcast_request_if_, - sizeof this->mcast_request_if_) == -1) - return -1; - else - return 0; -} - -int -ACE_SOCK_Dgram_Mcast::unsubscribe_ifs (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_ifs"); -#if defined (ACE_WIN32) - // Windows NT's winsock has trouble with multicast subscribes in the - // presence of multiple network interfaces when the IP address is - // given as INADDR_ANY. It will pick the first interface and only - // accept mcast there. So, to work around this, cycle through all - // of the interfaces known and subscribe to all the non-loopback - // ones. - // - // Note that this only needs to be done on NT, but there's no way to - // tell at this point if the code will be running on NT - only if it - // is compiled for NT-only or for NT/95, and that doesn't really - // help us. It doesn't hurt to do this on Win95, it's just a little - // slower than it normally would be. - // - // NOTE - <ACE::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 <ACE::get_ip_interfaces> works with - // MSVC. The reliable way of getting the interface list is - // available only with MSVC 5. - - if (net_if == 0) - { - 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_unsubscribed = 0; - - if (if_cnt < 2) - { - if (this->unsubscribe (mcast_addr, - ACE_LIB_TEXT ("0.0.0.0"), - protocol_family, - protocol) == 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->unsubscribe (mcast_addr, - ACE_TEXT_CHAR_TO_TCHAR - (if_addrs[if_cnt].get_host_addr()), - protocol_family, - protocol) == 0) - ++nr_unsubscribed; - } - - delete [] if_addrs; - - if (nr_unsubscribed == 0) - { - errno = ENODEV; - return -1; - } - - return 1; - } -#else - ACE_UNUSED_ARG (protocol_family); - ACE_UNUSED_ARG (protocol); -#endif /* ACE_WIN32 */ - // Otherwise, do it like everyone else. - - ip_mreq multicast_address; - - // Create multicast request. - if (this->make_multicast_address_i (mcast_addr, - multicast_address, - net_if) == -1) - return -1; - else - return 0; -} - -int -ACE_SOCK_Dgram_Mcast::unsubscribe (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe"); - int result = this->unsubscribe_ifs (mcast_addr, - net_if, - protocol_family, - protocol); - - // Check for the "short-circuit" return value of 1 (for NT). - if (result != 0) - return result; - - // Tell network device driver to stop reading datagrams with the - // <mcast_addr>. - else if (ACE_SOCK::set_option (IPPROTO_IP, - IP_DROP_MEMBERSHIP, - &this->mcast_request_if_, - sizeof this->mcast_request_if_) == -1) - return -1; - else - return 0; -} - -int -ACE_SOCK_Dgram_Mcast::unsubscribe (void) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe"); - return this->ACE_SOCK::set_option (IPPROTO_IP, - IP_DROP_MEMBERSHIP, - &this->mcast_request_if_, - sizeof this->mcast_request_if_); -} - -int -ACE_SOCK_Dgram_Mcast::make_multicast_address_i (const ACE_INET_Addr &mcast_addr, - ip_mreq &multicast_address , - const ACE_TCHAR *net_if) -{ - if (net_if != 0) - { -#if defined (ACE_WIN32) - // This port number is not necessary, just convenient - ACE_INET_Addr interface_addr; - if (interface_addr.set (mcast_addr.get_port_number (), - net_if) == -1) - return -1; - multicast_address.imr_interface.s_addr = - htonl (interface_addr.get_ip_address ()); -#else - ifreq if_address; - -#if defined (ACE_PSOS) - // Look up the interface by number, not name. - if_address.ifr_ifno = ACE_OS::atoi (net_if); -#else - ACE_OS::strcpy (if_address.ifr_name, net_if); -#endif /* defined (ACE_PSOS) */ - - if (ACE_OS::ioctl (this->get_handle (), - SIOCGIFADDR, - &if_address) == -1) - return -1; - - sockaddr_in *socket_address; - socket_address = ACE_reinterpret_cast(sockaddr_in *, - &if_address.ifr_addr); - multicast_address.imr_interface.s_addr = socket_address->sin_addr.s_addr; -#endif /* ACE_WIN32 */ - } - else - multicast_address.imr_interface.s_addr = INADDR_ANY; - - multicast_address.IMR_MULTIADDR.s_addr = htonl (mcast_addr.get_ip_address ()); - return 0; -} - -int -ACE_SOCK_Dgram_Mcast::make_multicast_address (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::make_multicast_address"); - - return this->make_multicast_address_i (mcast_addr, - this->mcast_request_if_, - net_if ); -} - - |