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; }
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; }