#include <SOCK_Dgram_Mcast.h>
Inheritance diagram for ACE_SOCK_Dgram_Mcast:
Public Types | |
OPT_BINDADDR_NO = 0 | |
Disable address bind. (Bind only port.). | |
OPT_BINDADDR_YES = 1 | |
Enable address bind. (Bind port and address.). | |
DEFOPT_BINDADDR = OPT_BINDADDR_NO | |
Default value for BINDADDR option. (Environment-dependent.). | |
OPT_NULLIFACE_ONE = 0 | |
If (net_if==NULL), use default interface. | |
OPT_NULLIFACE_ALL = 2 | |
If (net_if==NULL), use all mcast interfaces. | |
DEFOPT_NULLIFACE = OPT_NULLIFACE_ONE | |
Default value for NULLIFACE option. (Environment-dependent.). | |
DEFOPTS = DEFOPT_BINDADDR | DEFOPT_NULLIFACE | |
All default options. | |
enum | options { OPT_BINDADDR_NO = 0, OPT_BINDADDR_YES = 1, DEFOPT_BINDADDR = OPT_BINDADDR_NO, OPT_NULLIFACE_ONE = 0, OPT_NULLIFACE_ALL = 2, DEFOPT_NULLIFACE = OPT_NULLIFACE_ONE, DEFOPTS = DEFOPT_BINDADDR | DEFOPT_NULLIFACE } |
Option parameters. More... | |
Public Member Functions | |
ACE_SOCK_Dgram_Mcast (options opts=DEFOPTS) | |
~ACE_SOCK_Dgram_Mcast (void) | |
int | open (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0, int reuse_addr=1) |
int | join (const ACE_INET_Addr &mcast_addr, int reuse_addr=1, const ACE_TCHAR *net_if=0) |
int | leave (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0) |
ssize_t | send (const void *buf, size_t n, int flags=0) const |
ssize_t | send (const iovec iov[], int n, int flags=0) const |
int | set_option (int option, char optval) |
Set a socket option. | |
void | dump (void) const |
Dump the state of an object. | |
Public Attributes | |
ACE_ALLOC_HOOK_DECLARE | |
Declare the dynamic allocation hooks. | |
Protected Member Functions | |
int | open_i (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0, int reuse_addr=1) |
int | clear_subs_list (void) |
Empty the dynamic subscription list. | |
Private Member Functions | |
int | subscribe_ifs (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if, int reuse_addr) |
int | subscribe_i (const ACE_INET_Addr &mcast_addr, int reuse_addr=1, const ACE_TCHAR *net_if=0) |
Do subscription processing w/out updating the subscription list. | |
int | unsubscribe_ifs (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0) |
Unsubscribe from a multicast address on one or more network interface(s). | |
int | unsubscribe_i (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0) |
Do unsubscription processing w/out udpating subscription list. | |
Private Attributes | |
int | opts_ |
Per-instance options.. | |
ACE_INET_Addr | send_addr_ |
Multicast address to which local <send> methods send datagrams. | |
ACE_TCHAR * | send_net_if_ |
Network interface to which all <send> methods send multicast datagrams. |
Supports multiple simultaneous subscriptions, unsubscription from one or all subscriptions, and independent send/recv address and interface specifications. Template parameters and/or ctor arguments determine per-instance optional functionality.
Note that multicast semantics and implementation details are _very_ environment-specific; this class is just a wrapper around the underlying implementation and does not try to normalize the concept of multicast communications.
Usage Notes:
Interface specification notes (for <subscribe> and <unsubscribe>):
Definition at line 94 of file SOCK_Dgram_Mcast.h.
Option parameters.
These control per-instance optional functionality. They are set via optional constructor arguments.
Definition at line 107 of file SOCK_Dgram_Mcast.h.
00108 { 00109 // Define whether a specific (multicast) address (in addition to the port#) 00110 // is bound to the socket. 00111 // Notes: 00112 // - Effect of doing this is stack/environment dependent, but in most 00113 // environments can be used to filter out unwanted unicast, broadcast, and 00114 // (other) multicast messages sent to the same port#. 00115 // - Some IP stacks (e.g. some Win32) do not support binding multicast 00116 // addresses. Using this option will always cause an <open> error. 00117 // - It's not strictly possible for user code to do this level of filtering 00118 // w/out the bind; some environments support ways to determine which address 00119 // a message was sent _to_, but this class interface does not support access 00120 // to that info. 00121 // - The address (and port#) passed to <open> (or the first <subscribe>, if 00122 // <open> is not explicitly invoked) is the one that is bound. 00123 // 00124 /// Disable address bind. (Bind only port.) 00125 // Note that this might seem odd, but we need a way to distinquish between 00126 // default behavior, which might or might not be to bind, and explicitely 00127 // choosing to bind or not to bind--which "is the question." ;-) 00128 OPT_BINDADDR_NO = 0, 00129 /// Enable address bind. (Bind port and address.) 00130 OPT_BINDADDR_YES = 1, 00131 /// Default value for BINDADDR option. (Environment-dependent.) 00132 #if defined (ACE_LACKS_PERFECT_MULTICAST_FILTERING) \ 00133 && (ACE_LACKS_PERFECT_MULTICAST_FILTERING == 1) 00134 // Platforms that don't support perfect filtering. Note that perfect 00135 // filtering only really applies to multicast traffic, not unicast 00136 // or broadcast. 00137 DEFOPT_BINDADDR = OPT_BINDADDR_YES, 00138 # else 00139 // At least some Win32 OS's can not bind mcast addr, so disable it. 00140 // General-purpose default behavior is 'disabled', since effect is 00141 // environment-specific and side-effects might be surprising. 00142 DEFOPT_BINDADDR = OPT_BINDADDR_NO, 00143 #endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING = 1) */ 00144 // 00145 /// Define the interpretation of 'NULL' as a recv interface specification. 00146 // If the interface part of a multicast address specification is NULL, it 00147 // will be interpreted to mean either "the default interface" or "all 00148 // interfaces", depending on the setting of this option. 00149 // Notes: 00150 // - The 'nulliface_all' option can not be used in environments which do 00151 // not fully support the <ACE_Sock_Connect::get_ip_interfaces> method 00152 // (e.g. non-Windows). 00153 // If it is, using NULL for iface will _always_ fail. 00154 // - The default behavior in most IP stacks is to use the 'default' interface, 00155 // where 'default' has rather ad-hoc semantics. 00156 // - This applies only to receives, not sends (which always use only one 00157 // interface; NULL means use the "system default" interface). 00158 // Supported values: 00159 /// If (net_if==NULL), use default interface. 00160 // Note that this might seem odd, but we need a way to distinquish between 00161 // default behavior, which might or might not be to bind, and explicitely 00162 // choosing to bind or not to bind--which "is the question." ;-) 00163 OPT_NULLIFACE_ONE = 0, 00164 /// If (net_if==NULL), use all mcast interfaces. 00165 OPT_NULLIFACE_ALL = 2, 00166 /// Default value for NULLIFACE option. (Environment-dependent.) 00167 #ifdef ACE_WIN32 00168 // This is the (ad-hoc) legacy behavior for Win32/WinSock. 00169 // Notice: Older version of WinSock/MSVC may not get all multicast-capable 00170 // interfaces (e.g. PPP interfaces). 00171 DEFOPT_NULLIFACE = OPT_NULLIFACE_ALL, 00172 #else 00173 // General-purpose default behavior (as per legacy behavior). 00174 DEFOPT_NULLIFACE = OPT_NULLIFACE_ONE, 00175 #endif /* ACE_WIN32 */ 00176 /// All default options. 00177 DEFOPTS = DEFOPT_BINDADDR | DEFOPT_NULLIFACE 00178 };
ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast | ( | options | opts = DEFOPTS |
) |
You must invoke <open> or <subscribe>, to create/bind a socket and define operational parameters, before performing any I/O with this instance.
Definition at line 133 of file SOCK_Dgram_Mcast.cpp.
References ACE_TRACE.
00134 : opts_ (opts), 00135 send_net_if_ (0) 00136 { 00137 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast"); 00138 }
ACE_SOCK_Dgram_Mcast::~ACE_SOCK_Dgram_Mcast | ( | void | ) |
The OPT_DTORUNSUB_YES_ option defines whether an explicit <unsusbcribe> is done by the destructor. If not, most systems will automatically unsubscribe upon the close of the socket.
Definition at line 141 of file SOCK_Dgram_Mcast.cpp.
References ACE_TRACE, clear_subs_list(), and send_net_if_.
00142 { 00143 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::~ACE_SOCK_Dgram_Mcast"); 00144 00145 // Free memory and optionally unsubscribe from currently subscribed group(s). 00146 delete [] this->send_net_if_; 00147 this->clear_subs_list (); 00148 }
int ACE_SOCK_Dgram_Mcast::clear_subs_list | ( | void | ) | [protected] |
Empty the dynamic subscription list.
Definition at line 909 of file SOCK_Dgram_Mcast.cpp.
References ACE_GUARD_RETURN, and ACE_TRACE.
Referenced by ~ACE_SOCK_Dgram_Mcast().
00910 { 00911 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::clear_subs_list"); 00912 int result = 0; 00913 00914 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) 00915 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard, 00916 this->subscription_list_lock_, -1)); 00917 subscription_list_iter_t iter (this->subscription_list_); 00918 for (; !iter.done (); /*Hack: Do _not_ ::advance after remove*/) 00919 { 00920 ip_mreq *pm = iter.next (); 00921 iter.remove (); 00922 delete pm; 00923 } 00924 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ 00925 return result; 00926 }
void ACE_SOCK_Dgram_Mcast::dump | ( | void | ) | const |
Dump the state of an object.
Logs the setting of all options, the bound address, the send address and interface, and the list of current subscriptions.
Reimplemented from ACE_SOCK_Dgram.
Definition at line 68 of file SOCK_Dgram_Mcast.cpp.
References ACE_BEGIN_DUMP, ACE_BIT_ENABLED, ACE_DEBUG, ACE_END_DUMP, ACE_GUARD, ACE_NTOHL, ACE_TEXT, ACE_TRACE, ACE_SDM_helpers::addr_to_string(), LM_DEBUG, MAXNAMELEN, ACE_OS::strcmp(), and ACE_OS::strcpy().
00069 { 00070 #if defined (ACE_HAS_DUMP) 00071 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::dump"); 00072 00073 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); 00074 00075 # if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) 00076 ACE_TCHAR addr_string[MAXNAMELEN + 1]; 00077 00078 ACE_DEBUG ((LM_DEBUG, 00079 ACE_TEXT ("\nOptions: bindaddr=%s, nulliface=%s\n"), 00080 ACE_BIT_ENABLED (this->opts_, OPT_BINDADDR_YES) ? 00081 ACE_TEXT ("<Bound>") : ACE_TEXT ("<Not Bound>"), 00082 ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL) ? 00083 ACE_TEXT ("<All Ifaces>") : ACE_TEXT ("<Default Iface>"))); 00084 00085 // Show default send addr, port#, and interface. 00086 ACE_SDM_helpers::addr_to_string (this->send_addr_, addr_string, 00087 sizeof addr_string, 0); 00088 ACE_DEBUG ((LM_DEBUG, 00089 ACE_TEXT ("Send addr=%s iface=%s\n"), 00090 addr_string, 00091 this->send_net_if_ ? this->send_net_if_ 00092 : ACE_TEXT ("<default>"))); 00093 00094 // Show list of subscribed addresses. 00095 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Subscription list:\n"))); 00096 00097 ACE_MT (ACE_GUARD (ACE_SDM_LOCK, guard, this->subscription_list_lock_)); 00098 subscription_list_iter_t iter (this->subscription_list_); 00099 for ( ; !iter.done (); iter.advance ()) 00100 { 00101 ACE_TCHAR iface_string[MAXNAMELEN + 1]; 00102 ip_mreq *pm = iter.next (); 00103 00104 // Get subscribed address (w/out port# info - not relevant). 00105 ACE_INET_Addr ip_addr (static_cast<u_short> (0), 00106 ACE_NTOHL (pm->IMR_MULTIADDR.s_addr)); 00107 ACE_SDM_helpers::addr_to_string (ip_addr, addr_string, 00108 sizeof addr_string, 1); 00109 00110 // Get interface address/specification. 00111 ACE_INET_Addr if_addr (static_cast<u_short> (0), 00112 ACE_NTOHL (pm->imr_interface.s_addr)); 00113 ACE_SDM_helpers::addr_to_string (if_addr, iface_string, 00114 sizeof iface_string, 1); 00115 if (ACE_OS::strcmp (iface_string, ACE_TEXT ("0.0.0.0")) == 0) 00116 // Receives on system default iface. (Note that null_iface_opt_ 00117 // option processing has already occurred.) 00118 ACE_OS::strcpy (iface_string, ACE_TEXT ("<default>")); 00119 00120 // Dump info. 00121 ACE_DEBUG ((LM_DEBUG, 00122 ACE_TEXT ("\taddr=%s iface=%s\n"), 00123 addr_string, 00124 iface_string)); 00125 } 00126 # endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ 00127 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); 00128 #endif /* ACE_HAS_DUMP */ 00129 }
int ACE_SOCK_Dgram_Mcast::join | ( | const ACE_INET_Addr & | mcast_addr, | |
int | reuse_addr = 1 , |
|||
const ACE_TCHAR * | net_if = 0 | |||
) |
The given group is joined on the specified interface. If option OPT_NULLIFACE_ALL is used and <net_if> is = 0, the group is joined on all multicast capable interfaces (IFF supported). Multiple subscriptions to various address and interface combinations are supported and tracked. If this is the first invocation of <subscribe>, and <open> was not previously invoked, <open> will be invoked using <mcast_addr> for binding the socket and <net_if> as the interface for <send>.
Returns: -1 if the call fails. Failure can occur due to problems with the address, port#, and/or interface parameters or during the subscription attempt. Once bind() has been invoked (by the first <open> or <subscribe>), returns errno of ENXIO if the port# is not 0 and does not match the bound port#, or if OPT_BINDADDR_YES option is used and the address does not match the bound address. Returns errno of ENODEV if the addr/port#/interface parameters appeared valid, but no subscription(s) succeeded. An error is unconditionally returned if option OPT_NULLIFACE_ALL is used, <net_if> is NULL, and <ACE_Sock_Connect::get_ip_interfaces> is not implemented in this environment.
Note that the optional reuse_addr parameter does not apply to subscriptions; it is only used if <open> is implicitly invoked (see above).
Uses the mcast_addr to determine protocol_family, and protocol which we always pass as 0 anyway.
Definition at line 466 of file SOCK_Dgram_Mcast.cpp.
References ACE_BIT_ENABLED, ACE_ERROR, ACE_GUARD_RETURN, ACE_TEXT, ACE_TRACE, ACE_SDM_helpers::addr_to_string(), ENXIO, ACE_INET_Addr::get_port_number(), LM_ERROR, MAXNAMELEN, OPT_BINDADDR_YES, send_addr_, ACE_INET_Addr::set_port_number(), and subscribe_i().
00469 { 00470 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::join"); 00471 ACE_INET_Addr subscribe_addr = mcast_addr; 00472 00473 // If port# is 0, insert bound port# if it is set. (To satisfy lower-level 00474 // port# validation.) 00475 u_short def_port_number = this->send_addr_.get_port_number (); 00476 if (subscribe_addr.get_port_number () == 0 00477 && def_port_number != 0) 00478 { 00479 subscribe_addr.set_port_number (def_port_number); 00480 } 00481 00482 // Check for port# different than bound port#. 00483 u_short sub_port_number = mcast_addr.get_port_number (); 00484 if (sub_port_number != 0 00485 && def_port_number != 0 00486 && sub_port_number != def_port_number) 00487 { 00488 ACE_ERROR ((LM_ERROR, 00489 ACE_TEXT ("Subscribed port# (%u) different than bound ") 00490 ACE_TEXT ("port# (%u).\n"), 00491 (u_int) sub_port_number, 00492 (u_int) def_port_number)); 00493 errno = ENXIO; 00494 return -1; 00495 } 00496 00497 // If bind_addr_opt_ is enabled, check for address different than 00498 // bound address. 00499 ACE_INET_Addr tmp_addr (this->send_addr_); 00500 tmp_addr.set_port_number (mcast_addr.get_port_number ()); // force equal port numbers 00501 if (ACE_BIT_ENABLED (this->opts_, OPT_BINDADDR_YES) 00502 && !this->send_addr_.is_any () 00503 && this->send_addr_ != mcast_addr) 00504 { 00505 ACE_TCHAR sub_addr_string[MAXNAMELEN + 1]; 00506 ACE_TCHAR bound_addr_string[MAXNAMELEN + 1]; 00507 ACE_SDM_helpers::addr_to_string (mcast_addr, sub_addr_string, 00508 sizeof sub_addr_string, 1); 00509 ACE_SDM_helpers::addr_to_string (this->send_addr_, bound_addr_string, 00510 sizeof bound_addr_string, 1); 00511 ACE_ERROR ((LM_ERROR, 00512 ACE_TEXT ("Subscribed address (%s) different than ") 00513 ACE_TEXT ("bound address (%s).\n"), 00514 sub_addr_string, 00515 bound_addr_string)); 00516 errno = ENXIO; 00517 return -1; 00518 } 00519 00520 // Attempt subscription. 00521 int result = this->subscribe_i (subscribe_addr, reuse_addr, net_if); 00522 00523 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) 00524 if (result == 0) 00525 { 00526 // Add this addr/iface info to the list of subscriptions. 00527 // (Assumes this is unique addr/iface combo - most systems don't allow 00528 // re-sub to same addr/iface.) 00529 ip_mreq *pmreq = new ip_mreq; 00530 // (should not fail) 00531 if (this->make_multicast_ifaddr (pmreq, subscribe_addr, net_if) != -1) 00532 { 00533 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard, 00534 this->subscription_list_lock_, -1)); 00535 this->subscription_list_.insert_tail (pmreq); 00536 return 0; 00537 } 00538 // this still isn't really right. If ACE_GUARD_RETURN fails, we leak. 00539 // Need to add one of Chris' fancy ace auto pointers (bound?). 00540 delete pmreq; 00541 } 00542 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ 00543 00544 return result >= 0 ? 0 : result; 00545 }
int ACE_SOCK_Dgram_Mcast::leave | ( | const ACE_INET_Addr & | mcast_addr, | |
const ACE_TCHAR * | net_if = 0 | |||
) |
The specified group/interface combination is unsubscribed. If option OPT_NULLIFACE_ALL is used and <net_if> is = 0, the group is unsubscribed from all interfaces (IFF supported).
Returns: -1 if the unsubscribe failed. Most environments will return -1 if there was no active subscription for this address/interface combination. An error is unconditionally returned if option OPT_NULLIFACE_ALL is used, <net_if> is = 0, and <ACE_Sock_Connect::get_ip_interfaces> is not implemented in this environment (_even if_ the <subscribe> specifies a non- NULL <net_if>).
leave() replaces unsubscribe() and uses mcast_addr to determine protocol_family, and protocol which we always pass as 0 anyway.
Definition at line 798 of file SOCK_Dgram_Mcast.cpp.
References ACE_GUARD_RETURN, ACE_TRACE, ACE_SDM_helpers::is_equal(), and unsubscribe_i().
00800 { 00801 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::leave"); 00802 // Unsubscribe. 00803 int result = this->unsubscribe_i (mcast_addr, 00804 net_if); 00805 00806 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) 00807 // (Unconditionally) Remove this addr/if from subscription list. 00808 // (Addr/if is removed even if unsubscribe failed) 00809 ip_mreq tgt_mreq; 00810 if (this->make_multicast_ifaddr (&tgt_mreq, 00811 mcast_addr, 00812 net_if) != -1) 00813 { 00814 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard, 00815 this->subscription_list_lock_, -1)); 00816 subscription_list_iter_t iter (this->subscription_list_); 00817 for (; !iter.done (); iter.advance ()) 00818 { 00819 ip_mreq *pm = iter.next (); 00820 if (ACE_SDM_helpers::is_equal (*pm, tgt_mreq)) 00821 { 00822 iter.remove (); 00823 delete pm; 00824 break; 00825 } 00826 } 00827 } 00828 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ 00829 00830 return result >= 0 ? 0 : result; 00831 }
int ACE_SOCK_Dgram_Mcast::open | ( | const ACE_INET_Addr & | mcast_addr, | |
const ACE_TCHAR * | net_if = 0 , |
|||
int | reuse_addr = 1 | |||
) |
This method is optional; if not explicitly invoked, it is invoked by the first <subscribe>, using the subscribed address/port# and network interface paramters. The <mcast_addr> parameter defines the default send address/port# and also the port# and, if the OPT_BINDADDR_YES option is used, the multicast address that is bound to this socket. If the <send_net_if> parameter != 0, it defines the network interface used for all sends by this instance, otherwise the system "default" interface is used. (The <send_net_if> parameter is ignored if this feature is not supported by the envriornment.) The port# in <mcast_addr> may be 0, in which case a system-assigned (ephemeral) port# is used for sending and receiving. If reuse_addr != 0, the SO_REUSEADDR option and, if it is supported, the SO_REUSEPORT option are enabled.
Returns: -1 if the call fails. Failure can occur due to problems with the address, port#, and/or interface parameters or during system open() or socket option processing.
Definition at line 151 of file SOCK_Dgram_Mcast.cpp.
References ACE_TRACE, ACE_Addr::get_type(), ACE_SOCK::open(), open_i(), and SOCK_DGRAM.
00154 { 00155 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open"); 00156 00157 // Only perform the <open> initialization if we haven't been opened 00158 // earlier. 00159 // No sanity check? We should probably flag an error if the user 00160 // makes multiple calls to open(). 00161 if (this->get_handle () != ACE_INVALID_HANDLE) 00162 return 0; 00163 00164 // Invoke lower-layer ::open. 00165 if (ACE_SOCK::open (SOCK_DGRAM, 00166 mcast_addr.get_type (), 00167 0, // always use 0 00168 reuse_addr) == -1) 00169 return -1; 00170 00171 return this->open_i (mcast_addr, net_if, reuse_addr); 00172 }
int ACE_SOCK_Dgram_Mcast::open_i | ( | const ACE_INET_Addr & | mcast_addr, | |
const ACE_TCHAR * | net_if = 0 , |
|||
int | reuse_addr = 1 | |||
) | [protected] |
Contains common open functionality so that inheriting classes can reuse it.
Definition at line 175 of file SOCK_Dgram_Mcast.cpp.
References ACE_BIT_DISABLED, ACE_TRACE, ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), OPT_BINDADDR_YES, send_addr_, send_net_if_, ACE_INET_Addr::set(), ACE_INET_Addr::set_port_number(), ACE_SOCK_Dgram::shared_open(), SOL_SOCKET, ACE_OS::strcpy(), and ACE_OS::strlen().
Referenced by open().
00178 { 00179 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open_i"); 00180 // ACE_SOCK::open calls this if reuse_addr is set, so we only need to 00181 // process port reuse option. 00182 if (reuse_addr) 00183 { 00184 #if defined (SO_REUSEPORT) 00185 int one = 1; 00186 if (this->ACE_SOCK::set_option (SOL_SOCKET, 00187 SO_REUSEPORT, 00188 &one, 00189 sizeof one) == -1) 00190 return -1; 00191 #endif /* SO_REUSEPORT */ 00192 } 00193 00194 // Create an address/port# to bind the socket to. Use mcast_addr to 00195 // initialize bind_addy to pick up the correct protocol family. If 00196 // OPT_BINDADDR_YES is set, then we're done. Else use mcast_addr's 00197 // port number and use the "any" address. 00198 ACE_INET_Addr bind_addy (mcast_addr); 00199 if (ACE_BIT_DISABLED (this->opts_, OPT_BINDADDR_YES)) 00200 { 00201 #if defined (ACE_HAS_IPV6) 00202 if (mcast_addr.get_type () == PF_INET6) 00203 { 00204 if (bind_addy.set (mcast_addr.get_port_number (), "::", 00205 1, AF_INET6) == -1) 00206 return -1; 00207 } 00208 else 00209 // Bind to "any" address and explicit port#. 00210 if (bind_addy.set (mcast_addr.get_port_number ()) == -1) 00211 return -1; 00212 #else 00213 // Bind to "any" address and explicit port#. 00214 if (bind_addy.set (mcast_addr.get_port_number ()) == -1) 00215 return -1; 00216 #endif /* ACE_HAS_IPV6 */ 00217 } 00218 00219 // Bind to the address (which may be INADDR_ANY) and port# (which may be 0) 00220 if (ACE_SOCK_Dgram::shared_open (bind_addy, bind_addy.get_type ()) == -1) 00221 return -1; 00222 00223 // Cache the actual bound address (which may be INADDR_ANY) 00224 // and the actual bound port# (which will be a valid, non-zero port#). 00225 ACE_INET_Addr bound_addy; 00226 if (this->get_local_addr (bound_addy) == -1) 00227 { 00228 // (Unexpected failure - should be bound to something) 00229 if (bound_addy.set (bind_addy) == -1) 00230 { 00231 // (Shouldn't happen - bind_addy is a valid addy; punt.) 00232 return -1; 00233 } 00234 } 00235 00236 this->send_addr_ = mcast_addr; 00237 this->send_addr_.set_port_number (bound_addy.get_port_number ()); 00238 if (net_if) 00239 { 00240 if (this->set_nic (net_if, mcast_addr.get_type ())) 00241 return -1; 00242 00243 this->send_net_if_ = new ACE_TCHAR[ACE_OS::strlen (net_if) + 1]; 00244 ACE_OS::strcpy (this->send_net_if_, net_if); 00245 } 00246 00247 return 0; 00248 }
ACE_INLINE ssize_t ACE_SOCK_Dgram_Mcast::send | ( | const iovec | iov[], | |
int | n, | |||
int | flags = 0 | |||
) | const |
Send n <iovecs>, using the multicast address and network interface defined by the first <open> or <subscribe>.
Definition at line 41 of file SOCK_Dgram_Mcast.inl.
References ACE_TRACE, and ACE_SOCK_Dgram::send().
00044 { 00045 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::send"); 00046 return this->ACE_SOCK_Dgram::send (iov, 00047 n, 00048 this->send_addr_, 00049 flags); 00050 }
ACE_INLINE ssize_t ACE_SOCK_Dgram_Mcast::send | ( | const void * | buf, | |
size_t | n, | |||
int | flags = 0 | |||
) | const |
Send n bytes in buf, using the multicast address and network interface defined by the first <open> or <subscribe>.
Definition at line 29 of file SOCK_Dgram_Mcast.inl.
References ACE_TRACE, and ACE_SOCK_Dgram::send().
00032 { 00033 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::send"); 00034 return this->ACE_SOCK_Dgram::send (buf, 00035 n, 00036 this->send_addr_, 00037 flags); 00038 }
ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE int ACE_SOCK_Dgram_Mcast::set_option | ( | int | option, | |
char | optval | |||
) |
Set a socket option.
Set an IP option that takes a char as input, such as IP_MULTICAST_LOOP or IP_MULTICAST_TTL. This is just a more concise, nice interface to a subset of possible ACE_SOCK::set_option calls, but only works for IPPROTO_IP or IPPROTO_IPV6 level options.
Returns 0 on success, -1 on failure.
Definition at line 8 of file SOCK_Dgram_Mcast.inl.
References ACE_TRACE, IPPROTO_IP, and ACE_SOCK::set_option().
00010 { 00011 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::set_option"); 00012 00013 if (this->get_handle () == ACE_INVALID_HANDLE) 00014 return -1; 00015 00016 int level = IPPROTO_IP; 00017 #if defined (IPPROTO_IPV6) && ! defined (INTEGRITY) 00018 if (this->send_addr_.get_type () == PF_INET6) 00019 level = IPPROTO_IPV6; 00020 #endif /* IPPROTO_IPV6 */ 00021 00022 return this->ACE_SOCK::set_option (level, 00023 option, 00024 &optval, 00025 sizeof (optval)); 00026 }
int ACE_SOCK_Dgram_Mcast::subscribe_i | ( | const ACE_INET_Addr & | mcast_addr, | |
int | reuse_addr = 1 , |
|||
const ACE_TCHAR * | net_if = 0 | |||
) | [private] |
Do subscription processing w/out updating the subscription list.
Definition at line 549 of file SOCK_Dgram_Mcast.cpp.
References ACE_TRACE, ACE_Addr::get_type(), IP_ADD_MEMBERSHIP, IPPROTO_IP, and subscribe_ifs().
Referenced by join().
00552 { 00553 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_i"); 00554 ip_mreq mreq; 00555 #if defined (ACE_HAS_IPV6) 00556 ipv6_mreq mreq6; 00557 #endif /* __linux__ && ACE_HAS_IPV6 */ 00558 00559 // Open the socket IFF this is the first ::subscribe and ::open 00560 // was not explicitly invoked. 00561 if (this->open (mcast_addr, 00562 net_if, 00563 reuse_addr) == -1) 00564 return -1; 00565 00566 // Only do this if net_if == 0, i.e., INADDR_ANY 00567 if (net_if == 0) 00568 { 00569 int result = this->subscribe_ifs (mcast_addr, 00570 net_if, 00571 reuse_addr); 00572 // Check for error or "short-circuit" return. 00573 if (result != 0) 00574 return result; 00575 } 00576 00577 #if defined (ACE_HAS_IPV6) 00578 if (mcast_addr.get_type () == AF_INET6) 00579 { 00580 if (this->make_multicast_ifaddr6 (&mreq6, mcast_addr, net_if) == -1) 00581 return -1; 00582 // Tell IP stack to pass messages sent to this group. 00583 else if (this->ACE_SOCK::set_option (IPPROTO_IPV6, 00584 IPV6_JOIN_GROUP, 00585 &mreq6, 00586 sizeof mreq6) == -1) 00587 return -1; 00588 00589 return 0; 00590 } 00591 // Fall through for IPv4 case 00592 #endif /* ACE_HAS_IPV6 */ 00593 00594 // Create multicast addr/if struct. 00595 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1) 00596 return -1; 00597 // Tell IP stack to pass messages sent to this group. 00598 else if (this->ACE_SOCK::set_option (IPPROTO_IP, 00599 IP_ADD_MEMBERSHIP, 00600 &mreq, 00601 sizeof mreq) == -1) 00602 return -1; 00603 00604 return 0; 00605 }
int ACE_SOCK_Dgram_Mcast::subscribe_ifs | ( | const ACE_INET_Addr & | mcast_addr, | |
const ACE_TCHAR * | net_if, | |||
int | reuse_addr | |||
) | [private] |
Subscribe to a multicast address on one or more network interface(s). (No QoS support.)
Definition at line 251 of file SOCK_Dgram_Mcast.cpp.
References ACE_BIT_ENABLED, ACE_NEW_RETURN, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, AF_INET, ACE::get_ip_interfaces(), ACE_Addr::get_type(), and OPT_NULLIFACE_ALL.
Referenced by subscribe_i().
00254 { 00255 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_ifs"); 00256 00257 if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL) 00258 && net_if == 0) 00259 { 00260 #if defined (ACE_HAS_IPV6) 00261 if (mcast_addr.get_type () == AF_INET6) 00262 { 00263 size_t nr_subscribed = 0; 00264 # if defined(__linux__) 00265 struct if_nameindex *intf; 00266 00267 intf = ACE_OS::if_nameindex (); 00268 00269 if (intf == 0) 00270 return -1; 00271 00272 int index = 0; 00273 while (intf[index].if_index != 0 || intf[index].if_name != 0) 00274 { 00275 if (this->join (mcast_addr, reuse_addr, 00276 ACE_TEXT_CHAR_TO_TCHAR(intf[index].if_name)) == 0) 00277 ++nr_subscribed; 00278 00279 ++index; 00280 } 00281 00282 ACE_OS::if_freenameindex (intf); 00283 00284 # elif defined (ACE_WIN32) 00285 00286 IP_ADAPTER_ADDRESSES tmp_addrs; 00287 // Initial call to determine actual memory size needed 00288 DWORD dwRetVal; 00289 ULONG bufLen = 0; 00290 if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6, 00291 0, 00292 0, 00293 &tmp_addrs, 00294 &bufLen)) != ERROR_BUFFER_OVERFLOW) 00295 return -1; // With output bufferlength 0 this can't be right. 00296 00297 // Get required output buffer and retrieve info for real. 00298 PIP_ADAPTER_ADDRESSES pAddrs; 00299 char *buf; 00300 ACE_NEW_RETURN (buf, 00301 char[bufLen], 00302 -1); 00303 pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf); 00304 if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6, 00305 0, 00306 0, 00307 pAddrs, 00308 &bufLen)) != NO_ERROR) 00309 { 00310 delete[] buf; // clean up 00311 return -1; 00312 } 00313 00314 while (pAddrs) 00315 { 00316 if (this->join (mcast_addr, reuse_addr, 00317 ACE_TEXT_CHAR_TO_TCHAR(pAddrs->AdapterName)) == 0) 00318 ++nr_subscribed; 00319 00320 pAddrs = pAddrs->Next; 00321 } 00322 00323 delete[] buf; // clean up 00324 00325 # endif /* ACE_WIN32 */ 00326 00327 if (nr_subscribed == 0) 00328 { 00329 errno = ENODEV; 00330 return -1; 00331 } 00332 00333 return 1; 00334 } 00335 else 00336 { 00337 // Subscribe on all local multicast-capable network interfaces, by 00338 // doing recursive calls with specific interfaces. 00339 00340 ACE_INET_Addr *if_addrs = 0; 00341 size_t if_cnt; 00342 00343 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0) 00344 return -1; 00345 00346 size_t nr_subscribed = 0; 00347 00348 if (if_cnt < 2) 00349 { 00350 if (this->join (mcast_addr, 00351 reuse_addr, 00352 ACE_TEXT ("0.0.0.0")) == 0) 00353 ++nr_subscribed; 00354 } 00355 else 00356 { 00357 // Iterate through all the interfaces, figure out which ones 00358 // offer multicast service, and subscribe to them. 00359 while (if_cnt > 0) 00360 { 00361 --if_cnt; 00362 00363 // Convert to 0-based for indexing, next loop check. 00364 if (if_addrs[if_cnt].get_type () != AF_INET || if_addrs[if_cnt].is_loopback ()) 00365 continue; 00366 if (this->join (mcast_addr, 00367 reuse_addr, 00368 ACE_TEXT_CHAR_TO_TCHAR 00369 (if_addrs[if_cnt].get_host_addr ())) == 0) 00370 ++nr_subscribed; 00371 } 00372 } 00373 00374 delete [] if_addrs; 00375 00376 if (nr_subscribed == 0) 00377 { 00378 errno = ENODEV; 00379 return -1; 00380 } 00381 00382 // 1 indicates a "short-circuit" return. This handles the 00383 // recursive behavior of checking all the interfaces. 00384 return 1; 00385 00386 } 00387 #else 00388 // Subscribe on all local multicast-capable network interfaces, by 00389 // doing recursive calls with specific interfaces. 00390 00391 ACE_INET_Addr *if_addrs = 0; 00392 size_t if_cnt; 00393 00394 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0) 00395 return -1; 00396 00397 size_t nr_subscribed = 0; 00398 00399 if (if_cnt < 2) 00400 { 00401 if (this->join (mcast_addr, 00402 reuse_addr, 00403 ACE_TEXT ("0.0.0.0")) == 0) 00404 ++nr_subscribed; 00405 } 00406 else 00407 { 00408 // Iterate through all the interfaces, figure out which ones 00409 // offer multicast service, and subscribe to them. 00410 while (if_cnt > 0) 00411 { 00412 --if_cnt; 00413 00414 // Convert to 0-based for indexing, next loop check. 00415 if (if_addrs[if_cnt].is_loopback ()) 00416 continue; 00417 if (this->join (mcast_addr, 00418 reuse_addr, 00419 ACE_TEXT_CHAR_TO_TCHAR 00420 (if_addrs[if_cnt].get_host_addr ())) == 0) 00421 ++nr_subscribed; 00422 } 00423 } 00424 00425 delete [] if_addrs; 00426 00427 if (nr_subscribed == 0) 00428 { 00429 errno = ENODEV; 00430 return -1; 00431 } 00432 00433 // 1 indicates a "short-circuit" return. This handles the 00434 // recursive behavior of checking all the interfaces. 00435 return 1; 00436 #endif /* ACE_HAS_IPV6 */ 00437 } 00438 00439 #if defined (ACE_HAS_IPV6) 00440 if (mcast_addr.get_type () == AF_INET6) 00441 { 00442 if (this->make_multicast_ifaddr6 (0, mcast_addr, net_if) == -1) 00443 return -1; 00444 } 00445 else 00446 { 00447 // Validate passed multicast addr and iface specifications. 00448 if (this->make_multicast_ifaddr (0, 00449 mcast_addr, 00450 net_if) == -1) 00451 return -1; 00452 } 00453 #else 00454 // Validate passed multicast addr and iface specifications. 00455 if (this->make_multicast_ifaddr (0, 00456 mcast_addr, 00457 net_if) == -1) 00458 return -1; 00459 #endif /* ACE_HAS_IPV6 */ 00460 00461 return 0; 00462 00463 }
int ACE_SOCK_Dgram_Mcast::unsubscribe_i | ( | const ACE_INET_Addr & | mcast_addr, | |
const ACE_TCHAR * | net_if = 0 | |||
) | [private] |
Do unsubscription processing w/out udpating subscription list.
Definition at line 835 of file SOCK_Dgram_Mcast.cpp.
References ACE_TRACE, ACE_Addr::get_type(), IP_DROP_MEMBERSHIP, IPPROTO_IP, ACE_SOCK::set_option(), and unsubscribe_ifs().
Referenced by leave().
00837 { 00838 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_i"); 00839 00840 int result = this->unsubscribe_ifs (mcast_addr, 00841 net_if); 00842 00843 // Check for error or "short-circuit" return. 00844 if (result != 0) 00845 return result; 00846 00847 #if defined (ACE_HAS_IPV6) 00848 if (mcast_addr.get_type () == AF_INET6) 00849 { 00850 // Validate addr/if specifications and create addr/if struct. 00851 ipv6_mreq mreq; 00852 if (this->make_multicast_ifaddr6 (&mreq, mcast_addr, net_if) == -1) 00853 { 00854 return -1; 00855 } 00856 // Tell network device driver to stop reading datagrams with the 00857 // <mcast_addr>. 00858 else if (ACE_SOCK::set_option (IPPROTO_IPV6, 00859 IPV6_LEAVE_GROUP, 00860 &mreq, 00861 sizeof mreq) == -1) 00862 { 00863 return -1; 00864 } 00865 00866 } 00867 else // IPv4 00868 { 00869 // Validate addr/if specifications and create addr/if struct. 00870 ip_mreq mreq; 00871 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1) 00872 { 00873 return -1; 00874 } 00875 // Tell network device driver to stop reading datagrams with the 00876 // <mcast_addr>. 00877 else if (ACE_SOCK::set_option (IPPROTO_IP, 00878 IP_DROP_MEMBERSHIP, 00879 &mreq, 00880 sizeof mreq) == -1) 00881 { 00882 return -1; 00883 } 00884 00885 } 00886 #else 00887 // Validate addr/if specifications and create addr/if struct. 00888 ip_mreq mreq; 00889 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1) 00890 { 00891 return -1; 00892 } 00893 // Tell network device driver to stop reading datagrams with the 00894 // <mcast_addr>. 00895 // Note, this is not IPv6 friendly... 00896 else if (ACE_SOCK::set_option (IPPROTO_IP, 00897 IP_DROP_MEMBERSHIP, 00898 &mreq, 00899 sizeof mreq) == -1) 00900 { 00901 return -1; 00902 } 00903 #endif /* ACE_HAS_IPV6 */ 00904 00905 return 0; 00906 }
int ACE_SOCK_Dgram_Mcast::unsubscribe_ifs | ( | const ACE_INET_Addr & | mcast_addr, | |
const ACE_TCHAR * | net_if = 0 | |||
) | [private] |
Unsubscribe from a multicast address on one or more network interface(s).
Definition at line 608 of file SOCK_Dgram_Mcast.cpp.
References ACE_BIT_ENABLED, ACE_NEW_RETURN, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, AF_INET, ACE::get_ip_interfaces(), ACE_Addr::get_type(), and OPT_NULLIFACE_ALL.
Referenced by unsubscribe_i().
00610 { 00611 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_ifs"); 00612 00613 00614 if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL) 00615 && net_if == 0) 00616 { 00617 #if defined (ACE_HAS_IPV6) 00618 if (mcast_addr.get_type () == AF_INET6) 00619 { 00620 size_t nr_unsubscribed = 0; 00621 # if defined(__linux__) 00622 00623 struct if_nameindex *intf; 00624 00625 intf = ACE_OS::if_nameindex (); 00626 00627 if (intf == 0) 00628 return -1; 00629 00630 int index = 0; 00631 while (intf[index].if_index != 0 || intf[index].if_name != 0) 00632 { 00633 if (this->leave (mcast_addr, ACE_TEXT_CHAR_TO_TCHAR(intf[index].if_name)) == 0) 00634 ++nr_unsubscribed; 00635 00636 ++index; 00637 } 00638 00639 ACE_OS::if_freenameindex (intf); 00640 00641 # elif defined (ACE_WIN32) 00642 00643 IP_ADAPTER_ADDRESSES tmp_addrs; 00644 // Initial call to determine actual memory size needed 00645 DWORD dwRetVal; 00646 ULONG bufLen = 0; 00647 if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6, 00648 0, 00649 0, 00650 &tmp_addrs, 00651 &bufLen)) != ERROR_BUFFER_OVERFLOW) 00652 return -1; // With output bufferlength 0 this can't be right. 00653 00654 // Get required output buffer and retrieve info for real. 00655 PIP_ADAPTER_ADDRESSES pAddrs; 00656 char *buf; 00657 ACE_NEW_RETURN (buf, 00658 char[bufLen], 00659 -1); 00660 pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf); 00661 if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6, 00662 0, 00663 0, 00664 pAddrs, 00665 &bufLen)) != NO_ERROR) 00666 { 00667 delete[] buf; // clean up 00668 return -1; 00669 } 00670 00671 while (pAddrs) 00672 { 00673 if (this->leave (mcast_addr, ACE_TEXT_CHAR_TO_TCHAR(pAddrs->AdapterName)) == 0) 00674 ++nr_unsubscribed; 00675 00676 pAddrs = pAddrs->Next; 00677 } 00678 00679 delete[] buf; // clean up 00680 00681 # endif /* ACE_WIN32 */ 00682 00683 if (nr_unsubscribed == 0) 00684 { 00685 errno = ENODEV; 00686 return -1; 00687 } 00688 00689 return 1; 00690 00691 00692 } 00693 else 00694 { 00695 // Unsubscribe on all local multicast-capable network interfaces, by 00696 // doing recursive calls with specific interfaces. 00697 00698 ACE_INET_Addr *if_addrs = 0; 00699 size_t if_cnt; 00700 00701 // NOTE - <get_ip_interfaces> doesn't always get all of the 00702 // interfaces. In particular, it may not get a PPP interface. This 00703 // is a limitation of the way <get_ip_interfaces> works with 00704 // old versions of MSVC. The reliable way of getting the interface 00705 // list is available only with MSVC 5 and newer. 00706 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0) 00707 return -1; 00708 00709 size_t nr_unsubscribed = 0; 00710 00711 if (if_cnt < 2) 00712 { 00713 if (this->leave (mcast_addr, 00714 ACE_TEXT ("0.0.0.0")) == 0) 00715 ++nr_unsubscribed; 00716 } 00717 else 00718 { 00719 while (if_cnt > 0) 00720 { 00721 --if_cnt; 00722 // Convert to 0-based for indexing, next loop check 00723 if (if_addrs[if_cnt].get_type () != AF_INET || if_addrs[if_cnt].is_loopback ()) 00724 continue; 00725 if (this->leave (mcast_addr, 00726 ACE_TEXT_CHAR_TO_TCHAR 00727 (if_addrs[if_cnt].get_host_addr ())) == 0) 00728 ++nr_unsubscribed; 00729 } 00730 } 00731 00732 delete [] if_addrs; 00733 00734 if (nr_unsubscribed == 0) 00735 { 00736 errno = ENODEV; 00737 return -1; 00738 } 00739 00740 return 1; 00741 00742 } 00743 #else /* ACE_HAS_IPV6 */ 00744 // Unsubscribe on all local multicast-capable network interfaces, by 00745 // doing recursive calls with specific interfaces. 00746 00747 ACE_INET_Addr *if_addrs = 0; 00748 size_t if_cnt; 00749 00750 // NOTE - <get_ip_interfaces> doesn't always get all of the 00751 // interfaces. In particular, it may not get a PPP interface. This 00752 // is a limitation of the way <get_ip_interfaces> works with 00753 // old versions of MSVC. The reliable way of getting the interface list 00754 // is available only with MSVC 5 and newer. 00755 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0) 00756 return -1; 00757 00758 size_t nr_unsubscribed = 0; 00759 00760 if (if_cnt < 2) 00761 { 00762 if (this->leave (mcast_addr, 00763 ACE_TEXT ("0.0.0.0")) == 0) 00764 ++nr_unsubscribed; 00765 } 00766 else 00767 { 00768 while (if_cnt > 0) 00769 { 00770 --if_cnt; 00771 // Convert to 0-based for indexing, next loop check 00772 if (if_addrs[if_cnt].is_loopback ()) 00773 continue; 00774 if (this->leave (mcast_addr, 00775 ACE_TEXT_CHAR_TO_TCHAR 00776 (if_addrs[if_cnt].get_host_addr ())) == 0) 00777 ++nr_unsubscribed; 00778 } 00779 } 00780 00781 delete [] if_addrs; 00782 00783 if (nr_unsubscribed == 0) 00784 { 00785 errno = ENODEV; 00786 return -1; 00787 } 00788 00789 return 1; 00790 #endif /* !ACE_HAS_IPV6 */ 00791 } 00792 00793 return 0; 00794 }
Declare the dynamic allocation hooks.
Reimplemented from ACE_SOCK_Dgram.
Definition at line 319 of file SOCK_Dgram_Mcast.h.
int ACE_SOCK_Dgram_Mcast::opts_ [private] |
Multicast address to which local <send> methods send datagrams.
Definition at line 361 of file SOCK_Dgram_Mcast.h.
ACE_TCHAR* ACE_SOCK_Dgram_Mcast::send_net_if_ [private] |
Network interface to which all <send> methods send multicast datagrams.
Definition at line 363 of file SOCK_Dgram_Mcast.h.
Referenced by open_i(), and ~ACE_SOCK_Dgram_Mcast().