diff options
author | Erik Sohns <erik.sohns@posteo.de> | 2021-08-28 20:12:42 +0200 |
---|---|---|
committer | Erik Sohns <erik.sohns@posteo.de> | 2021-08-28 20:12:42 +0200 |
commit | aa5239614bb958573dc96402f371701fa2401b34 (patch) | |
tree | 50ab5374e203e8787e5c6cc5386cd9bd41230e99 /ACE/ace/SOCK_Dgram_Mcast.h | |
parent | 2f9886504dde18e2aec8d9af2558467db22518fa (diff) | |
download | ATCD-aa5239614bb958573dc96402f371701fa2401b34.tar.gz |
Revert "make some 'private' members 'protected' to support sub-classing"
This reverts commit f2f00f8252f3d434697986185a1d806b7270191f.
Diffstat (limited to 'ACE/ace/SOCK_Dgram_Mcast.h')
-rw-r--r-- | ACE/ace/SOCK_Dgram_Mcast.h | 814 |
1 files changed, 407 insertions, 407 deletions
diff --git a/ACE/ace/SOCK_Dgram_Mcast.h b/ACE/ace/SOCK_Dgram_Mcast.h index b5110621ead..5c4c835eccd 100644 --- a/ACE/ace/SOCK_Dgram_Mcast.h +++ b/ACE/ace/SOCK_Dgram_Mcast.h @@ -1,407 +1,407 @@ -// -*- C++ -*-
-
-//=============================================================================
-/**
- * @file SOCK_Dgram_Mcast.h
- *
- * @author Irfan Pyrali <irfan@cs.wustl.edu>
- * @author Tim Harrison <harrison@cs.wustl.edu>
- * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
- * @author Bill Fulton <bill_a_fulton@raytheon.com>
- * @author Don Hinton <dhinton@objectsciences.com>
- */
-//=============================================================================
-
-#ifndef ACE_SOCK_DGRAM_MCAST_H
-#define ACE_SOCK_DGRAM_MCAST_H
-
-#include /**/ "ace/pre.h"
-
-#include /**/ "ace/ACE_export.h"
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-# pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
-#include "ace/SOCK_Dgram.h"
-#include "ace/INET_Addr.h"
-
-#if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE)
-# include "ace/Containers_T.h"
-# include "ace/Synch_Traits.h"
-# include "ace/Thread_Mutex.h"
-# if !defined (ACE_SDM_LOCK)
-# define ACE_SDM_LOCK ACE_SYNCH_MUTEX
-# endif /* ACE_SDM_LOCK */
-#endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */
-
-ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-
-/**
- * @class ACE_SOCK_Dgram_Mcast
- *
- * @brief Defines the ACE socket wrapper for UDP/IP multicast.
- *
- * Supports multiple simultaneous subscriptions, unsubscription from one or
- * all subscriptions, and independent send/recv address and interface
- * specifications. Constructor arguments determine per-instance optional
- * functionality.
- *
- * Note that multicast semantics and implementation details are @i 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:
- * - Send and receive addresses and network interfaces, but not port number,
- * are independent. While this instance is open, one send interface (and a
- * default send address) is in effect and 0, 1, or multiple receive
- * addresses/interfaces are in effect.
- * - The first open()/subscribe() invocation defines the network interface
- * and default address used for all sends by this instance, defines the
- * port number and optionally the multicast address bound to the underlying
- * socket, and defines the (one) port number that is used for all subscribes
- * (subsequent subscribes must pass the same port number or 0).
- * - The default loopback state is not explicitly set; the environment will
- * determine the default state. Note that some environments (e.g. some
- * Windows versions) do not allow the default to be changed, and that the
- * semantics of loopback control are environment dependent (e.g. sender vs.
- * receiver control).
- * - In general, due to multicast design and implementation quirks/bugs, it is
- * difficult to tell which address a received message was sent to or which
- * interface it was received on (even if only one subscription is active).
- * However, there are filtering options that can be applied, to narrow it
- * down considerably.
- *
- * Interface specification notes (for subscribe() and unsubscribe()):
- * - If @a net_if == 0, the @c OPT_NULLIFACE_ALL and @c OPT_NULLIFACE_ONE
- * options determine whether only the system default interface
- * (if @c OPT_NULLIFACE_ONE is set) or all interfaces (if
- * @c OPT_NULLIFACE_ALL is set) is affected. Specifying all interfaces
- * functions correctly only on:
- * + Windows
- * + Platforms with the ACE_HAS_GETIFADDRS config setting (includes Linux)
- * + Platforms which accept the IP address as an interface
- * name/specification
- * + Systems with only one non-loopback interface.
- * Other platforms require additional supporting code.
- * - Multiple subscriptions for the same address but different interfaces is
- * normally supported, but re-subscription to an address/interface that is
- * already subscribed is normally not allowed.
- * - The @a net_if interface specification syntax is environment-specific.
- * UNIX systems will normally use device specifications such as "le0" or
- * "elxl1", while other systems will use the IP address of the interface.
- * Some platforms, such as pSoS, support only cardinal numbers as network
- * interface specifications; for these platforms, just give these numbers in
- * string form and join() will convert them into numbers.
- */
-class ACE_Export ACE_SOCK_Dgram_Mcast : public ACE_SOCK_Dgram
-{
-public:
-
- /**
- * @brief Option parameters.
- *
- * These control per-instance optional functionality. They are set via
- * an optional constructor argument.
- *
- * @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.
- */
- enum options
- {
- /* Define whether a specific multicast address (in addition to the port
- * number) is bound to the socket.
- * @note:
- * - Effect of doing this is stack/environment dependent, but in most
- * environments can be used to filter out unwanted unicast, broadcast,
- * and (other) multicast messages sent to the same port number.
- * - Some IP stacks (e.g. some Windows) do not support binding multicast
- * addresses. Using this option will always cause an open() error.
- * - It's not strictly possible for user code to do this level of filtering
- * without the bind; some environments support ways to determine which
- * address a message was sent to, but this class interface does not
- * support access to that information.
- * - The address (and port number) passed to open() (or the first
- * join(), if open() is not explicitly invoked) is the one that is bound.
- */
-
- /// Disable address bind. (Bind only port.)
- /// @note This might seem odd, but we need a way to distinguish between
- /// default behavior, which might or might not be to bind, and explicitly
- /// choosing to bind or not to bind--which "is the question." ;-)
- OPT_BINDADDR_NO = 0,
- /// Enable address bind. (Bind port and address.)
- OPT_BINDADDR_YES = 1,
- /// Default value for BINDADDR option. (Environment-dependent.)
-#if defined (ACE_LACKS_PERFECT_MULTICAST_FILTERING) \
- && (ACE_LACKS_PERFECT_MULTICAST_FILTERING == 1)
- /// Platforms that don't support perfect filtering. Note that perfect
- /// filtering only really applies to multicast traffic, not unicast
- /// or broadcast.
- DEFOPT_BINDADDR = OPT_BINDADDR_YES,
-# else
- /// At least some Win32 OS's can not bind mcast addr, so disable it.
- /// General-purpose default behavior is 'disabled', since effect is
- /// environment-specific and side-effects might be surprising.
- DEFOPT_BINDADDR = OPT_BINDADDR_NO,
-#endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING = 1) */
-
- /*
- * Define the interpretation of NULL as a join interface specification.
- * If the interface part of a multicast address specification is NULL, it
- * will be interpreted to mean either "the default interface" or "all
- * interfaces", depending on the setting of this option.
- * @note
- * - The @c OPT_NULLIFACE_ALL option can be used only in the following
- * environments:
- * + Windows
- * + Platforms with the ACE_HAS_GETIFADDRS config setting (includes
- * Linux)
- * + Platforms which accept the IP address as an interface
- * name/specification and for which
- * ACE_Sock_Connect::get_ip_interfaces() is fully implemented
- * + Systems with only one non-loopback interface.
- * Other platforms require additional supporting code.
- * - The default behavior in most IP stacks is to use the default
- * interface where "default" has rather ad-hoc semantics.
- * - This applies only to receives, not sends (which always use only one
- * interface; NULL means use the "system default" interface).
- */
- /// Supported values:
- /// If (net_if==NULL), use default interface.
- /// @note This might seem odd, but we need a way to distinguish between
- /// default behavior, which might or might not be to bind, and explicitly
- /// choosing to bind or not to bind--which "is the question." ;-)
- OPT_NULLIFACE_ONE = 0,
- /// If (net_if==NULL), use all mcast interfaces.
- OPT_NULLIFACE_ALL = 2,
- /// Default value for NULLIFACE option. (Environment-dependent.)
-#ifdef ACE_WIN32
- /// This is the (ad-hoc) legacy behavior for Win32/WinSock.
- /// @note Older version of WinSock/MSVC may not get all multicast-capable
- /// interfaces (e.g. PPP interfaces).
- DEFOPT_NULLIFACE = OPT_NULLIFACE_ALL,
-#else
- /// General-purpose default behavior (as per legacy behavior).
- DEFOPT_NULLIFACE = OPT_NULLIFACE_ONE,
-#endif /* ACE_WIN32 */
- /// All default options.
- DEFOPTS = DEFOPT_BINDADDR | DEFOPT_NULLIFACE
- };
-
- /// Create an unitialized instance and define per-instance optional
- /// functionality.
- /**
- * You must invoke open() or join(), to create/bind a socket and define
- * operational parameters, before performing any I/O with this instance.
- */
- ACE_SOCK_Dgram_Mcast (options opts = DEFOPTS);
-
- /// Release all resources and implicitly or explicitly unsubscribe
- /// from all currently subscribed groups.
- /**
- * The OPT_DTORUNSUB_YES_ option defines whether an explicit unsubscribe() is
- * done by the destructor. If not, most systems will automatically
- * unsubscribe upon the close of the socket.
- */
- ~ACE_SOCK_Dgram_Mcast ();
-
- /**
- * 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 join(), using the subscribed address/port number and network
- * interface parameters.
- *
- * @param mcast_addr Defines the default send address/port number and,
- * if the @c OPT_BINDADDR_YES option is used, the multicast address
- * that is bound to this socket. The port number in @a mcast_addr
- * may be 0, in which case a system-assigned (ephemeral) port number
- * is used for sending and receiving.
- *
- * @param net_if If @a net_if is not 0, it defines the network interface
- * used for all sends by this instance, otherwise the system default
- * interface is used. (The @a net_if parameter is ignored if this
- * feature is not supported by the environment.)
- *
- * @param reuse_addr If @a reuse_addr is not 0, the @c SO_REUSEADDR option
- * and, if it is supported, the SO_REUSEPORT option are enabled.
- *
- * @retval 0 on success
- * @retval -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.
- */
- int open (const ACE_INET_Addr &mcast_addr,
- const ACE_TCHAR *net_if = 0,
- int reuse_addr = 1);
-
- // = Multicast group subscribe/unsubscribe routines.
-
- /// 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 @a 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 @a mcast_addr for binding
- * the socket and @a 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, @a net_if is NULL, and
- * ACE_Sock_Connect::get_ip_interfaces() is not implemented in this
- * environment.
- *
- * Note that the optional @a reuse_addr parameter does not apply to
- * subscriptions; it is only used if open() is implicitly invoked (see above).
- *
- * Uses the mcast_addr to determine protocol_family, and protocol which
- * we always pass as 0 anyway.
- */
- int join (const ACE_INET_Addr &mcast_addr,
- int reuse_addr = 1, // (see above)
- const ACE_TCHAR *net_if = 0);
-
-
- /// 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 @a 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,
- * @a 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 @a net_if).
- *
- * leave() replaces unsubscribe() and uses mcast_addr to determine
- * protocol_family, and protocol which we always pass as 0 anyway.
- */
- int leave (const ACE_INET_Addr &mcast_addr,
- const ACE_TCHAR *net_if = 0);
-
- // = Data transfer routines.
-
- /// Send @a n bytes in @a buf, using the multicast address and network interface
- /// defined by the first open() or subscribe().
- ssize_t send (const void *buf,
- size_t n,
- int flags = 0) const;
-
- /// Send @a n iovecs, using the multicast address and network interface
- /// defined by the first open() or subscribe().
- ssize_t send (const iovec iov[],
- int n,
- int flags = 0) const;
-
- // = Options.
-
- /// 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.
- *
- * @deprecated This method has been deprecated since it cannot be used
- * easily with with IPv6 options. Use ACE_SOCK::set_option instead.
- */
- int set_option (int option, char optval);
-
- /// 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.
- */
- void dump () const;
-
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
-
- /// Override write accessor for the constructor options (@see enum options above)
- /// This class is typically default instantiated in a connection handler templated
- /// framework so these cannot be specified on construction.
- void opts (int opts);
-
- /// Read accessor for the constructor options (@see enum options above)
- int opts () const;
-
-private:
-
- /// Subscribe to a multicast address on one or more network interface(s).
- /// (No QoS support.)
- int subscribe_ifs (const ACE_INET_Addr &mcast_addr,
- const ACE_TCHAR *net_if,
- int reuse_addr);
-
- /// Do subscription processing w/out updating the subscription list.
- /// (Layered method for subscribe() processing).
- int subscribe_i (const ACE_INET_Addr &mcast_addr,
- int reuse_addr = 1,
- const ACE_TCHAR *net_if = 0);
-
- /// Unsubscribe from a multicast address on one or more network interface(s).
- int unsubscribe_ifs (const ACE_INET_Addr &mcast_addr,
- const ACE_TCHAR *net_if = 0);
-
- /// Do unsubscription processing w/out udpating subscription list.
- /// (Layered method for <unsubscribe> processing).
- int unsubscribe_i (const ACE_INET_Addr &mcast_addr,
- const ACE_TCHAR *net_if = 0);
-
-protected:
- /// Contains common open functionality so that inheriting classes can
- /// reuse it.
- int open_i (const ACE_INET_Addr &mcast_addr, // Bound & sendto address.
- const ACE_TCHAR *net_if = 0, // Net interface for sends.
- int reuse_addr = 1);
-
- /// Empty the dynamic subscription list.
- int clear_subs_list ();
-
- /// Multicast address to which local send() methods send datagrams.
- ACE_INET_Addr send_addr_;
- /// Network interface to which all send() methods send multicast datagrams.
- ACE_TCHAR *send_net_if_;
-
-private:
- /// Per-instance options..
- int opts_;
-
-#if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE)
- typedef ACE_DLList<ip_mreq> subscription_list_t;
- typedef ACE_DLList_Iterator<ip_mreq> subscription_list_iter_t;
- /// List of currently subscribed addr/iface pairs (and assc. types).
- mutable subscription_list_t subscription_list_;
- /// Lock used to protect subscription list.
- mutable ACE_SDM_LOCK subscription_list_lock_;
- // (Lock type does not need to support recursive locking.)
-#endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */
-
-};
-
-ACE_END_VERSIONED_NAMESPACE_DECL
-
-#if defined (__ACE_INLINE__)
-#include "ace/SOCK_Dgram_Mcast.inl"
-#endif /* __ACE_INLINE__ */
-
-#include /**/ "ace/post.h"
-#endif /* ACE_SOCK_DGRAM_MCAST_H */
+// -*- C++ -*- + +//============================================================================= +/** + * @file SOCK_Dgram_Mcast.h + * + * @author Irfan Pyrali <irfan@cs.wustl.edu> + * @author Tim Harrison <harrison@cs.wustl.edu> + * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu> + * @author Bill Fulton <bill_a_fulton@raytheon.com> + * @author Don Hinton <dhinton@objectsciences.com> + */ +//============================================================================= + +#ifndef ACE_SOCK_DGRAM_MCAST_H +#define ACE_SOCK_DGRAM_MCAST_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SOCK_Dgram.h" +#include "ace/INET_Addr.h" + +#if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) +# include "ace/Containers_T.h" +# include "ace/Synch_Traits.h" +# include "ace/Thread_Mutex.h" +# if !defined (ACE_SDM_LOCK) +# define ACE_SDM_LOCK ACE_SYNCH_MUTEX +# endif /* ACE_SDM_LOCK */ +#endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_SOCK_Dgram_Mcast + * + * @brief Defines the ACE socket wrapper for UDP/IP multicast. + * + * Supports multiple simultaneous subscriptions, unsubscription from one or + * all subscriptions, and independent send/recv address and interface + * specifications. Constructor arguments determine per-instance optional + * functionality. + * + * Note that multicast semantics and implementation details are @i 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: + * - Send and receive addresses and network interfaces, but not port number, + * are independent. While this instance is open, one send interface (and a + * default send address) is in effect and 0, 1, or multiple receive + * addresses/interfaces are in effect. + * - The first open()/subscribe() invocation defines the network interface + * and default address used for all sends by this instance, defines the + * port number and optionally the multicast address bound to the underlying + * socket, and defines the (one) port number that is used for all subscribes + * (subsequent subscribes must pass the same port number or 0). + * - The default loopback state is not explicitly set; the environment will + * determine the default state. Note that some environments (e.g. some + * Windows versions) do not allow the default to be changed, and that the + * semantics of loopback control are environment dependent (e.g. sender vs. + * receiver control). + * - In general, due to multicast design and implementation quirks/bugs, it is + * difficult to tell which address a received message was sent to or which + * interface it was received on (even if only one subscription is active). + * However, there are filtering options that can be applied, to narrow it + * down considerably. + * + * Interface specification notes (for subscribe() and unsubscribe()): + * - If @a net_if == 0, the @c OPT_NULLIFACE_ALL and @c OPT_NULLIFACE_ONE + * options determine whether only the system default interface + * (if @c OPT_NULLIFACE_ONE is set) or all interfaces (if + * @c OPT_NULLIFACE_ALL is set) is affected. Specifying all interfaces + * functions correctly only on: + * + Windows + * + Platforms with the ACE_HAS_GETIFADDRS config setting (includes Linux) + * + Platforms which accept the IP address as an interface + * name/specification + * + Systems with only one non-loopback interface. + * Other platforms require additional supporting code. + * - Multiple subscriptions for the same address but different interfaces is + * normally supported, but re-subscription to an address/interface that is + * already subscribed is normally not allowed. + * - The @a net_if interface specification syntax is environment-specific. + * UNIX systems will normally use device specifications such as "le0" or + * "elxl1", while other systems will use the IP address of the interface. + * Some platforms, such as pSoS, support only cardinal numbers as network + * interface specifications; for these platforms, just give these numbers in + * string form and join() will convert them into numbers. + */ +class ACE_Export ACE_SOCK_Dgram_Mcast : public ACE_SOCK_Dgram +{ +public: + + /** + * @brief Option parameters. + * + * These control per-instance optional functionality. They are set via + * an optional constructor argument. + * + * @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. + */ + enum options + { + /* Define whether a specific multicast address (in addition to the port + * number) is bound to the socket. + * @note: + * - Effect of doing this is stack/environment dependent, but in most + * environments can be used to filter out unwanted unicast, broadcast, + * and (other) multicast messages sent to the same port number. + * - Some IP stacks (e.g. some Windows) do not support binding multicast + * addresses. Using this option will always cause an open() error. + * - It's not strictly possible for user code to do this level of filtering + * without the bind; some environments support ways to determine which + * address a message was sent to, but this class interface does not + * support access to that information. + * - The address (and port number) passed to open() (or the first + * join(), if open() is not explicitly invoked) is the one that is bound. + */ + + /// Disable address bind. (Bind only port.) + /// @note This might seem odd, but we need a way to distinguish between + /// default behavior, which might or might not be to bind, and explicitly + /// choosing to bind or not to bind--which "is the question." ;-) + OPT_BINDADDR_NO = 0, + /// Enable address bind. (Bind port and address.) + OPT_BINDADDR_YES = 1, + /// Default value for BINDADDR option. (Environment-dependent.) +#if defined (ACE_LACKS_PERFECT_MULTICAST_FILTERING) \ + && (ACE_LACKS_PERFECT_MULTICAST_FILTERING == 1) + /// Platforms that don't support perfect filtering. Note that perfect + /// filtering only really applies to multicast traffic, not unicast + /// or broadcast. + DEFOPT_BINDADDR = OPT_BINDADDR_YES, +# else + /// At least some Win32 OS's can not bind mcast addr, so disable it. + /// General-purpose default behavior is 'disabled', since effect is + /// environment-specific and side-effects might be surprising. + DEFOPT_BINDADDR = OPT_BINDADDR_NO, +#endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING = 1) */ + + /* + * Define the interpretation of NULL as a join interface specification. + * If the interface part of a multicast address specification is NULL, it + * will be interpreted to mean either "the default interface" or "all + * interfaces", depending on the setting of this option. + * @note + * - The @c OPT_NULLIFACE_ALL option can be used only in the following + * environments: + * + Windows + * + Platforms with the ACE_HAS_GETIFADDRS config setting (includes + * Linux) + * + Platforms which accept the IP address as an interface + * name/specification and for which + * ACE_Sock_Connect::get_ip_interfaces() is fully implemented + * + Systems with only one non-loopback interface. + * Other platforms require additional supporting code. + * - The default behavior in most IP stacks is to use the default + * interface where "default" has rather ad-hoc semantics. + * - This applies only to receives, not sends (which always use only one + * interface; NULL means use the "system default" interface). + */ + /// Supported values: + /// If (net_if==NULL), use default interface. + /// @note This might seem odd, but we need a way to distinguish between + /// default behavior, which might or might not be to bind, and explicitly + /// choosing to bind or not to bind--which "is the question." ;-) + OPT_NULLIFACE_ONE = 0, + /// If (net_if==NULL), use all mcast interfaces. + OPT_NULLIFACE_ALL = 2, + /// Default value for NULLIFACE option. (Environment-dependent.) +#ifdef ACE_WIN32 + /// This is the (ad-hoc) legacy behavior for Win32/WinSock. + /// @note Older version of WinSock/MSVC may not get all multicast-capable + /// interfaces (e.g. PPP interfaces). + DEFOPT_NULLIFACE = OPT_NULLIFACE_ALL, +#else + /// General-purpose default behavior (as per legacy behavior). + DEFOPT_NULLIFACE = OPT_NULLIFACE_ONE, +#endif /* ACE_WIN32 */ + /// All default options. + DEFOPTS = DEFOPT_BINDADDR | DEFOPT_NULLIFACE + }; + + /// Create an unitialized instance and define per-instance optional + /// functionality. + /** + * You must invoke open() or join(), to create/bind a socket and define + * operational parameters, before performing any I/O with this instance. + */ + ACE_SOCK_Dgram_Mcast (options opts = DEFOPTS); + + /// Release all resources and implicitly or explicitly unsubscribe + /// from all currently subscribed groups. + /** + * The OPT_DTORUNSUB_YES_ option defines whether an explicit unsubscribe() is + * done by the destructor. If not, most systems will automatically + * unsubscribe upon the close of the socket. + */ + ~ACE_SOCK_Dgram_Mcast (); + + /** + * 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 join(), using the subscribed address/port number and network + * interface parameters. + * + * @param mcast_addr Defines the default send address/port number and, + * if the @c OPT_BINDADDR_YES option is used, the multicast address + * that is bound to this socket. The port number in @a mcast_addr + * may be 0, in which case a system-assigned (ephemeral) port number + * is used for sending and receiving. + * + * @param net_if If @a net_if is not 0, it defines the network interface + * used for all sends by this instance, otherwise the system default + * interface is used. (The @a net_if parameter is ignored if this + * feature is not supported by the environment.) + * + * @param reuse_addr If @a reuse_addr is not 0, the @c SO_REUSEADDR option + * and, if it is supported, the SO_REUSEPORT option are enabled. + * + * @retval 0 on success + * @retval -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. + */ + int open (const ACE_INET_Addr &mcast_addr, + const ACE_TCHAR *net_if = 0, + int reuse_addr = 1); + + // = Multicast group subscribe/unsubscribe routines. + + /// 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 @a 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 @a mcast_addr for binding + * the socket and @a 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, @a net_if is NULL, and + * ACE_Sock_Connect::get_ip_interfaces() is not implemented in this + * environment. + * + * Note that the optional @a reuse_addr parameter does not apply to + * subscriptions; it is only used if open() is implicitly invoked (see above). + * + * Uses the mcast_addr to determine protocol_family, and protocol which + * we always pass as 0 anyway. + */ + int join (const ACE_INET_Addr &mcast_addr, + int reuse_addr = 1, // (see above) + const ACE_TCHAR *net_if = 0); + + + /// 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 @a 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, + * @a 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 @a net_if). + * + * leave() replaces unsubscribe() and uses mcast_addr to determine + * protocol_family, and protocol which we always pass as 0 anyway. + */ + int leave (const ACE_INET_Addr &mcast_addr, + const ACE_TCHAR *net_if = 0); + + // = Data transfer routines. + + /// Send @a n bytes in @a buf, using the multicast address and network interface + /// defined by the first open() or subscribe(). + ssize_t send (const void *buf, + size_t n, + int flags = 0) const; + + /// Send @a n iovecs, using the multicast address and network interface + /// defined by the first open() or subscribe(). + ssize_t send (const iovec iov[], + int n, + int flags = 0) const; + + // = Options. + + /// 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. + * + * @deprecated This method has been deprecated since it cannot be used + * easily with with IPv6 options. Use ACE_SOCK::set_option instead. + */ + int set_option (int option, char optval); + + /// 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. + */ + void dump () const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Override write accessor for the constructor options (@see enum options above) + /// This class is typically default instantiated in a connection handler templated + /// framework so these cannot be specified on construction. + void opts (int opts); + + /// Read accessor for the constructor options (@see enum options above) + int opts () const; + +private: + + /// Subscribe to a multicast address on one or more network interface(s). + /// (No QoS support.) + int subscribe_ifs (const ACE_INET_Addr &mcast_addr, + const ACE_TCHAR *net_if, + int reuse_addr); + + /// Do subscription processing w/out updating the subscription list. + /// (Layered method for subscribe() processing). + int subscribe_i (const ACE_INET_Addr &mcast_addr, + int reuse_addr = 1, + const ACE_TCHAR *net_if = 0); + + /// Unsubscribe from a multicast address on one or more network interface(s). + int unsubscribe_ifs (const ACE_INET_Addr &mcast_addr, + const ACE_TCHAR *net_if = 0); + + /// Do unsubscription processing w/out udpating subscription list. + /// (Layered method for <unsubscribe> processing). + int unsubscribe_i (const ACE_INET_Addr &mcast_addr, + const ACE_TCHAR *net_if = 0); + +protected: + /// Contains common open functionality so that inheriting classes can + /// reuse it. + int open_i (const ACE_INET_Addr &mcast_addr, // Bound & sendto address. + const ACE_TCHAR *net_if = 0, // Net interface for sends. + int reuse_addr = 1); + + /// Empty the dynamic subscription list. + int clear_subs_list (); + +private: + /// Per-instance options.. + int opts_; + + /// Multicast address to which local send() methods send datagrams. + ACE_INET_Addr send_addr_; + /// Network interface to which all send() methods send multicast datagrams. + ACE_TCHAR *send_net_if_; + +#if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) + typedef ACE_DLList<ip_mreq> subscription_list_t; + typedef ACE_DLList_Iterator<ip_mreq> subscription_list_iter_t; + /// List of currently subscribed addr/iface pairs (and assc. types). + mutable subscription_list_t subscription_list_; + /// Lock used to protect subscription list. + mutable ACE_SDM_LOCK subscription_list_lock_; + // (Lock type does not need to support recursive locking.) +#endif /* ACE_SOCK_DGRAM_MCAST_DUMPABLE */ + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/SOCK_Dgram_Mcast.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_SOCK_DGRAM_MCAST_H */ |