summaryrefslogtreecommitdiff
path: root/ace/SOCK_Dgram.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/SOCK_Dgram.cpp')
-rw-r--r--ace/SOCK_Dgram.cpp740
1 files changed, 0 insertions, 740 deletions
diff --git a/ace/SOCK_Dgram.cpp b/ace/SOCK_Dgram.cpp
deleted file mode 100644
index 244ab959a46..00000000000
--- a/ace/SOCK_Dgram.cpp
+++ /dev/null
@@ -1,740 +0,0 @@
-#include "ace/SOCK_Dgram.h"
-
-#include "ace/Handle_Set.h"
-#include "ace/Log_Msg.h"
-#include "ace/INET_Addr.h"
-#include "ace/ACE.h"
-#include "ace/OS_NS_string.h"
-#include "ace/OS_Memory.h"
-#include "ace/OS_NS_sys_select.h"
-#include "ace/OS_NS_ctype.h"
-#include "ace/os_include/net/os_if.h"
-
-#if !defined (__ACE_INLINE__)
-# include "ace/SOCK_Dgram.inl"
-#endif /* __ACE_INLINE__ */
-
-#if defined (ACE_HAS_IPV6) && defined (ACE_WIN32)
-#include /**/ <Iphlpapi.h>
-#endif
-
-ACE_RCSID (ace,
- SOCK_Dgram,
- "$Id$")
-
-// This is a workaround for platforms with non-standard
-// definitions of the ip_mreq structure
-#if ! defined (IMR_MULTIADDR)
-#define IMR_MULTIADDR imr_multiaddr
-#endif /* ! defined (IMR_MULTIADDR) */
-
-ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-
-ACE_ALLOC_HOOK_DEFINE (ACE_SOCK_Dgram)
-
-void
-ACE_SOCK_Dgram::dump (void) const
-{
-#if defined (ACE_HAS_DUMP)
- ACE_TRACE ("ACE_SOCK_Dgram::dump");
-#endif /* ACE_HAS_DUMP */
-}
-
-// Allows a client to read from a socket without having to provide a
-// buffer to read. This method determines how much data is in the
-// socket, allocates a buffer of this size, reads in the data, and
-// returns the number of bytes read.
-
-ssize_t
-ACE_SOCK_Dgram::recv (iovec *io_vec,
- ACE_Addr &addr,
- int flags,
- const ACE_Time_Value *timeout) const
-{
- ACE_TRACE ("ACE_SOCK_Dgram::recv");
-#if defined (FIONREAD)
- ACE_Handle_Set handle_set;
- handle_set.reset ();
- handle_set.set_bit (this->get_handle ());
-
- // Check the status of the current socket to make sure there's data
- // to recv (or time out).
- int select_width;
-# if defined (ACE_WIN32)
- // This arg is ignored on Windows and causes pointer truncation
- // warnings on 64-bit compiles.
- select_width = 0;
-# else
- select_width = int (this->get_handle ()) + 1;
-# endif /* ACE_WIN32 */
- switch (ACE_OS::select (select_width,
- handle_set,
- 0, 0,
- timeout))
- {
- case -1:
- return -1;
- /* NOTREACHED */
- case 0:
- errno = ETIME;
- return -1;
- /* NOTREACHED */
- default:
- // Goes fine, fallthrough to get data
- break;
- }
-
- sockaddr *saddr = (sockaddr *) addr.get_addr ();
- int addr_len = addr.get_size ();
- u_long inlen;
-
- if (ACE_OS::ioctl (this->get_handle (),
- FIONREAD, (u_long *) &inlen) == -1)
- return -1;
- else if (inlen > 0)
- {
- ACE_NEW_RETURN (io_vec->iov_base,
- char[inlen],
- -1);
- io_vec->iov_len = ACE_OS::recvfrom (this->get_handle (),
- (char *) io_vec->iov_base,
- inlen,
- flags,
- (sockaddr *) saddr,
- &addr_len);
- addr.set_size (addr_len);
- return io_vec->iov_len;
- }
- else
- return 0;
-#else
- ACE_UNUSED_ARG (flags);
- ACE_UNUSED_ARG (addr);
- ACE_UNUSED_ARG (io_vec);
- ACE_UNUSED_ARG (timeout);
- ACE_NOTSUP_RETURN (-1);
-#endif /* FIONREAD */
-}
-
-// Here's the shared open function. Note that if we are using the
-// PF_INET protocol family and the address of LOCAL == the address of
-// the special variable SAP_ANY then we are going to arbitrarily bind
-// to a portnumber.
-
-int
-ACE_SOCK_Dgram::shared_open (const ACE_Addr &local,
- int protocol_family)
-{
- ACE_TRACE ("ACE_SOCK_Dgram::shared_open");
- int error = 0;
-
- if (local == ACE_Addr::sap_any)
- {
- if (protocol_family == PF_INET
-#if defined (ACE_HAS_IPV6)
- || protocol_family == PF_INET6
-#endif /* ACE_HAS_IPV6 */
- )
- {
- if (ACE::bind_port (this->get_handle (),
- INADDR_ANY,
- protocol_family) == -1)
- error = 1;
- }
- }
- else if (ACE_OS::bind (this->get_handle (),
- reinterpret_cast<sockaddr *> (local.get_addr ()),
- local.get_size ()) == -1)
- error = 1;
-
- if (error != 0)
- this->close ();
-
- return error ? -1 : 0;
-}
-
-int
-ACE_SOCK_Dgram::open (const ACE_Addr &local,
- int protocol_family,
- int protocol,
- ACE_Protocol_Info *protocolinfo,
- ACE_SOCK_GROUP g,
- u_long flags,
- int reuse_addr)
-{
- if (ACE_SOCK::open (SOCK_DGRAM,
- protocol_family,
- protocol,
- protocolinfo,
- g,
- flags,
- reuse_addr) == -1)
- return -1;
- else if (this->shared_open (local,
- protocol_family) == -1)
- return -1;
- else
- return 0;
-}
-
-// Here's the general-purpose open routine.
-
-int
-ACE_SOCK_Dgram::open (const ACE_Addr &local,
- int protocol_family,
- int protocol,
- int reuse_addr)
-{
- ACE_TRACE ("ACE_SOCK_Dgram::open");
-
- if (local != ACE_Addr::sap_any)
- protocol_family = local.get_type ();
- else if (protocol_family == PF_UNSPEC)
- {
-#if defined (ACE_HAS_IPV6)
- protocol_family = ACE::ipv6_enabled () ? PF_INET6 : PF_INET;
-#else
- protocol_family = PF_INET;
-#endif /* ACE_HAS_IPV6 */
- }
-
- if (ACE_SOCK::open (SOCK_DGRAM,
- protocol_family,
- protocol,
- reuse_addr) == -1)
- return -1;
- else
- return this->shared_open (local,
- protocol_family);
-}
-
-// Here's the general-purpose constructor used by a connectionless
-// datagram ``server''...
-
-ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
- int protocol_family,
- int protocol,
- int reuse_addr)
-{
- ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram");
-
- if (this->open (local,
- protocol_family,
- protocol,
- reuse_addr) == -1)
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE_SOCK_Dgram")));
-}
-
-ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
- int protocol_family,
- int protocol,
- ACE_Protocol_Info *protocolinfo,
- ACE_SOCK_GROUP g,
- u_long flags,
- int reuse_addr)
-{
- ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram");
- if (this->open (local,
- protocol_family,
- protocol,
- protocolinfo,
- g,
- flags,
- reuse_addr) == -1)
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE_SOCK_Dgram")));
-}
-
-#if defined (ACE_HAS_MSG)
-// Send an iovec of size N to ADDR as a datagram (connectionless
-// version).
-
-ssize_t
-ACE_SOCK_Dgram::send (const iovec iov[],
- int n,
- const ACE_Addr &addr,
- int flags) const
-{
- ACE_TRACE ("ACE_SOCK_Dgram::send");
- msghdr send_msg;
-
- send_msg.msg_iov = (iovec *) iov;
- send_msg.msg_iovlen = n;
-#if defined (ACE_HAS_SOCKADDR_MSG_NAME)
- send_msg.msg_name = (struct sockaddr *) addr.get_addr ();
-#else
- send_msg.msg_name = (char *) addr.get_addr ();
-#endif /* ACE_HAS_SOCKADDR_MSG_NAME */
- send_msg.msg_namelen = addr.get_size ();
-
-#if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG)
- send_msg.msg_control = 0;
- send_msg.msg_controllen = 0;
- send_msg.msg_flags = 0;
-#else
- send_msg.msg_accrights = 0;
- send_msg.msg_accrightslen = 0;
-#endif /* ACE_HAS_4_4BSD_SENDMSG_RECVMSG */
-
- return ACE_OS::sendmsg (this->get_handle (),
- &send_msg,
- flags);
-}
-
-// Recv an iovec of size N to ADDR as a datagram (connectionless
-// version).
-
-ssize_t
-ACE_SOCK_Dgram::recv (iovec iov[],
- int n,
- ACE_Addr &addr,
- int flags) const
-{
- ACE_TRACE ("ACE_SOCK_Dgram::recv");
- msghdr recv_msg;
-
- recv_msg.msg_iov = (iovec *) iov;
- recv_msg.msg_iovlen = n;
-#if defined (ACE_HAS_SOCKADDR_MSG_NAME)
- recv_msg.msg_name = (struct sockaddr *) addr.get_addr ();
-#else
- recv_msg.msg_name = (char *) addr.get_addr ();
-#endif /* ACE_HAS_SOCKADDR_MSG_NAME */
- recv_msg.msg_namelen = addr.get_size ();
-
-#if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG)
- recv_msg.msg_control = 0 ;
- recv_msg.msg_controllen = 0 ;
-#else
- recv_msg.msg_accrights = 0;
- recv_msg.msg_accrightslen = 0;
-#endif /* ACE_HAS_4_4BSD_SENDMSG_RECVMSG */
-
- ssize_t status = ACE_OS::recvmsg (this->get_handle (),
- &recv_msg,
- flags);
- addr.set_size (recv_msg.msg_namelen);
- addr.set_type (((sockaddr_in *) addr.get_addr())->sin_family);
- return status;
-}
-
-#else /* ACE_HAS_MSG */
-
-// Send an iovec of size N to ADDR as a datagram (connectionless
-// version).
-
-ssize_t
-ACE_SOCK_Dgram::send (const iovec iov[],
- int n,
- const ACE_Addr &addr,
- int flags) const
-{
- ACE_TRACE ("ACE_SOCK_Dgram::send");
-
- size_t length = 0;
- int i;
-
- // Determine the total length of all the buffers in <iov>.
- for (i = 0; i < n; i++)
-#if ! (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0530))
- // The iov_len is unsigned in Borland. If we go ahead and try the
- // if, it will emit a warning.
- if (iov[i].iov_len < 0)
- return -1;
- else
-#endif
- length += iov[i].iov_len;
-
- char *buf;
-
-#if defined (ACE_HAS_ALLOCA)
- buf = alloca (length);
-#else
- ACE_NEW_RETURN (buf,
- char[length],
- -1);
-#endif /* !defined (ACE_HAS_ALLOCA) */
-
- char *ptr = buf;
-
- for (i = 0; i < n; i++)
- {
- ACE_OS::memcpy (ptr, iov[i].iov_base, iov[i].iov_len);
- ptr += iov[i].iov_len;
- }
-
- ssize_t result = ACE_SOCK_Dgram::send (buf, length, addr, flags);
-#if !defined (ACE_HAS_ALLOCA)
- delete [] buf;
-#endif /* !defined (ACE_HAS_ALLOCA) */
- return result;
-}
-
-// Recv an iovec of size N to ADDR as a datagram (connectionless
-// version).
-
-ssize_t
-ACE_SOCK_Dgram::recv (iovec iov[],
- int n,
- ACE_Addr &addr,
- int flags) const
-{
- ACE_TRACE ("ACE_SOCK_Dgram::recv");
-
- ssize_t length = 0;
- int i;
-
- for (i = 0; i < n; i++)
-#if ! (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0530))
- // The iov_len is unsigned in Borland. If we go ahead and try the
- // if, it will emit a warning.
- if (iov[i].iov_len < 0)
- return -1;
- else
-#endif
- length += iov[i].iov_len;
-
- char *buf;
-
-#if defined (ACE_HAS_ALLOCA)
- buf = alloca (length);
-#else
- ACE_NEW_RETURN (buf,
- char[length],
- -1);
-#endif /* !defined (ACE_HAS_ALLOCA) */
-
- length = ACE_SOCK_Dgram::recv (buf, length, addr, flags);
-
- if (length != -1)
- {
- char *ptr = buf;
- int copyn = length;
-
- for (i = 0;
- i < n && copyn > 0;
- i++)
- {
- ACE_OS::memcpy (iov[i].iov_base, ptr,
- // iov_len is int on some platforms, size_t on others
- copyn > (int) iov[i].iov_len
- ? (size_t) iov[i].iov_len
- : (size_t) copyn);
- ptr += iov[i].iov_len;
- copyn -= iov[i].iov_len;
- }
- }
-
-#if !defined (ACE_HAS_ALLOCA)
- delete [] buf;
-#endif /* !defined (ACE_HAS_ALLOCA) */
- return length;
-}
-
-#endif /* ACE_HAS_MSG */
-
-ssize_t
-ACE_SOCK_Dgram::recv (void *buf,
- size_t n,
- ACE_Addr &addr,
- int flags,
- const ACE_Time_Value *timeout) const
-{
- ACE_Handle_Set handle_set;
- handle_set.reset ();
- handle_set.set_bit (this->get_handle ());
-
- // Check the status of the current socket.
- int select_width;
-#if defined (ACE_WIN32)
- // This arg is ignored on Windows and causes pointer truncation
- // warnings on 64-bit compiles.
- select_width = 0;
-#else
- select_width = int (this->get_handle ()) + 1;
-#endif /* ACE_WIN32 */
- switch (ACE_OS::select (select_width,
- handle_set,
- 0,
- 0,
- timeout))
- {
- case -1:
- return -1;
- /* NOTREACHED */
- case 0:
- errno = ETIME;
- return -1;
- /* NOTREACHED */
- default:
- // Goes fine, call <recv> to get data
- return this->recv (buf, n, addr, flags);
- }
-}
-
-ssize_t
-ACE_SOCK_Dgram::send (const void *buf,
- size_t n,
- const ACE_Addr &addr,
- int flags,
- const ACE_Time_Value *timeout) const
-{
- ACE_Handle_Set handle_set;
- handle_set.reset ();
- handle_set.set_bit (this->get_handle ());
-
- // Check the status of the current socket.
- int select_width;
-#if defined (ACE_WIN32)
- // This arg is ignored on Windows and causes pointer truncation
- // warnings on 64-bit compiles.
- select_width = 0;
-#else
- select_width = int (this->get_handle ()) + 1;
-#endif /* ACE_WIN32 */
- switch (ACE_OS::select (select_width,
- 0,
- handle_set,
- 0,
- timeout))
- {
- case -1:
- return -1;
- /* NOTREACHED */
- case 0:
- errno = ETIME;
- return -1;
- /* NOTREACHED */
- default:
- // Goes fine, call <send> to transmit the data.
- return this->send (buf, n, addr, flags);
- }
-}
-
-int
-ACE_SOCK_Dgram::set_nic (const ACE_TCHAR *net_if,
- int addr_family)
-{
-#if defined (IP_MULTICAST_IF) && (IP_MULTICAST_IF != 0)
-# if defined (ACE_HAS_IPV6)
- bool ipv6_mif_set = false;
- if (addr_family == AF_INET6 || addr_family == AF_UNSPEC)
- {
- ACE_INET_Addr addr;
- addr.set (static_cast<u_short> (0), ACE_IPV6_ANY);
- ipv6_mreq send_mreq;
- if (this->make_multicast_ifaddr6 (&send_mreq,
- addr,
- net_if) == -1)
- return -1;
-
- // Only let this attempt to set unknown interface when INET6 is
- // specifically requested. Otherwise we will just try INET.
- if (send_mreq.ipv6mr_interface != 0 || addr_family == AF_INET6)
- {
- if (this->ACE_SOCK::set_option
- (IPPROTO_IPV6, IPV6_MULTICAST_IF,
- &(send_mreq.ipv6mr_interface),
- sizeof send_mreq.ipv6mr_interface) == -1)
- return -1;
- }
- ipv6_mif_set = send_mreq.ipv6mr_interface != 0;
- }
-
-# if defined (ACE_WIN32)
- // For Win32 net_if is distintly different between INET6 and INET
- // so it is always either an INET6 if or an INET if.
- if (!ipv6_mif_set && (addr_family == AF_INET || addr_family == AF_UNSPEC))
-# else
- if (addr_family == AF_INET || addr_family == AF_UNSPEC)
-# endif
- {
- ACE_INET_Addr addr (static_cast<u_short> (0));
- ip_mreq send_mreq;
- if (this->make_multicast_ifaddr (&send_mreq,
- addr,
- net_if) == -1)
- {
- if (!ipv6_mif_set)
- return -1;
- }
- else if (this->ACE_SOCK::set_option (IPPROTO_IP,
- IP_MULTICAST_IF,
- &(send_mreq.imr_interface),
- sizeof send_mreq.imr_interface) == -1)
- {
- if (!ipv6_mif_set)
- return -1;
- }
- }
-# else /* ACE_HAS_IPV6 */
- ACE_UNUSED_ARG (addr_family);
- ACE_INET_Addr addr (static_cast<u_short> (0));
- ip_mreq send_mreq;
- if (this->make_multicast_ifaddr (&send_mreq,
- addr,
- net_if) == -1)
- return -1;
- if (this->ACE_SOCK::set_option (IPPROTO_IP,
- IP_MULTICAST_IF,
- &(send_mreq.imr_interface),
- sizeof send_mreq.imr_interface) == -1)
- return -1;
-# endif /* !ACE_HAS_IPV6 */
-#else /* IP_MULTICAST_IF */
- // Send interface option not supported - ignore it.
- // (We may have been invoked by ::subscribe, so we have to allow
- // a non-null interface parameter in this function.)
- ACE_DEBUG ((LM_DEBUG,
- ACE_LIB_TEXT ("Send interface specification not ")
- ACE_LIB_TEXT ("supported - IGNORED.\n")));
-#endif /* !IP_MULTICAST_IF */
-
- return 0;
-}
-
-int
-ACE_SOCK_Dgram::make_multicast_ifaddr (ip_mreq *ret_mreq,
- const ACE_INET_Addr &mcast_addr,
- const ACE_TCHAR *net_if)
-{
- ACE_TRACE ("ACE_SOCK_Dgram_Mcast::make_multicast_ifaddr");
- ip_mreq lmreq; // Scratch copy.
- if (net_if != 0)
- {
-#if defined (ACE_WIN32) || defined(__INTERIX)
- // This port number is not necessary, just convenient
- ACE_INET_Addr interface_addr;
- if (interface_addr.set (mcast_addr.get_port_number (), net_if) == -1)
- return -1;
- lmreq.imr_interface.s_addr =
- ACE_HTONL (interface_addr.get_ip_address ());
-#else
- ifreq if_address;
-
-#if defined (ACE_PSOS)
- // Look up the interface by number, not name.
- if_address.ifr_ifno = ACE_OS::atoi (net_if);
-#else
- ACE_OS::strcpy (if_address.ifr_name, ACE_TEXT_ALWAYS_CHAR (net_if));
-#endif /* defined (ACE_PSOS) */
-
- if (ACE_OS::ioctl (this->get_handle (),
- SIOCGIFADDR,
- &if_address) == -1)
- return -1;
-
- sockaddr_in *socket_address;
- socket_address = reinterpret_cast<sockaddr_in*> (&if_address.ifr_addr);
- lmreq.imr_interface.s_addr = socket_address->sin_addr.s_addr;
-#endif /* ACE_WIN32 || __INTERIX */
- }
- else
- lmreq.imr_interface.s_addr = INADDR_ANY;
-
- lmreq.IMR_MULTIADDR.s_addr = ACE_HTONL (mcast_addr.get_ip_address ());
-
- // Set return info, if requested.
- if (ret_mreq)
- *ret_mreq = lmreq;
-
- return 0;
-}
-
-#if defined (ACE_HAS_IPV6)
-// XXX: This will not work on any operating systems that do not support
-// if_nametoindex or that is not Win32 >= Windows XP/Server 2003
-int
-ACE_SOCK_Dgram::make_multicast_ifaddr6 (ipv6_mreq *ret_mreq,
- const ACE_INET_Addr &mcast_addr,
- const ACE_TCHAR *net_if)
-{
- ACE_TRACE ("ACE_SOCK_Dgram_Mcast::make_multicast_ifaddr6");
- ipv6_mreq lmreq; // Scratch copy.
-
- ACE_OS::memset (&lmreq,
- 0,
- sizeof (lmreq));
-
-#if defined(__linux__)
- if (net_if != 0)
- {
- lmreq.ipv6mr_interface = ACE_OS::if_nametoindex (ACE_TEXT_ALWAYS_CHAR(net_if));
- }
- else
-#elif defined (ACE_WIN32)
- if (net_if != 0)
- {
- int if_ix = 0;
- bool num_if =
- ACE_OS::ace_isdigit (net_if[0]) &&
- (if_ix = ACE_OS::atoi (net_if)) > 0;
-
- IP_ADAPTER_ADDRESSES tmp_addrs;
- // Initial call to determine actual memory size needed
- DWORD dwRetVal;
- ULONG bufLen = 0;
- if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6,
- 0,
- NULL,
- &tmp_addrs,
- &bufLen)) != ERROR_BUFFER_OVERFLOW)
- return -1; // With output bufferlength 0 this can't be right.
-
- // Get required output buffer and retrieve info for real.
- PIP_ADAPTER_ADDRESSES pAddrs;
- char *buf;
- ACE_NEW_RETURN (buf,
- char[bufLen],
- -1);
- pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf);
- if ((dwRetVal = ::GetAdaptersAddresses (AF_INET6,
- 0,
- NULL,
- pAddrs,
- &bufLen)) != NO_ERROR)
- {
- delete[] buf; // clean up
- return -1;
- }
-
- lmreq.ipv6mr_interface = 0; // initialize
- while (pAddrs)
- {
- if ((num_if && pAddrs->Ipv6IfIndex == static_cast<unsigned int>(if_ix))
- || (!num_if &&
- (ACE_OS::strcmp (ACE_TEXT_ALWAYS_CHAR (net_if),
- pAddrs->AdapterName) == 0
- || ACE_OS::strcmp (ACE_TEXT_ALWAYS_CHAR (net_if),
- ACE_Wide_To_Ascii (pAddrs->FriendlyName).char_rep()) == 0)))
- {
- lmreq.ipv6mr_interface = pAddrs->Ipv6IfIndex;
- break;
- }
-
- pAddrs = pAddrs->Next;
- }
-
- delete[] buf; // clean up
- }
- else
-#endif /* ACE_WIN32 */
- lmreq.ipv6mr_interface = 0;
-
- // now set the multicast address
- ACE_OS::memcpy (&lmreq.ipv6mr_multiaddr,
- &((sockaddr_in6 *) mcast_addr.get_addr ())->sin6_addr,
- sizeof (in6_addr));
-
- // Set return info, if requested.
- if (ret_mreq)
- *ret_mreq = lmreq;
-
- return 0;
-}
-#endif /* __linux__ && ACE_HAS_IPV6 */
-
-ACE_END_VERSIONED_NAMESPACE_DECL