#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 Methods | |
| ACE_SOCK_Dgram_Mcast (options opts=DEFOPTS) | |
| Ctor - Create an unitialized instance and define per-instance optional functionality. More... | |
| ~ACE_SOCK_Dgram_Mcast (void) | |
| Dtor - Release all resources and implicitly or explicitly unsubscribe from all currently subscribed groups. More... | |
| int | open (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0, int reuse_addr=1) |
| Explicitly open/bind the socket and define the network interface and default multicast address used for sending messages. More... | |
| 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) |
| Join a multicast group on a given interface (or all interfaces, if supported). More... | |
| 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) |
| Leave a multicast group on a given interface (or all interfaces, if supported). More... | |
| int | leave (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0) |
| int | unsubscribe (void) |
| Unsubscribe all current subscriptions. More... | |
| ssize_t | 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>. More... | |
| ssize_t | 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>. More... | |
| int | set_option (int option, char optval) |
| Set a socket option. More... | |
| void | dump (void) const |
| Dump the state of an object. More... | |
Public Attributes | |
| ACE_ALLOC_HOOK_DECLARE | |
| Declare the dynamic allocation hooks. More... | |
Protected Methods | |
| int | open_i (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0, int reuse_addr=1) |
| Contains common open functionality so that inheriting classes can reuse it. More... | |
| int | make_multicast_ifaddr (ip_mreq *mreq, const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if) |
| Create a multicast addr/if pair, in format useful for system calls. If mreq param is NULL, just verify the passed addr/interface specs. More... | |
| int | make_multicast_ifaddr_i (ip_mreq *mreq, const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=ACE_LIB_TEXT("le0")) |
| Create a multicast addr/if pair. This method factors out common code called by <make_multicast_address> and <subscribe>. More... | |
| int | clear_subs_list (void) |
| Empty the dynamic subscription list. More... | |
Private Methods | |
| int | subscribe_ifs (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if, int reuse_addr) |
| Subscribe to a multicast address on one or more network interface(s). (No QoS support.). More... | |
| 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. More... | |
| 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). More... | |
| int | unsubscribe_i (const ACE_INET_Addr &mcast_addr, const ACE_TCHAR *net_if=0) |
| Do unsubscription processing w/out udpating subscription list. More... | |
Private Attributes | |
| int | opts_ |
| Per-instance options.. More... | |
| ACE_INET_Addr | send_addr_ |
| Multicast address to which local <send> methods send datagrams. More... | |
| ACE_TCHAR * | send_net_if_ |
| Network interface to which all <send> methods send multicast datagrams. More... | |
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:
Definition at line 90 of file SOCK_Dgram_Mcast.h.
|
|
Option parameters.
These control per-instance optional functionality. They are set via optional constructor arguments. Note: Certain option values are not valid for all environments (see comments in source file for environment-specific restrictions). Default values are always valid values for the compilation environment.
Definition at line 103 of file SOCK_Dgram_Mcast.h. Referenced by ACE_SOCK_Dgram_Mcast.
00104 {
00105 // Define whether a specific (multicast) address (in addition to the port#)
00106 // is bound to the socket.
00107 // Notes:
00108 // - Effect of doing this is stack/environment dependent, but in most
00109 // environments can be used to filter out unwanted unicast, broadcast, and
00110 // (other) multicast messages sent to the same port#.
00111 // - Some IP stacks (e.g. some Win32) do not support binding multicast
00112 // addresses. Using this option will always cause an <open> error.
00113 // - It's not strictly possible for user code to do this level of filtering
00114 // w/out the bind; some environments support ways to determine which address
00115 // a message was sent _to_, but this class interface does not support access
00116 // to that info.
00117 // - The address (and port#) passed to <open> (or the first <subscribe>, if
00118 // <open> is not explicitly invoked) is the one that is bound.
00119 //
00120 /// Disable address bind. (Bind only port.)
00121 // Note that this might seem odd, but we need a way to distinquish between
00122 // default behavior, which might or might not be to bind, and explicitely
00123 // choosing to bind or not to bind--which "is the question." ;-)
00124 OPT_BINDADDR_NO = 0,
00125 /// Enable address bind. (Bind port and address.)
00126 OPT_BINDADDR_YES = 1,
00127 /// Default value for BINDADDR option. (Environment-dependent.)
00128 #if defined (ACE_LACKS_PERFECT_MULTICAST_FILTERING) \
00129 && (ACE_LACKS_PERFECT_MULTICAST_FILTERING == 1)
00130 // Platforms that don't support perfect filtering. Note that perfect
00131 // filtering only really applies to multicast traffic, not unicast
00132 // or broadcast.
00133 DEFOPT_BINDADDR = OPT_BINDADDR_YES,
00134 # else
00135 // At least some Win32 OS's can not bind mcast addr, so disable it.
00136 // General-purpose default behavior is 'disabled', since effect is
00137 // environment-specific and side-effects might be surprising.
00138 DEFOPT_BINDADDR = OPT_BINDADDR_NO,
00139 #endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING = 1) */
00140 //
00141 /// Define the interpretation of 'NULL' as a recv interface specification.
00142 // If the interface part of a multicast address specification is NULL, it
00143 // will be interpreted to mean either "the default interface" or "all
00144 // interfaces", depending on the setting of this option.
00145 // Notes:
00146 // - The 'nulliface_all' option can not be used in environments which do
00147 // not fully support the <ACE_Sock_Connect::get_ip_interfaces> method
00148 // (e.g. non-Windows).
00149 // If it is, using NULL for iface will _always_ fail.
00150 // - The default behavior in most IP stacks is to use the 'default' interface,
00151 // where 'default' has rather ad-hoc semantics.
00152 // - This applies only to receives, not sends (which always use only one
00153 // interface; NULL means use the "system default" interface).
00154 // Supported values:
00155 /// If (net_if==NULL), use default interface.
00156 // Note that this might seem odd, but we need a way to distinquish between
00157 // default behavior, which might or might not be to bind, and explicitely
00158 // choosing to bind or not to bind--which "is the question." ;-)
00159 OPT_NULLIFACE_ONE = 0,
00160 /// If (net_if==NULL), use all mcast interfaces.
00161 OPT_NULLIFACE_ALL = 2,
00162 /// Default value for NULLIFACE option. (Environment-dependent.)
00163 #ifdef ACE_WIN32
00164 // This is the (ad-hoc) legacy behavior for Win32/WinSock.
00165 // Notice: Older version of WinSock/MSVC may not get all multicast-capable
00166 // interfaces (e.g. PPP interfaces).
00167 DEFOPT_NULLIFACE = OPT_NULLIFACE_ALL,
00168 #else
00169 // General-purpose default behavior (as per legacy behavior).
00170 DEFOPT_NULLIFACE = OPT_NULLIFACE_ONE,
00171 #endif /* ACE_WIN32 */
00172 /// All default options.
00173 DEFOPTS = DEFOPT_BINDADDR | DEFOPT_NULLIFACE
00174 };
|
|
|
Ctor - Create an unitialized instance and define per-instance optional functionality. 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 119 of file SOCK_Dgram_Mcast.cpp. References ACE_TRACE, and options.
00120 : opts_ (opts), 00121 send_net_if_ (0) 00122 { 00123 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast"); 00124 } |
|
|
Dtor - Release all resources and implicitly or explicitly unsubscribe from all currently subscribed groups. 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 127 of file SOCK_Dgram_Mcast.cpp. References ACE_TRACE, clear_subs_list, and send_net_if_.
00128 {
00129 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::~ACE_SOCK_Dgram_Mcast");
00130
00131 // Free memory and optionally unsubscribe from currently subscribed group(s).
00132 delete [] this->send_net_if_;
00133 this->clear_subs_list ();
00134 }
|
|
|
Empty the dynamic subscription list.
Definition at line 617 of file SOCK_Dgram_Mcast.cpp. References ACE_GUARD_RETURN, ACE_MT, and ACE_TRACE. Referenced by ~ACE_SOCK_Dgram_Mcast.
00618 {
00619 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::clear_subs_list");
00620 int result = 0;
00621
00622 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE)
00623 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard,
00624 this->subscription_list_lock_, -1));
00625 subscription_list_iter_t iter (this->subscription_list_);
00626 for (; !iter.done (); /*Hack: Do _not_ ::advance after remove*/)
00627 {
00628 ip_mreq *pm = iter.next ();
00629 iter.remove ();
00630 delete pm;
00631 }
00632 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */
00633 return result;
00634 }
|
|
|
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 56 of file SOCK_Dgram_Mcast.cpp. References ACE_BEGIN_DUMP, ACE_BIT_ENABLED, ACE_DEBUG, ACE_END_DUMP, ACE_GUARD, ACE_LIB_TEXT, ACE_MT, ACE_NTOHL, ACE_TCHAR, ACE_TRACE, ACE_SDM_helpers::addr_to_string, ip_mreq::imr_interface, LM_DEBUG, MAXNAMELEN, OPT_BINDADDR_YES, OPT_NULLIFACE_ALL, ACE_OS_String::strcmp, and ACE_OS_String::strcpy.
00057 {
00058 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::dump");
00059
00060 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00061
00062 # if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE)
00063 ACE_TCHAR addr_string[MAXNAMELEN + 1];
00064
00065 ACE_DEBUG ((LM_DEBUG,
00066 ACE_LIB_TEXT ("\nOptions: bindaddr=%s, nulliface=%s\n"),
00067 ACE_BIT_ENABLED (this->opts_, OPT_BINDADDR_YES) ?
00068 ACE_LIB_TEXT ("<Bound>") : ACE_LIB_TEXT ("<Not Bound>"),
00069 ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL) ?
00070 ACE_LIB_TEXT ("<All Ifaces>") : ACE_LIB_TEXT ("<Default Iface>")));
00071
00072 // Show default send addr, port#, and interface.
00073 ACE_SDM_helpers::addr_to_string (this->send_addr_, addr_string,
00074 sizeof addr_string, 0);
00075 ACE_DEBUG ((LM_DEBUG,
00076 ACE_LIB_TEXT ("Send addr=%s iface=%s\n"),
00077 addr_string,
00078 this->send_net_if_ ? this->send_net_if_
00079 : ACE_LIB_TEXT ("<default>")));
00080
00081 // Show list of subscribed addresses.
00082 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("Subscription list:\n")));
00083
00084 ACE_MT (ACE_GUARD (ACE_SDM_LOCK, guard, this->subscription_list_lock_));
00085 subscription_list_iter_t iter (this->subscription_list_);
00086 for ( ; !iter.done (); iter.advance ())
00087 {
00088 ACE_TCHAR iface_string[MAXNAMELEN + 1];
00089 ip_mreq *pm = iter.next ();
00090
00091 // Get subscribed address (w/out port# info - not relevant).
00092 ACE_INET_Addr ip_addr (ACE_static_cast (u_short, 0),
00093 ACE_NTOHL (pm->IMR_MULTIADDR.s_addr));
00094 ACE_SDM_helpers::addr_to_string (ip_addr, addr_string,
00095 sizeof addr_string, 1);
00096
00097 // Get interface address/specification.
00098 ACE_INET_Addr if_addr (ACE_static_cast (u_short, 0),
00099 ACE_NTOHL (pm->imr_interface.s_addr));
00100 ACE_SDM_helpers::addr_to_string (if_addr, iface_string,
00101 sizeof iface_string, 1);
00102 if (ACE_OS_String::strcmp (iface_string, ACE_LIB_TEXT ("0.0.0.0")) == 0)
00103 // Receives on system default iface. (Note that null_iface_opt_
00104 // option processing has already occurred.)
00105 ACE_OS_String::strcpy (iface_string, ACE_LIB_TEXT ("<default>"));
00106
00107 // Dump info.
00108 ACE_DEBUG ((LM_DEBUG,
00109 ACE_LIB_TEXT ("\taddr=%s iface=%s\n"),
00110 addr_string,
00111 iface_string));
00112 }
00113 # endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */
00114 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00115 }
|
|
||||||||||||||||
|
Definition at line 325 of file SOCK_Dgram_Mcast.cpp. References ACE_BIT_ENABLED, ACE_ERROR, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_TCHAR, ACE_TRACE, ACE_SDM_helpers::addr_to_string, ENXIO, ACE_INET_Addr::get_ip_address, ACE_INET_Addr::get_port_number, LM_ERROR, make_multicast_ifaddr, MAXNAMELEN, OPT_BINDADDR_YES, send_addr_, ACE_INET_Addr::set_port_number, and subscribe_i. Referenced by subscribe.
00328 {
00329 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::join");
00330 ACE_INET_Addr subscribe_addr = mcast_addr;
00331
00332 // If port# is 0, insert bound port# if it is set. (To satisfy lower-level
00333 // port# validation.)
00334 u_short def_port_number = this->send_addr_.get_port_number ();
00335 if (subscribe_addr.get_port_number () == 0
00336 && def_port_number != 0)
00337 {
00338 subscribe_addr.set_port_number (def_port_number);
00339 }
00340
00341 // Check for port# different than bound port#.
00342 u_short sub_port_number = mcast_addr.get_port_number ();
00343 if (sub_port_number != 0
00344 && def_port_number != 0
00345 && sub_port_number != def_port_number)
00346 {
00347 ACE_ERROR ((LM_ERROR,
00348 ACE_LIB_TEXT ("Subscribed port# (%u) different than bound ")
00349 ACE_LIB_TEXT ("port# (%u).\n"),
00350 (u_int) sub_port_number,
00351 (u_int) def_port_number));
00352 errno = ENXIO;
00353 return -1;
00354 }
00355
00356 // If bind_addr_opt_ is enabled, check for address different than
00357 // bound address.
00358 if (ACE_BIT_ENABLED (this->opts_, OPT_BINDADDR_YES)
00359 && this->send_addr_.get_ip_address () != INADDR_ANY
00360 && this->send_addr_.get_ip_address () != mcast_addr.get_ip_address ())
00361 {
00362 ACE_TCHAR sub_addr_string[MAXNAMELEN + 1];
00363 ACE_TCHAR bound_addr_string[MAXNAMELEN + 1];
00364 ACE_SDM_helpers::addr_to_string (mcast_addr, sub_addr_string,
00365 sizeof sub_addr_string, 1);
00366 ACE_SDM_helpers::addr_to_string (this->send_addr_, bound_addr_string,
00367 sizeof bound_addr_string, 1);
00368 ACE_ERROR ((LM_ERROR,
00369 ACE_LIB_TEXT ("Subscribed address (%s) different than ")
00370 ACE_LIB_TEXT ("bound address (%s).\n"),
00371 sub_addr_string,
00372 bound_addr_string));
00373 errno = ENXIO;
00374 return -1;
00375 }
00376
00377 // Attempt subscription.
00378 int result = this->subscribe_i (subscribe_addr, reuse_addr, net_if);
00379
00380 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE)
00381 if (result == 0)
00382 {
00383 // Add this addr/iface info to the list of subscriptions.
00384 // (Assumes this is unique addr/iface combo - most systems don't allow
00385 // re-sub to same addr/iface.)
00386 ip_mreq *pmreq = new ip_mreq;
00387 // (should not fail)
00388 if (this->make_multicast_ifaddr (pmreq, subscribe_addr, net_if) != -1)
00389 {
00390 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard,
00391 this->subscription_list_lock_, -1));
00392 this->subscription_list_.insert_tail (pmreq);
00393 return 0;
00394 }
00395 // this still isn't really right. If ACE_GUARD_RETURN fails, we leak.
00396 // Need to add one of Chris' fancy ace auto pointers (bound?).
00397 delete pmreq;
00398 }
00399 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */
00400
00401 return result >= 0 ? 0 : result;
00402 }
|
|
||||||||||||
|
Definition at line 527 of file SOCK_Dgram_Mcast.cpp. References ACE_GUARD_RETURN, ACE_MT, ACE_TCHAR, ACE_TRACE, ACE_SDM_helpers::is_equal, make_multicast_ifaddr, and unsubscribe_i. Referenced by unsubscribe, and unsubscribe_ifs.
00529 {
00530 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::leave");
00531 // Unsubscribe.
00532 int result = this->unsubscribe_i (mcast_addr,
00533 net_if);
00534
00535 #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE)
00536 // (Unconditionally) Remove this addr/if from subscription list.
00537 // (Addr/if is removed even if unsubscribe failed)
00538 ip_mreq tgt_mreq;
00539 if (this->make_multicast_ifaddr (&tgt_mreq,
00540 mcast_addr,
00541 net_if) != -1)
00542 {
00543 ACE_MT (ACE_GUARD_RETURN (ACE_SDM_LOCK, guard,
00544 this->subscription_list_lock_, -1));
00545 subscription_list_iter_t iter (this->subscription_list_);
00546 for (; !iter.done (); iter.advance ())
00547 {
00548 ip_mreq *pm = iter.next ();
00549 if (ACE_SDM_helpers::is_equal (*pm, tgt_mreq))
00550 {
00551 iter.remove ();
00552 delete pm;
00553 break;
00554 }
00555 }
00556 }
00557 #endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */
00558
00559 return result >= 0 ? 0 : result;
00560 }
|
|
||||||||||||||||
|
Create a multicast addr/if pair, in format useful for system calls. If mreq param is NULL, just verify the passed addr/interface specs.
Definition at line 637 of file SOCK_Dgram_Mcast.cpp. References ACE_HTONL, ACE_TCHAR, ACE_TRACE, ACE_OS::atoi, ACE_INET_Addr::get_ip_address, ACE_INET_Addr::get_port_number, ip_mreq::imr_interface, ACE_OS::ioctl, ACE_INET_Addr::set, SIOCGIFADDR, and ACE_OS_String::strcpy. Referenced by join, leave, open_i, subscribe_i, subscribe_ifs, and unsubscribe_i.
00640 {
00641 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::make_multicast_ifaddr");
00642 ip_mreq lmreq; // Scratch copy.
00643 if (net_if != 0)
00644 {
00645 #if defined (ACE_WIN32)
00646 // This port number is not necessary, just convenient
00647 ACE_INET_Addr interface_addr;
00648 if (interface_addr.set (mcast_addr.get_port_number (), net_if) == -1)
00649 return -1;
00650 lmreq.imr_interface.s_addr =
00651 ACE_HTONL (interface_addr.get_ip_address ());
00652 #else
00653 ifreq if_address;
00654
00655 #if defined (ACE_PSOS)
00656 // Look up the interface by number, not name.
00657 if_address.ifr_ifno = ACE_OS::atoi (net_if);
00658 #else
00659 ACE_OS_String::strcpy (if_address.ifr_name, net_if);
00660 #endif /* defined (ACE_PSOS) */
00661
00662 if (ACE_OS::ioctl (this->get_handle (),
00663 SIOCGIFADDR,
00664 &if_address) == -1)
00665 return -1;
00666
00667 sockaddr_in *socket_address;
00668 socket_address = ACE_reinterpret_cast (sockaddr_in*,
00669 &if_address.ifr_addr);
00670 lmreq.imr_interface.s_addr = socket_address->sin_addr.s_addr;
00671 #endif /* ACE_WIN32 */
00672 }
00673 else
00674 lmreq.imr_interface.s_addr = INADDR_ANY;
00675
00676 lmreq.IMR_MULTIADDR.s_addr = ACE_HTONL (mcast_addr.get_ip_address ());
00677
00678 // Set return info, if requested.
00679 if (ret_mreq)
00680 *ret_mreq = lmreq;
00681
00682 return 0;
00683 }
|
|
||||||||||||||||
|
Create a multicast addr/if pair. This method factors out common code called by <make_multicast_address> and <subscribe>.
|
|
||||||||||||||||
|
Explicitly open/bind the socket and define the network interface and default multicast address used for sending messages. 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 137 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.
00140 {
00141 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open");
00142
00143 // Only perform the <open> initialization if we haven't been opened
00144 // earlier.
00145 // No sanity check? We should probably flag an error if the user
00146 // makes multiple calls to open().
00147 if (this->get_handle () != ACE_INVALID_HANDLE)
00148 return 0;
00149
00150 // Invoke lower-layer ::open.
00151 if (ACE_SOCK::open (SOCK_DGRAM,
00152 mcast_addr.get_type (),
00153 0, // always use 0
00154 reuse_addr) == -1)
00155 return -1;
00156
00157 return open_i (mcast_addr, net_if, reuse_addr);
00158 }
|
|
||||||||||||||||
|
Contains common open functionality so that inheriting classes can reuse it.
Definition at line 161 of file SOCK_Dgram_Mcast.cpp. References ACE_BIT_DISABLED, ACE_DEBUG, ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, ACE_SOCK::get_local_addr, ACE_INET_Addr::get_port_number, ACE_Addr::get_type, ip_mreq::imr_interface, IP_MULTICAST_IF, LM_DEBUG, make_multicast_ifaddr, OPT_BINDADDR_YES, send_addr_, send_net_if_, ACE_INET_Addr::set, ACE_SOCK::set_option, ACE_INET_Addr::set_port_number, ACE_SOCK_Dgram::shared_open, ACE_OS_String::strcpy, and ACE_OS_String::strlen. Referenced by open.
00164 {
00165 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::open_i");
00166 // ACE_SOCK::open calls this if reuse_addr is set, so we only need to
00167 // process port reuse option.
00168 if (reuse_addr)
00169 {
00170 #if defined (SO_REUSEPORT)
00171 int one = 1;
00172 if (this->ACE_SOCK::set_option (SOL_SOCKET,
00173 SO_REUSEPORT,
00174 &one,
00175 sizeof one) == -1)
00176 return -1;
00177 #endif /* SO_REUSEPORT */
00178 }
00179
00180 // Create an address/port# to bind the socket to. Use mcast_addr to
00181 // initialize bind_addy to pick up the correct protocol family. If
00182 // OPT_BINDADDR_YES is set, then we're done. Else use mcast_addr's
00183 // port number and use the "any" address.
00184 ACE_INET_Addr bind_addy (mcast_addr);
00185 if (ACE_BIT_DISABLED (this->opts_, OPT_BINDADDR_YES))
00186 {
00187 // Bind to "any" address and explicit port#.
00188 if (bind_addy.set (mcast_addr.get_port_number ()) == -1)
00189 return -1;
00190 }
00191
00192 // Bind to the address (which may be INADDR_ANY) and port# (which may be 0)
00193 if (ACE_SOCK_Dgram::shared_open (bind_addy, bind_addy.get_type ()) == -1)
00194 return -1;
00195
00196 // Cache the actual bound address (which may be INADDR_ANY)
00197 // and the actual bound port# (which will be a valid, non-zero port#).
00198 ACE_INET_Addr bound_addy;
00199 if (this->get_local_addr (bound_addy) == -1)
00200 {
00201 // (Unexpected failure - should be bound to something)
00202 if (bound_addy.set (bind_addy) == -1)
00203 {
00204 // (Shouldn't happen - bind_addy is a valid addy; punt.)
00205 return -1;
00206 }
00207 }
00208
00209 this->send_addr_ = mcast_addr;
00210 this->send_addr_.set_port_number (bound_addy.get_port_number ());
00211 if (net_if)
00212 {
00213 #if defined (IP_MULTICAST_IF) && (IP_MULTICAST_IF != 0)
00214 ip_mreq send_mreq;
00215 if (this->make_multicast_ifaddr (&send_mreq,
00216 mcast_addr,
00217 net_if) == -1)
00218 return -1;
00219 if (this->ACE_SOCK::set_option (IPPROTO_IP,
00220 IP_MULTICAST_IF,
00221 &(send_mreq.imr_interface),
00222 sizeof send_mreq.imr_interface) == -1)
00223 return -1;
00224 this->send_net_if_ = new ACE_TCHAR[ACE_OS_String::strlen (net_if) + 1];
00225 ACE_OS_String::strcpy (this->send_net_if_, net_if);
00226 #else
00227 // Send interface option not supported - ignore it.
00228 // (We may have been invoked by ::subscribe, so we have to allow
00229 // a non-null interface parameter in this function.)
00230 ACE_DEBUG ((LM_DEBUG,
00231 ACE_LIB_TEXT ("Send interface specification not ")
00232 ACE_LIB_TEXT ("supported - IGNORED.\n")));
00233 #endif // IP_MULTICAST_IF
00234 }
00235
00236 return 0;
00237 }
|
|
||||||||||||||||
|
Send <n> <iovecs>, using the multicast address and network interface defined by the first <open> or <subscribe>.
Definition at line 38 of file SOCK_Dgram_Mcast.i. References ACE_TRACE, and ACE_SOCK_Dgram::send.
00041 {
00042 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::send");
00043 return this->ACE_SOCK_Dgram::send (iov,
00044 n,
00045 this->send_addr_,
00046 flags);
00047 }
|
|
||||||||||||||||
|
Send <n> bytes in <buf>, using the multicast address and network interface defined by the first <open> or <subscribe>.
Definition at line 26 of file SOCK_Dgram_Mcast.i. References ACE_TRACE, and ACE_SOCK_Dgram::send.
00029 {
00030 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::send");
00031 return this->ACE_SOCK_Dgram::send (buf,
00032 n,
00033 this->send_addr_,
00034 flags);
00035 }
|
|
||||||||||||
|
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. Use <ACE_SOCK::set_option> directly to set anything else.
Definition at line 5 of file SOCK_Dgram_Mcast.i. References ACE_TRACE, ACE_IPC_SAP::get_handle, ACE_Addr::get_type, send_addr_, and ACE_SOCK::set_option.
00007 {
00008 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::set_option");
00009
00010 if (this->get_handle () == ACE_INVALID_HANDLE)
00011 return -1;
00012
00013 int level = IPPROTO_IP;
00014 #if defined (IPPROTO_IPV6)
00015 if (this->send_addr_.get_type () == PF_INET6)
00016 level = IPPROTO_IPV6;
00017 #endif /* IPPROTO_IPV6 */
00018
00019 return this->ACE_SOCK::set_option (level,
00020 option,
00021 &optval,
00022 sizeof (optval));
00023 }
|
|
||||||||||||||||||||||||
|
Join a multicast group on a given interface (or all interfaces, if supported). 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). NOTICE - This method has been deprecated, please use join() instead. In addition, the following paramters have also been deprecated: <protocol_family> and <protocol> have no effect. Definition at line 310 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 406 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, IP_ADD_MEMBERSHIP, make_multicast_ifaddr, open, ACE_SOCK::set_option, and subscribe_ifs. Referenced by join.
00409 {
00410 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_i");
00411 ip_mreq mreq;
00412
00413 // Open the socket IFF this is the first ::subscribe and ::open
00414 // was not explicitly invoked.
00415 if (this->open (mcast_addr,
00416 net_if,
00417 reuse_addr) == -1)
00418 return -1;
00419
00420 // Only do this if net_if == 0, i.e., INADDR_ANY
00421 if (net_if == 0)
00422 {
00423 int result = this->subscribe_ifs (mcast_addr,
00424 net_if,
00425 reuse_addr);
00426 // Check for error or "short-circuit" return.
00427 if (result != 0)
00428 return result;
00429 }
00430
00431 // Create multicast addr/if struct.
00432 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
00433 return -1;
00434
00435 // Tell IP stack to pass messages sent to this group.
00436 // Note, this is not IPv6 compliant.
00437 else if (this->ACE_SOCK::set_option (IPPROTO_IP,
00438 IP_ADD_MEMBERSHIP,
00439 &mreq,
00440 sizeof mreq) == -1)
00441 return -1;
00442
00443 return 0;
00444 }
|
|
||||||||||||||||
|
Subscribe to a multicast address on one or more network interface(s). (No QoS support.).
Definition at line 240 of file SOCK_Dgram_Mcast.cpp. References ACE_BIT_ENABLED, ACE_LIB_TEXT, ACE_TCHAR, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, ACE_INET_Addr::get_ip_address, ACE_Sock_Connect::get_ip_interfaces, INADDR_LOOPBACK, make_multicast_ifaddr, OPT_NULLIFACE_ALL, and subscribe. Referenced by subscribe_i.
00243 {
00244 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe_ifs");
00245
00246 if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL)
00247 && net_if == 0)
00248 {
00249 // Subscribe on all local multicast-capable network interfaces, by
00250 // doing recursive calls with specific interfaces.
00251
00252 ACE_INET_Addr *if_addrs = 0;
00253 size_t if_cnt;
00254
00255 if (ACE_Sock_Connect::get_ip_interfaces (if_cnt, if_addrs) != 0)
00256 return -1;
00257
00258 size_t nr_subscribed = 0;
00259
00260 if (if_cnt < 2)
00261 {
00262 if (this->subscribe (mcast_addr,
00263 reuse_addr,
00264 ACE_LIB_TEXT ("0.0.0.0")) == 0)
00265 ++nr_subscribed;
00266 }
00267 else
00268 {
00269 // Iterate through all the interfaces, figure out which ones
00270 // offer multicast service, and subscribe to them.
00271 while (if_cnt > 0)
00272 {
00273 --if_cnt;
00274
00275 // Convert to 0-based for indexing, next loop check.
00276 if (if_addrs[if_cnt].get_ip_address () == INADDR_LOOPBACK)
00277 continue;
00278 if (this->subscribe (mcast_addr,
00279 reuse_addr,
00280 ACE_TEXT_CHAR_TO_TCHAR
00281 (if_addrs[if_cnt].get_host_addr ())) == 0)
00282 ++nr_subscribed;
00283 }
00284 }
00285
00286 delete [] if_addrs;
00287
00288 if (nr_subscribed == 0)
00289 {
00290 errno = ENODEV;
00291 return -1;
00292 }
00293
00294 // 1 indicates a "short-circuit" return. This handles the
00295 // recursive behavior of checking all the interfaces.
00296 return 1;
00297 }
00298
00299 // Validate passed multicast addr and iface specifications.
00300 if (this->make_multicast_ifaddr (0,
00301 mcast_addr,
00302 net_if) == -1)
00303 return -1;
00304
00305 return 0;
00306 }
|
|
|
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. This method has been deprecated. Since a list of groups is not maintained (except when ACE_SOCK_DGRAM_MCAST_DUMPABLE is defined), it isn't possible to unsubscribe to all the groups without closing the socket. Therefore, if applications wish to unsubscribe to all groups without closing the socket, they much keep track of the subscriptions and call the above unsubscribe () for each. Definition at line 597 of file SOCK_Dgram_Mcast.cpp. References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TRACE, and LM_INFO.
00598 {
00599 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe");
00600
00601 // Can't implement this reliably without keeping an expensive list,
00602 // and can't close the socket since the caller may want to continue
00603 // using the socket to send() or join() new groups. Even if we
00604 // wanted to be clever and reopen the socket, we'd need to know what
00605 // options had been set, and reset them--and we have no way of doing
00606 // that either. :-(
00607 // Should this return -1?
00608 ACE_ERROR_RETURN ((LM_INFO,
00609 ACE_LIB_TEXT ("ACE_SOCK_Dgram_Mcast::unsubscribe (void) ")
00610 ACE_LIB_TEXT ("has been deprecated. You must either ")
00611 ACE_LIB_TEXT ("close to socket to unsubscribe to all ")
00612 ACE_LIB_TEXT ("or unsubscribe to each individually.\n")),
00613 0);
00614 }
|
|
||||||||||||||||||||
|
Leave a multicast group on a given interface (or all interfaces, if supported). 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>). NOTICE - This method has been deprecated. Please use leave() instead. In addition, <protocol_family> and <protocol> have no effect. Definition at line 513 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, and leave.
|
|
||||||||||||
|
Do unsubscription processing w/out udpating subscription list.
Definition at line 564 of file SOCK_Dgram_Mcast.cpp. References ACE_TCHAR, ACE_TRACE, IP_DROP_MEMBERSHIP, make_multicast_ifaddr, ACE_SOCK::set_option, and unsubscribe_ifs. Referenced by leave.
00566 {
00567 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_i");
00568
00569 int result = this->unsubscribe_ifs (mcast_addr,
00570 net_if);
00571
00572 // Check for error or "short-circuit" return.
00573 if (result != 0)
00574 return result;
00575
00576 // Validate addr/if specifications and create addr/if struct.
00577 ip_mreq mreq;
00578 if (this->make_multicast_ifaddr (&mreq, mcast_addr, net_if) == -1)
00579 {
00580 return -1;
00581 }
00582 // Tell network device driver to stop reading datagrams with the
00583 // <mcast_addr>.
00584 // Note, this is not IPv6 friendly...
00585 else if (ACE_SOCK::set_option (IPPROTO_IP,
00586 IP_DROP_MEMBERSHIP,
00587 &mreq,
00588 sizeof mreq) == -1)
00589 {
00590 return -1;
00591 }
00592
00593 return 0;
00594 }
|
|
||||||||||||
|
Unsubscribe from a multicast address on one or more network interface(s).
Definition at line 447 of file SOCK_Dgram_Mcast.cpp. References ACE_BIT_ENABLED, ACE_LIB_TEXT, ACE_TCHAR, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, ACE_INET_Addr::get_ip_address, ACE_Sock_Connect::get_ip_interfaces, INADDR_LOOPBACK, leave, and OPT_NULLIFACE_ALL. Referenced by unsubscribe_i.
00449 {
00450 ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe_ifs");
00451
00452
00453 if (ACE_BIT_ENABLED (this->opts_, OPT_NULLIFACE_ALL)
00454 && net_if == 0)
00455 {
00456 // Unsubscribe on all local multicast-capable network interfaces, by
00457 // doing recursive calls with specific interfaces.
00458
00459 ACE_INET_Addr *if_addrs = 0;
00460 size_t if_cnt;
00461
00462 // NOTE - <get_ip_interfaces> doesn't always get all of the
00463 // interfaces. In particular, it may not get a PPP interface. This
00464 // is a limitation of the way <get_ip_interfaces> works with
00465 // old versions of MSVC. The reliable way of getting the interface list
00466 // is available only with MSVC 5 and newer.
00467 if (ACE_Sock_Connect::get_ip_interfaces (if_cnt, if_addrs) != 0)
00468 return -1;
00469
00470 size_t nr_unsubscribed = 0;
00471
00472 if (if_cnt < 2)
00473 {
00474 if (this->leave (mcast_addr,
00475 ACE_LIB_TEXT ("0.0.0.0")) == 0)
00476 ++nr_unsubscribed;
00477 }
00478 else
00479 {
00480 while (if_cnt > 0)
00481 {
00482 --if_cnt;
00483 // Convert to 0-based for indexing, next loop check
00484 if (if_addrs[if_cnt].get_ip_address () == INADDR_LOOPBACK)
00485 continue;
00486 if (this->leave (mcast_addr,
00487 ACE_TEXT_CHAR_TO_TCHAR
00488 (if_addrs[if_cnt].get_host_addr ())) == 0)
00489 ++nr_unsubscribed;
00490 }
00491 }
00492
00493 delete [] if_addrs;
00494
00495 if (nr_unsubscribed == 0)
00496 {
00497 errno = ENODEV;
00498 return -1;
00499 }
00500
00501 return 1;
00502 }
00503
00504 return 0;
00505 }
|
|
|
Declare the dynamic allocation hooks.
Reimplemented from ACE_SOCK_Dgram. Definition at line 347 of file SOCK_Dgram_Mcast.h. |
|
|
Per-instance options..
Definition at line 398 of file SOCK_Dgram_Mcast.h. |
|
|
Multicast address to which local <send> methods send datagrams.
Definition at line 401 of file SOCK_Dgram_Mcast.h. Referenced by join, open_i, and set_option. |
|
|
Network interface to which all <send> methods send multicast datagrams.
Definition at line 403 of file SOCK_Dgram_Mcast.h. Referenced by open_i, and ~ACE_SOCK_Dgram_Mcast. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002