#include <SOCK_Dgram_Mcast.h>
Inheritance diagram for ACE_SOCK_Dgram_Mcast:
Public Types | |
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_ALL, 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 | subscribe (const ACE_INET_Addr &mcast_addr, int reuse_addr=1, const ACE_TCHAR *net_if=0, int protocol_family=PF_INET, int protocol=0) |
int | join (const ACE_INET_Addr &mcast_addr, int reuse_addr=1, const ACE_TCHAR *net_if=0) |
int | unsubscribe (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0, int protocol_family=PF_INET, int protocol=0) |
int | leave (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0) |
int | unsubscribe (void) |
Unsubscribe all current subscriptions. | |
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 methods send datagrams. | |
ACE_TCHAR * | send_net_if_ |
Network interface to which all 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 and ):
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. Referenced by ACE_SOCK_Dgram_Mcast().
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 }; |
|
You must invoke or , 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, and options.
00134 : opts_ (opts), 00135 send_net_if_ (0) 00136 { 00137 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast"); 00138 } |
|
The OPT_DTORUNSUB_YES_ option defines whether an explicit 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 } |
|
Empty the dynamic subscription list.
Definition at line 974 of file SOCK_Dgram_Mcast.cpp. References ACE_GUARD_RETURN, and ACE_TRACE. Referenced by ~ACE_SOCK_Dgram_Mcast().
00975 { 00976 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::clear_subs_list"); 00977 int result = 0; 00978 00979 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) 00980 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard, 00981 this->subscription_list_lock_, -1)); 00982 subscription_list_iter_t iter (this->subscription_list_); 00983 for (; !iter.done (); /*Hack: Do _not_ ::advance after remove*/) 00984 { 00985 ip_mreq *pm = iter.next (); 00986 iter.remove (); 00987 delete pm; 00988 } 00989 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ 00990 return result; 00991 } |
|
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_LIB_TEXT, ACE_NTOHL, ACE_TCHAR, ACE_TRACE, ACE_SDM_helpers::addr_to_string(), LM_DEBUG, MAXNAMELEN, OPT_BINDADDR_YES, OPT_NULLIFACE_ALL, 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_LIB_TEXT ("\nOptions: bindaddr=%s, nulliface=%s\n"), 00080 ACE_BIT_ENABLED (this->opts_, OPT_BINDADDR_YES) ? 00081 ACE_LIB_TEXT ("<Bound>") : ACE_LIB_TEXT ("<Not Bound>"), 00082 ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL) ? 00083 ACE_LIB_TEXT ("<All Ifaces>") : ACE_LIB_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_LIB_TEXT ("Send addr=%s iface=%s\n"), 00090 addr_string, 00091 this->send_net_if_ ? this->send_net_if_ 00092 : ACE_LIB_TEXT ("<default>"))); 00093 00094 // Show list of subscribed addresses. 00095 ACE_DEBUG ((LM_DEBUG, ACE_LIB_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_LIB_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_LIB_TEXT ("<default>")); 00119 00120 // Dump info. 00121 ACE_DEBUG ((LM_DEBUG, 00122 ACE_LIB_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 } |
|
Definition at line 482 of file SOCK_Dgram_Mcast.cpp. References ACE_BIT_ENABLED, ACE_ERROR, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, ACE_SDM_helpers::addr_to_string(), ENXIO, ACE_INET_Addr::get_port_number(), ACE_INET_Addr::is_any(), LM_ERROR, ACE_SOCK_Dgram::make_multicast_ifaddr(), MAXNAMELEN, OPT_BINDADDR_YES, send_addr_, ACE_INET_Addr::set_port_number(), and subscribe_i(). Referenced by subscribe(), and subscribe_ifs().
00485 { 00486 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::join"); 00487 ACE_INET_Addr subscribe_addr = mcast_addr; 00488 00489 // If port# is 0, insert bound port# if it is set. (To satisfy lower-level 00490 // port# validation.) 00491 u_short def_port_number = this->send_addr_.get_port_number (); 00492 if (subscribe_addr.get_port_number () == 0 00493 && def_port_number != 0) 00494 { 00495 subscribe_addr.set_port_number (def_port_number); 00496 } 00497 00498 // Check for port# different than bound port#. 00499 u_short sub_port_number = mcast_addr.get_port_number (); 00500 if (sub_port_number != 0 00501 && def_port_number != 0 00502 && sub_port_number != def_port_number) 00503 { 00504 ACE_ERROR ((LM_ERROR, 00505 ACE_LIB_TEXT ("Subscribed port# (%u) different than bound ") 00506 ACE_LIB_TEXT ("port# (%u).\n"), 00507 (u_int) sub_port_number, 00508 (u_int) def_port_number)); 00509 errno = ENXIO; 00510 return -1; 00511 } 00512 00513 // If bind_addr_opt_ is enabled, check for address different than 00514 // bound address. 00515 ACE_INET_Addr tmp_addr (this->send_addr_); 00516 tmp_addr.set_port_number (mcast_addr.get_port_number ()); // force equal port numbers 00517 if (ACE_BIT_ENABLED (this->opts_, OPT_BINDADDR_YES) 00518 && !this->send_addr_.is_any () 00519 && this->send_addr_ != mcast_addr) 00520 { 00521 ACE_TCHAR sub_addr_string[MAXNAMELEN + 1]; 00522 ACE_TCHAR bound_addr_string[MAXNAMELEN + 1]; 00523 ACE_SDM_helpers::addr_to_string (mcast_addr, sub_addr_string, 00524 sizeof sub_addr_string, 1); 00525 ACE_SDM_helpers::addr_to_string (this->send_addr_, bound_addr_string, 00526 sizeof bound_addr_string, 1); 00527 ACE_ERROR ((LM_ERROR, 00528 ACE_LIB_TEXT ("Subscribed address (%s) different than ") 00529 ACE_LIB_TEXT ("bound address (%s).\n"), 00530 sub_addr_string, 00531 bound_addr_string)); 00532 errno = ENXIO; 00533 return -1; 00534 } 00535 00536 // Attempt subscription. 00537 int result = this->subscribe_i (subscribe_addr, reuse_addr, net_if); 00538 00539 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) 00540 if (result == 0) 00541 { 00542 // Add this addr/iface info to the list of subscriptions. 00543 // (Assumes this is unique addr/iface combo - most systems don't allow 00544 // re-sub to same addr/iface.) 00545 ip_mreq *pmreq = new ip_mreq; 00546 // (should not fail) 00547 if (this->make_multicast_ifaddr (pmreq, subscribe_addr, net_if) != -1) 00548 { 00549 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard, 00550 this->subscription_list_lock_, -1)); 00551 this->subscription_list_.insert_tail (pmreq); 00552 return 0; 00553 } 00554 // this still isn't really right. If ACE_GUARD_RETURN fails, we leak. 00555 // Need to add one of Chris' fancy ace auto pointers (bound?). 00556 delete pmreq; 00557 } 00558 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ 00559 00560 return result >= 0 ? 0 : result; 00561 } |
|
Definition at line 843 of file SOCK_Dgram_Mcast.cpp. References ACE_GUARD_RETURN, ACE_TCHAR, ACE_TRACE, ACE_SDM_helpers::is_equal(), ACE_SOCK_Dgram::make_multicast_ifaddr(), and unsubscribe_i(). Referenced by unsubscribe(), and unsubscribe_ifs().
00845 { 00846 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::leave"); 00847 // Unsubscribe. 00848 int result = this->unsubscribe_i (mcast_addr, 00849 net_if); 00850 00851 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) 00852 // (Unconditionally) Remove this addr/if from subscription list. 00853 // (Addr/if is removed even if unsubscribe failed) 00854 ip_mreq tgt_mreq; 00855 if (this->make_multicast_ifaddr (&tgt_mreq, 00856 mcast_addr, 00857 net_if) != -1) 00858 { 00859 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard, 00860 this->subscription_list_lock_, -1)); 00861 subscription_list_iter_t iter (this->subscription_list_); 00862 for (; !iter.done (); iter.advance ()) 00863 { 00864 ip_mreq *pm = iter.next (); 00865 if (ACE_SDM_helpers::is_equal (*pm, tgt_mreq)) 00866 { 00867 iter.remove (); 00868 delete pm; 00869 break; 00870 } 00871 } 00872 } 00873 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ 00874 00875 return result >= 0 ? 0 : result; 00876 } |
|
This method is optional; if not explicitly invoked, it is invoked by the first , using the subscribed address/port# and network interface paramters. The 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 parameter != 0, it defines the network interface used for all sends by this instance, otherwise the system "default" interface is used. (The parameter is ignored if this feature is not supported by the envriornment.) The port# in may be 0, in which case a system-assigned (ephemeral) port# is used for sending and receiving. If != 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_TCHAR, ACE_TRACE, ACE_IPC_SAP::get_handle(), ACE_Addr::get_type(), ACE_SOCK::open(), and open_i(). Referenced by subscribe_i().
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 } |
|
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_TCHAR, ACE_TRACE, ACE_SOCK::get_local_addr(), ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), OPT_BINDADDR_YES, send_addr_, send_net_if_, ACE_INET_Addr::set(), ACE_SOCK_Dgram::set_nic(), ACE_SOCK::set_option(), ACE_INET_Addr::set_port_number(), ACE_SOCK_Dgram::shared_open(), 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 } |
|
Send , using the multicast address and network interface defined by the first or . 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 } |
|
Send bytes in , using the multicast address and network interface defined by the first or . 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 } |
|
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, ACE_IPC_SAP::get_handle(), ACE_Addr::get_type(), send_addr_, 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 } |
|
The given group is joined on the specified interface. If option OPT_NULLIFACE_ALL is used and 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 , and was not previously invoked, will be invoked using for binding the socket and as the interface for . 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 or ), 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, is NULL, and <ACE_Sock_Connect::get_ip_interfaces> is not implemented in this environment. Note that the optional parameter does not apply to subscriptions; it is only used if is implicitly invoked (see above).
Definition at line 467 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, and join(). Referenced by subscribe_ifs().
|
|
Do subscription processing w/out updating the subscription list.
Definition at line 565 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, ACE_Addr::get_type(), IP_ADD_MEMBERSHIP, ACE_SOCK_Dgram::make_multicast_ifaddr(), ACE_SOCK_Dgram::make_multicast_ifaddr6(), open(), ACE_SOCK::set_option(), and subscribe_ifs(). Referenced by join().
00568 { 00569 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_i"); 00570 ip_mreq mreq; 00571 #if defined (ACE_HAS_IPV6) 00572 ipv6_mreq mreq6; 00573 #endif /* __linux__ && ACE_HAS_IPV6 */ 00574 00575 // Open the socket IFF this is the first ::subscribe and ::open 00576 // was not explicitly invoked. 00577 if (this->open (mcast_addr, 00578 net_if, 00579 reuse_addr) == -1) 00580 return -1; 00581 00582 // Only do this if net_if == 0, i.e., INADDR_ANY 00583 if (net_if == 0) 00584 { 00585 int result = this->subscribe_ifs (mcast_addr, 00586 net_if, 00587 reuse_addr); 00588 // Check for error or "short-circuit" return. 00589 if (result != 0) 00590 return result; 00591 } 00592 00593 #if defined (ACE_HAS_IPV6) 00594 if (mcast_addr.get_type () == AF_INET6) 00595 { 00596 if (this->make_multicast_ifaddr6 (&mreq6, mcast_addr, net_if) == -1) 00597 return -1; 00598 // Tell IP stack to pass messages sent to this group. 00599 else if (this->ACE_SOCK::set_option (IPPROTO_IPV6, 00600 IPV6_JOIN_GROUP, 00601 &mreq6, 00602 sizeof mreq6) == -1) 00603 return -1; 00604 } 00605 else 00606 { 00607 // Create multicast addr/if struct. 00608 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1) 00609 return -1; 00610 // Tell IP stack to pass messages sent to this group. 00611 else if (this->ACE_SOCK::set_option (IPPROTO_IP, 00612 IP_ADD_MEMBERSHIP, 00613 &mreq, 00614 sizeof mreq) == -1) 00615 return -1; 00616 00617 } 00618 #else 00619 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1) 00620 return -1; 00621 // Tell IP stack to pass messages sent to this group. 00622 // Note, this is not IPv6 compliant. 00623 else if (this->ACE_SOCK::set_option (IPPROTO_IP, 00624 IP_ADD_MEMBERSHIP, 00625 &mreq, 00626 sizeof mreq) == -1) 00627 return -1; 00628 00629 #endif /* ACE_HAS_IPV6 */ 00630 00631 return 0; 00632 } |
|
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_LIB_TEXT, ACE_NEW_RETURN, ACE_TCHAR, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, ACE::get_ip_interfaces(), ACE_Addr::get_type(), ACE_INET_Addr::is_loopback(), join(), ACE_SOCK_Dgram::make_multicast_ifaddr(), ACE_SOCK_Dgram::make_multicast_ifaddr6(), OPT_NULLIFACE_ALL, and subscribe(). 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 NULL, 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 NULL, 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->subscribe (mcast_addr, 00351 reuse_addr, 00352 ACE_LIB_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->subscribe (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->subscribe (mcast_addr, 00402 reuse_addr, 00403 ACE_LIB_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->subscribe (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 } |
|
Unsubscribe all current subscriptions. Unsubscribe all active group/interface subscriptions (if any). Returns -1 if any unsubscribe failed, 0 if there are no errors or no current subscriptions.
Definition at line 954 of file SOCK_Dgram_Mcast.cpp. References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TRACE, and LM_INFO.
00955 { 00956 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe"); 00957 00958 // Can't implement this reliably without keeping an expensive list, 00959 // and can't close the socket since the caller may want to continue 00960 // using the socket to send() or join() new groups. Even if we 00961 // wanted to be clever and reopen the socket, we'd need to know what 00962 // options had been set, and reset them--and we have no way of doing 00963 // that either. :-( 00964 // Should this return -1? 00965 ACE_ERROR_RETURN ((LM_INFO, 00966 ACE_LIB_TEXT ("ACE_SOCK_Dgram_Mcast::unsubscribe (void) ") 00967 ACE_LIB_TEXT ("has been deprecated. You must either ") 00968 ACE_LIB_TEXT ("close to socket to unsubscribe to all ") 00969 ACE_LIB_TEXT ("or unsubscribe to each individually.\n")), 00970 0); 00971 } |
|
The specified group/interface combination is unsubscribed. If option OPT_NULLIFACE_ALL is used and 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, is = 0, and <ACE_Sock_Connect::get_ip_interfaces> is not implemented in this environment (_even if_ the specifies a non- NULL ).
Definition at line 829 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, and leave().
|
|
Do unsubscription processing w/out udpating subscription list.
Definition at line 880 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, ACE_Addr::get_type(), IP_DROP_MEMBERSHIP, ACE_SOCK_Dgram::make_multicast_ifaddr(), ACE_SOCK_Dgram::make_multicast_ifaddr6(), ACE_SOCK::set_option(), and unsubscribe_ifs(). Referenced by leave().
00882 { 00883 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_i"); 00884 00885 int result = this->unsubscribe_ifs (mcast_addr, 00886 net_if); 00887 00888 // Check for error or "short-circuit" return. 00889 if (result != 0) 00890 return result; 00891 00892 #if defined (ACE_HAS_IPV6) 00893 if (mcast_addr.get_type () == AF_INET6) 00894 { 00895 // Validate addr/if specifications and create addr/if struct. 00896 ipv6_mreq mreq; 00897 if (this->make_multicast_ifaddr6 (&mreq, mcast_addr, net_if) == -1) 00898 { 00899 return -1; 00900 } 00901 // Tell network device driver to stop reading datagrams with the 00902 // <mcast_addr>. 00903 else if (ACE_SOCK::set_option (IPPROTO_IPV6, 00904 IPV6_LEAVE_GROUP, 00905 &mreq, 00906 sizeof mreq) == -1) 00907 { 00908 return -1; 00909 } 00910 00911 } 00912 else // IPv4 00913 { 00914 // Validate addr/if specifications and create addr/if struct. 00915 ip_mreq mreq; 00916 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1) 00917 { 00918 return -1; 00919 } 00920 // Tell network device driver to stop reading datagrams with the 00921 // <mcast_addr>. 00922 else if (ACE_SOCK::set_option (IPPROTO_IP, 00923 IP_DROP_MEMBERSHIP, 00924 &mreq, 00925 sizeof mreq) == -1) 00926 { 00927 return -1; 00928 } 00929 00930 } 00931 #else 00932 // Validate addr/if specifications and create addr/if struct. 00933 ip_mreq mreq; 00934 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1) 00935 { 00936 return -1; 00937 } 00938 // Tell network device driver to stop reading datagrams with the 00939 // <mcast_addr>. 00940 // Note, this is not IPv6 friendly... 00941 else if (ACE_SOCK::set_option (IPPROTO_IP, 00942 IP_DROP_MEMBERSHIP, 00943 &mreq, 00944 sizeof mreq) == -1) 00945 { 00946 return -1; 00947 } 00948 #endif /* ACE_HAS_IPV6 */ 00949 00950 return 0; 00951 } |
|
Unsubscribe from a multicast address on one or more network interface(s).
Definition at line 635 of file SOCK_Dgram_Mcast.cpp. References ACE_BIT_ENABLED, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_TCHAR, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, ACE::get_ip_interfaces(), ACE_Addr::get_type(), ACE_INET_Addr::is_loopback(), leave(), and OPT_NULLIFACE_ALL. Referenced by unsubscribe_i().
00637 { 00638 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_ifs"); 00639 00640 00641 if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL) 00642 && net_if == 0) 00643 { 00644 #if defined (ACE_HAS_IPV6) 00645 if (mcast_addr.get_type () == AF_INET6) 00646 { 00647 size_t nr_unsubscribed = 0; 00648 # if defined(__linux__) 00649 00650 struct if_nameindex *intf; 00651 00652 intf = ACE_OS::if_nameindex (); 00653 00654 if (intf == 0) 00655 return -1; 00656 00657 int index = 0; 00658 while (intf[index].if_index != 0 || intf[index].if_name != 0) 00659 { 00660 if (this->leave (mcast_addr, ACE_TEXT_CHAR_TO_TCHAR(intf[index].if_name)) == 0) 00661 ++nr_unsubscribed; 00662 00663 ++index; 00664 } 00665 00666 ACE_OS::if_freenameindex (intf); 00667 00668 # elif defined (ACE_WIN32) 00669 00670 IP_ADAPTER_ADDRESSES tmp_addrs; 00671 // Initial call to determine actual memory size needed 00672 DWORD dwRetVal; 00673 ULONG bufLen = 0; 00674 if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6, 00675 0, 00676 NULL, 00677 &tmp_addrs, 00678 &bufLen)) != ERROR_BUFFER_OVERFLOW) 00679 return -1; // With output bufferlength 0 this can't be right. 00680 00681 // Get required output buffer and retrieve info for real. 00682 PIP_ADAPTER_ADDRESSES pAddrs; 00683 char *buf; 00684 ACE_NEW_RETURN (buf, 00685 char[bufLen], 00686 -1); 00687 pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf); 00688 if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6, 00689 0, 00690 NULL, 00691 pAddrs, 00692 &bufLen)) != NO_ERROR) 00693 { 00694 delete[] buf; // clean up 00695 return -1; 00696 } 00697 00698 while (pAddrs) 00699 { 00700 if (this->leave (mcast_addr, ACE_TEXT_CHAR_TO_TCHAR(pAddrs->AdapterName)) == 0) 00701 ++nr_unsubscribed; 00702 00703 pAddrs = pAddrs->Next; 00704 } 00705 00706 delete[] buf; // clean up 00707 00708 # endif /* ACE_WIN32 */ 00709 00710 if (nr_unsubscribed == 0) 00711 { 00712 errno = ENODEV; 00713 return -1; 00714 } 00715 00716 return 1; 00717 00718 00719 } 00720 else 00721 { 00722 // Unsubscribe on all local multicast-capable network interfaces, by 00723 // doing recursive calls with specific interfaces. 00724 00725 ACE_INET_Addr *if_addrs = 0; 00726 size_t if_cnt; 00727 00728 // NOTE - <get_ip_interfaces> doesn't always get all of the 00729 // interfaces. In particular, it may not get a PPP interface. This 00730 // is a limitation of the way <get_ip_interfaces> works with 00731 // old versions of MSVC. The reliable way of getting the interface 00732 // list is available only with MSVC 5 and newer. 00733 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0) 00734 return -1; 00735 00736 size_t nr_unsubscribed = 0; 00737 00738 if (if_cnt < 2) 00739 { 00740 if (this->leave (mcast_addr, 00741 ACE_LIB_TEXT ("0.0.0.0")) == 0) 00742 ++nr_unsubscribed; 00743 } 00744 else 00745 { 00746 while (if_cnt > 0) 00747 { 00748 --if_cnt; 00749 // Convert to 0-based for indexing, next loop check 00750 if (if_addrs[if_cnt].get_type () != AF_INET || if_addrs[if_cnt].is_loopback ()) 00751 continue; 00752 if (this->leave (mcast_addr, 00753 ACE_TEXT_CHAR_TO_TCHAR 00754 (if_addrs[if_cnt].get_host_addr ())) == 0) 00755 ++nr_unsubscribed; 00756 } 00757 } 00758 00759 delete [] if_addrs; 00760 00761 if (nr_unsubscribed == 0) 00762 { 00763 errno = ENODEV; 00764 return -1; 00765 } 00766 00767 return 1; 00768 00769 } 00770 #else /* ACE_HAS_IPV6 */ 00771 // Unsubscribe on all local multicast-capable network interfaces, by 00772 // doing recursive calls with specific interfaces. 00773 00774 ACE_INET_Addr *if_addrs = 0; 00775 size_t if_cnt; 00776 00777 // NOTE - <get_ip_interfaces> doesn't always get all of the 00778 // interfaces. In particular, it may not get a PPP interface. This 00779 // is a limitation of the way <get_ip_interfaces> works with 00780 // old versions of MSVC. The reliable way of getting the interface list 00781 // is available only with MSVC 5 and newer. 00782 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0) 00783 return -1; 00784 00785 size_t nr_unsubscribed = 0; 00786 00787 if (if_cnt < 2) 00788 { 00789 if (this->leave (mcast_addr, 00790 ACE_LIB_TEXT ("0.0.0.0")) == 0) 00791 ++nr_unsubscribed; 00792 } 00793 else 00794 { 00795 while (if_cnt > 0) 00796 { 00797 --if_cnt; 00798 // Convert to 0-based for indexing, next loop check 00799 if (if_addrs[if_cnt].is_loopback ()) 00800 continue; 00801 if (this->leave (mcast_addr, 00802 ACE_TEXT_CHAR_TO_TCHAR 00803 (if_addrs[if_cnt].get_host_addr ())) == 0) 00804 ++nr_unsubscribed; 00805 } 00806 } 00807 00808 delete [] if_addrs; 00809 00810 if (nr_unsubscribed == 0) 00811 { 00812 errno = ENODEV; 00813 return -1; 00814 } 00815 00816 return 1; 00817 #endif /* !ACE_HAS_IPV6 */ 00818 } 00819 00820 return 0; 00821 } |
|
Declare the dynamic allocation hooks.
Reimplemented from ACE_SOCK_Dgram. Definition at line 352 of file SOCK_Dgram_Mcast.h. |
|
Per-instance options..
Definition at line 391 of file SOCK_Dgram_Mcast.h. |
|
Multicast address to which local methods send datagrams.
Definition at line 394 of file SOCK_Dgram_Mcast.h. Referenced by join(), open_i(), and set_option(). |
|
Network interface to which all methods send multicast datagrams.
Definition at line 396 of file SOCK_Dgram_Mcast.h. Referenced by open_i(), and ~ACE_SOCK_Dgram_Mcast(). |