#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 963 of file SOCK_Dgram_Mcast.cpp. References ACE_GUARD_RETURN, and ACE_TRACE. Referenced by ~ACE_SOCK_Dgram_Mcast().
00964 {
00965 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::clear_subs_list");
00966 int result = 0;
00967
00968 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE)
00969 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard,
00970 this->subscription_list_lock_, -1));
00971 subscription_list_iter_t iter (this->subscription_list_);
00972 for (; !iter.done (); /*Hack: Do _not_ ::advance after remove*/)
00973 {
00974 ip_mreq *pm = iter.next ();
00975 iter.remove ();
00976 delete pm;
00977 }
00978 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */
00979 return result;
00980 }
|
|
|
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_TCHAR, ACE_TEXT, 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_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 }
|
|
||||||||||||||||
|
Definition at line 482 of file SOCK_Dgram_Mcast.cpp. References ACE_BIT_ENABLED, ACE_ERROR, ACE_GUARD_RETURN, ACE_TCHAR, ACE_TEXT, 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_TEXT ("Subscribed port# (%u) different than bound ")
00506 ACE_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_TEXT ("Subscribed address (%s) different than ")
00529 ACE_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 832 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().
00834 {
00835 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::leave");
00836 // Unsubscribe.
00837 int result = this->unsubscribe_i (mcast_addr,
00838 net_if);
00839
00840 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE)
00841 // (Unconditionally) Remove this addr/if from subscription list.
00842 // (Addr/if is removed even if unsubscribe failed)
00843 ip_mreq tgt_mreq;
00844 if (this->make_multicast_ifaddr (&tgt_mreq,
00845 mcast_addr,
00846 net_if) != -1)
00847 {
00848 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard,
00849 this->subscription_list_lock_, -1));
00850 subscription_list_iter_t iter (this->subscription_list_);
00851 for (; !iter.done (); iter.advance ())
00852 {
00853 ip_mreq *pm = iter.next ();
00854 if (ACE_SDM_helpers::is_equal (*pm, tgt_mreq))
00855 {
00856 iter.remove ();
00857 delete pm;
00858 break;
00859 }
00860 }
00861 }
00862 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */
00863
00864 return result >= 0 ? 0 : result;
00865 }
|
|
||||||||||||||||
|
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(), open_i(), and SOCK_DGRAM. 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(), 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 }
|
|
||||||||||||||||
|
Send n , 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 n bytes in buf, 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(), IPPROTO_IP, 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, IPPROTO_IP, 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 return 0;
00606 }
00607 // Fall through for IPv4 case
00608 #endif /* ACE_HAS_IPV6 */
00609
00610 // Create multicast addr/if struct.
00611 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
00612 return -1;
00613 // Tell IP stack to pass messages sent to this group.
00614 else if (this->ACE_SOCK::set_option (IPPROTO_IP,
00615 IP_ADD_MEMBERSHIP,
00616 &mreq,
00617 sizeof mreq) == -1)
00618 return -1;
00619
00620 return 0;
00621 }
|
|
||||||||||||||||
|
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_TCHAR, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, AF_INET, 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 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->subscribe (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->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_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 943 of file SOCK_Dgram_Mcast.cpp. References ACE_ERROR_RETURN, ACE_TEXT, ACE_TRACE, and LM_INFO.
00944 {
00945 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe");
00946
00947 // Can't implement this reliably without keeping an expensive list,
00948 // and can't close the socket since the caller may want to continue
00949 // using the socket to send() or join() new groups. Even if we
00950 // wanted to be clever and reopen the socket, we'd need to know what
00951 // options had been set, and reset them--and we have no way of doing
00952 // that either. :-(
00953 // Should this return -1?
00954 ACE_ERROR_RETURN ((LM_INFO,
00955 ACE_TEXT ("ACE_SOCK_Dgram_Mcast::unsubscribe (void) ")
00956 ACE_TEXT ("has been deprecated. You must either ")
00957 ACE_TEXT ("close to socket to unsubscribe to all ")
00958 ACE_TEXT ("or unsubscribe to each individually.\n")),
00959 0);
00960 }
|
|
||||||||||||||||||||
|
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 818 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, and leave().
|
|
||||||||||||
|
Do unsubscription processing w/out udpating subscription list.
Definition at line 869 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, ACE_Addr::get_type(), IP_DROP_MEMBERSHIP, IPPROTO_IP, ACE_SOCK_Dgram::make_multicast_ifaddr(), ACE_SOCK_Dgram::make_multicast_ifaddr6(), ACE_SOCK::set_option(), and unsubscribe_ifs(). Referenced by leave().
00871 {
00872 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_i");
00873
00874 int result = this->unsubscribe_ifs (mcast_addr,
00875 net_if);
00876
00877 // Check for error or "short-circuit" return.
00878 if (result != 0)
00879 return result;
00880
00881 #if defined (ACE_HAS_IPV6)
00882 if (mcast_addr.get_type () == AF_INET6)
00883 {
00884 // Validate addr/if specifications and create addr/if struct.
00885 ipv6_mreq mreq;
00886 if (this->make_multicast_ifaddr6 (&mreq, mcast_addr, net_if) == -1)
00887 {
00888 return -1;
00889 }
00890 // Tell network device driver to stop reading datagrams with the
00891 // <mcast_addr>.
00892 else if (ACE_SOCK::set_option (IPPROTO_IPV6,
00893 IPV6_LEAVE_GROUP,
00894 &mreq,
00895 sizeof mreq) == -1)
00896 {
00897 return -1;
00898 }
00899
00900 }
00901 else // IPv4
00902 {
00903 // Validate addr/if specifications and create addr/if struct.
00904 ip_mreq mreq;
00905 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
00906 {
00907 return -1;
00908 }
00909 // Tell network device driver to stop reading datagrams with the
00910 // <mcast_addr>.
00911 else if (ACE_SOCK::set_option (IPPROTO_IP,
00912 IP_DROP_MEMBERSHIP,
00913 &mreq,
00914 sizeof mreq) == -1)
00915 {
00916 return -1;
00917 }
00918
00919 }
00920 #else
00921 // Validate addr/if specifications and create addr/if struct.
00922 ip_mreq mreq;
00923 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
00924 {
00925 return -1;
00926 }
00927 // Tell network device driver to stop reading datagrams with the
00928 // <mcast_addr>.
00929 // Note, this is not IPv6 friendly...
00930 else if (ACE_SOCK::set_option (IPPROTO_IP,
00931 IP_DROP_MEMBERSHIP,
00932 &mreq,
00933 sizeof mreq) == -1)
00934 {
00935 return -1;
00936 }
00937 #endif /* ACE_HAS_IPV6 */
00938
00939 return 0;
00940 }
|
|
||||||||||||
|
Unsubscribe from a multicast address on one or more network interface(s).
Definition at line 624 of file SOCK_Dgram_Mcast.cpp. References ACE_BIT_ENABLED, ACE_NEW_RETURN, ACE_TCHAR, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, AF_INET, ACE::get_ip_interfaces(), ACE_Addr::get_type(), ACE_INET_Addr::is_loopback(), leave(), and OPT_NULLIFACE_ALL. Referenced by unsubscribe_i().
00626 {
00627 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_ifs");
00628
00629
00630 if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL)
00631 && net_if == 0)
00632 {
00633 #if defined (ACE_HAS_IPV6)
00634 if (mcast_addr.get_type () == AF_INET6)
00635 {
00636 size_t nr_unsubscribed = 0;
00637 # if defined(__linux__)
00638
00639 struct if_nameindex *intf;
00640
00641 intf = ACE_OS::if_nameindex ();
00642
00643 if (intf == 0)
00644 return -1;
00645
00646 int index = 0;
00647 while (intf[index].if_index != 0 || intf[index].if_name != 0)
00648 {
00649 if (this->leave (mcast_addr, ACE_TEXT_CHAR_TO_TCHAR(intf[index].if_name)) == 0)
00650 ++nr_unsubscribed;
00651
00652 ++index;
00653 }
00654
00655 ACE_OS::if_freenameindex (intf);
00656
00657 # elif defined (ACE_WIN32)
00658
00659 IP_ADAPTER_ADDRESSES tmp_addrs;
00660 // Initial call to determine actual memory size needed
00661 DWORD dwRetVal;
00662 ULONG bufLen = 0;
00663 if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6,
00664 0,
00665 0,
00666 &tmp_addrs,
00667 &bufLen)) != ERROR_BUFFER_OVERFLOW)
00668 return -1; // With output bufferlength 0 this can't be right.
00669
00670 // Get required output buffer and retrieve info for real.
00671 PIP_ADAPTER_ADDRESSES pAddrs;
00672 char *buf;
00673 ACE_NEW_RETURN (buf,
00674 char[bufLen],
00675 -1);
00676 pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf);
00677 if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6,
00678 0,
00679 0,
00680 pAddrs,
00681 &bufLen)) != NO_ERROR)
00682 {
00683 delete[] buf; // clean up
00684 return -1;
00685 }
00686
00687 while (pAddrs)
00688 {
00689 if (this->leave (mcast_addr, ACE_TEXT_CHAR_TO_TCHAR(pAddrs->AdapterName)) == 0)
00690 ++nr_unsubscribed;
00691
00692 pAddrs = pAddrs->Next;
00693 }
00694
00695 delete[] buf; // clean up
00696
00697 # endif /* ACE_WIN32 */
00698
00699 if (nr_unsubscribed == 0)
00700 {
00701 errno = ENODEV;
00702 return -1;
00703 }
00704
00705 return 1;
00706
00707
00708 }
00709 else
00710 {
00711 // Unsubscribe on all local multicast-capable network interfaces, by
00712 // doing recursive calls with specific interfaces.
00713
00714 ACE_INET_Addr *if_addrs = 0;
00715 size_t if_cnt;
00716
00717 // NOTE - <get_ip_interfaces> doesn't always get all of the
00718 // interfaces. In particular, it may not get a PPP interface. This
00719 // is a limitation of the way <get_ip_interfaces> works with
00720 // old versions of MSVC. The reliable way of getting the interface
00721 // list is available only with MSVC 5 and newer.
00722 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
00723 return -1;
00724
00725 size_t nr_unsubscribed = 0;
00726
00727 if (if_cnt < 2)
00728 {
00729 if (this->leave (mcast_addr,
00730 ACE_TEXT ("0.0.0.0")) == 0)
00731 ++nr_unsubscribed;
00732 }
00733 else
00734 {
00735 while (if_cnt > 0)
00736 {
00737 --if_cnt;
00738 // Convert to 0-based for indexing, next loop check
00739 if (if_addrs[if_cnt].get_type () != AF_INET || if_addrs[if_cnt].is_loopback ())
00740 continue;
00741 if (this->leave (mcast_addr,
00742 ACE_TEXT_CHAR_TO_TCHAR
00743 (if_addrs[if_cnt].get_host_addr ())) == 0)
00744 ++nr_unsubscribed;
00745 }
00746 }
00747
00748 delete [] if_addrs;
00749
00750 if (nr_unsubscribed == 0)
00751 {
00752 errno = ENODEV;
00753 return -1;
00754 }
00755
00756 return 1;
00757
00758 }
00759 #else /* ACE_HAS_IPV6 */
00760 // Unsubscribe on all local multicast-capable network interfaces, by
00761 // doing recursive calls with specific interfaces.
00762
00763 ACE_INET_Addr *if_addrs = 0;
00764 size_t if_cnt;
00765
00766 // NOTE - <get_ip_interfaces> doesn't always get all of the
00767 // interfaces. In particular, it may not get a PPP interface. This
00768 // is a limitation of the way <get_ip_interfaces> works with
00769 // old versions of MSVC. The reliable way of getting the interface list
00770 // is available only with MSVC 5 and newer.
00771 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0)
00772 return -1;
00773
00774 size_t nr_unsubscribed = 0;
00775
00776 if (if_cnt < 2)
00777 {
00778 if (this->leave (mcast_addr,
00779 ACE_TEXT ("0.0.0.0")) == 0)
00780 ++nr_unsubscribed;
00781 }
00782 else
00783 {
00784 while (if_cnt > 0)
00785 {
00786 --if_cnt;
00787 // Convert to 0-based for indexing, next loop check
00788 if (if_addrs[if_cnt].is_loopback ())
00789 continue;
00790 if (this->leave (mcast_addr,
00791 ACE_TEXT_CHAR_TO_TCHAR
00792 (if_addrs[if_cnt].get_host_addr ())) == 0)
00793 ++nr_unsubscribed;
00794 }
00795 }
00796
00797 delete [] if_addrs;
00798
00799 if (nr_unsubscribed == 0)
00800 {
00801 errno = ENODEV;
00802 return -1;
00803 }
00804
00805 return 1;
00806 #endif /* !ACE_HAS_IPV6 */
00807 }
00808
00809 return 0;
00810 }
|
|
|
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(). |
1.3.6