diff options
Diffstat (limited to 'ace/SOCK_Dgram_Mcast.cpp')
-rw-r--r-- | ace/SOCK_Dgram_Mcast.cpp | 314 |
1 files changed, 64 insertions, 250 deletions
diff --git a/ace/SOCK_Dgram_Mcast.cpp b/ace/SOCK_Dgram_Mcast.cpp index d9bbaca1524..0a184226281 100644 --- a/ace/SOCK_Dgram_Mcast.cpp +++ b/ace/SOCK_Dgram_Mcast.cpp @@ -6,7 +6,7 @@ #if defined (ACE_LACKS_INLINE_FUNCTIONS) #include "ace/SOCK_Dgram_Mcast.i" -#endif /* ACE_LACKS_INLINE_FUNCTIONS */ +#endif ACE_RCSID(ace, SOCK_Dgram_Mcast, "$Id$") @@ -26,76 +26,16 @@ ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast (void) } 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 (local.set (this->mcast_addr_.get_port_number ()) == -1) - return -1; - else if (ACE_SOCK_Dgram::shared_open (local, - protocol_family) == -1) - return -1; - } - - return 0; -} - -int -ACE_SOCK_Dgram_Mcast::open (const ACE_Addr &mcast_addr, - const ACE_QoS_Params &qos_params, - int protocol_family, - int protocol, - ACE_Protocol_Info *protocolinfo, - ACE_SOCK_GROUP g, - u_long flags, - int reuse_addr) +ACE_SOCK_Dgram_Mcast::subscribe_i (const ACE_INET_Addr &mcast_addr, + int reuse_addr, + const ASYS_TCHAR *net_if, + int protocol_family, + int protocol) { - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open"); - - ACE_UNUSED_ARG (qos_params); + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_i"); // 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))); + this->mcast_addr_.set (mcast_addr); // Only perform the <open> initialization if we haven't been opened // earlier. @@ -104,9 +44,6 @@ ACE_SOCK_Dgram_Mcast::open (const ACE_Addr &mcast_addr, if (ACE_SOCK::open (SOCK_DGRAM, protocol_family, protocol, - protocolinfo, - g, - flags, reuse_addr) == -1) return -1; @@ -118,10 +55,10 @@ ACE_SOCK_Dgram_Mcast::open (const ACE_Addr &mcast_addr, sizeof one) == -1) return -1; #if defined (SO_REUSEPORT) - else if (this->ACE_SOCK::set_option (SOL_SOCKET, - SO_REUSEPORT, - &one, - sizeof one) == -1) + if (this->ACE_SOCK::set_option (SOL_SOCKET, + SO_REUSEPORT, + &one, + sizeof one) == -1) return -1; #endif /* SO_REUSEPORT */ @@ -134,18 +71,6 @@ ACE_SOCK_Dgram_Mcast::open (const ACE_Addr &mcast_addr, protocol_family) == -1) return -1; } - - return 0; -} - -int -ACE_SOCK_Dgram_Mcast::subscribe_ifs (const ACE_INET_Addr &mcast_addr, - const ASYS_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 @@ -214,109 +139,8 @@ ACE_SOCK_Dgram_Mcast::subscribe_ifs (const ACE_INET_Addr &mcast_addr, else return 1; } -#else - ACE_UNUSED_ARG (mcast_addr); - ACE_UNUSED_ARG (protocol_family); - ACE_UNUSED_ARG (protocol); - ACE_UNUSED_ARG (reuse_addr); + // else do it like everyone else... #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_ifs (const ACE_INET_Addr &mcast_addr, - const ACE_QoS_Params &qos_params, - const ASYS_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, - qos_params, - reuse_addr, - ASYS_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, - qos_params, - reuse_addr, - ASYS_WIDE_STRING (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 - return 1; - } -#else - ACE_UNUSED_ARG (mcast_addr); - ACE_UNUSED_ARG (qos_params); - 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_, @@ -333,28 +157,19 @@ ACE_SOCK_Dgram_Mcast::subscribe (const ACE_INET_Addr &mcast_addr, 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). - if (result != 0) - return result; - - // Create multicast request. - else if (this->make_multicast_address (this->mcast_addr_, - net_if) == -1) + int result = this->subscribe_i (mcast_addr, + reuse_addr, + net_if, + protocol_family, + protocol); + // Check for the error case. + if (result == -1) return -1; - +#if defined (ACE_WIN32) + // Check for the "short-circuit" return value (for NT). + else if (result == 1) + return 0; +#endif /* ACE_WIN32 */ // Tell network device driver to read datagrams with a // multicast_address IP interface. else if (this->ACE_SOCK::set_option (IPPROTO_IP, @@ -374,25 +189,22 @@ ACE_SOCK_Dgram_Mcast::subscribe (const ACE_INET_Addr &mcast_addr, int protocol_family, int protocol) { - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe"); - - if (this->open (mcast_addr, - protocol_family, - protocol, - reuse_addr) == -1) + int result = this->subscribe_i (mcast_addr, + reuse_addr, + net_if, + protocol_family, + protocol); + // Check for the error case. + if (result == -1) return -1; +#if defined (ACE_WIN32) + // @@ Note that this code is currently broken since <subscribe_i> + // calls the wrong version of subscribe recursively! - // The following method call only applies to Win32 currently. - int result = this->subscribe_ifs (mcast_addr, - qos_params, - net_if, - protocol_family, - protocol, - reuse_addr); - // Check for the "short-circuit" return value of 1 (for NT). - if (result != 0) - return result; - + // Check for the "short-circuit" return value (for NT). + else if (result == 1) + return 0; +#endif /* ACE_WIN32 */ // Tell network device driver to read datagrams with a // <mcast_request_if_> IP interface. else if (ACE_OS::join_leaf (this->get_handle (), @@ -412,12 +224,12 @@ ACE_SOCK_Dgram_Mcast::subscribe (const ACE_INET_Addr &mcast_addr, } int -ACE_SOCK_Dgram_Mcast::unsubscribe_ifs (const ACE_INET_Addr &mcast_addr, - const ASYS_TCHAR *net_if, - int protocol_family, - int protocol) +ACE_SOCK_Dgram_Mcast::unsubscribe_i (const ACE_INET_Addr &mcast_addr, + const ASYS_TCHAR *net_if, + int protocol_family, + int protocol) { - ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_ifs"); + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_i"); #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 @@ -481,14 +293,13 @@ ACE_SOCK_Dgram_Mcast::unsubscribe_ifs (const ACE_INET_Addr &mcast_addr, return 1; } -#else + // else do it like everyone else... +#endif /* ACE_WIN32 */ + 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, @@ -505,24 +316,27 @@ ACE_SOCK_Dgram_Mcast::unsubscribe (const ACE_INET_Addr &mcast_addr, 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; + int result = this->unsubscribe_i (mcast_addr, + net_if, + protocol_family, + protocol); - // Tell network device driver to stop reading datagrams with the - // <mcast_addr>. + // Check for error return and bail out. + if (result == -1) + return -1; +#if defined (ACE_WIN32) + // Check for the "short-circuit" return value (for NT). + else if (result == 1) + return 0; +#endif /* ACE_WIN32 */ + // Tell network device driver to read datagrams with a + // multicast_address address. 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; + return 0; } int @@ -551,7 +365,7 @@ ACE_SOCK_Dgram_Mcast::make_multicast_address_i (const ACE_INET_Addr &mcast_addr, multicast_address.imr_interface.s_addr = htonl (interface_addr.get_ip_address ()); #else - ifreq if_address; + struct ifreq if_address; #if defined (ACE_PSOS) // Look up the interface by number, not name. @@ -565,7 +379,7 @@ ACE_SOCK_Dgram_Mcast::make_multicast_address_i (const ACE_INET_Addr &mcast_addr, &if_address) == -1) return -1; - sockaddr_in *socket_address; + struct 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; |