diff options
author | ajs3 <ajs3@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2007-07-29 15:55:38 +0000 |
---|---|---|
committer | ajs3 <ajs3@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2007-07-29 15:55:38 +0000 |
commit | e40511de55836cc3d81793f6b8d9b74870ff5523 (patch) | |
tree | 3fd83815798fa85f40800951331fe8f2f7fd08c7 | |
parent | b87b2c6964222da4329a733060d2b82c496a4c26 (diff) | |
download | ATCD-e40511de55836cc3d81793f6b8d9b74870ff5523.tar.gz |
Adding SOCK_SCTP_STREAM_Connector files
-rw-r--r-- | ACE/ace/SOCK_SCTP_STREAM_Connector.cpp | 435 | ||||
-rw-r--r-- | ACE/ace/SOCK_SCTP_STREAM_Connector.h | 329 | ||||
-rw-r--r-- | ACE/ace/SOCK_SCTP_STREAM_Connector.inl | 38 | ||||
-rw-r--r-- | ACE/ace/ace.mpc | 1 |
4 files changed, 803 insertions, 0 deletions
diff --git a/ACE/ace/SOCK_SCTP_STREAM_Connector.cpp b/ACE/ace/SOCK_SCTP_STREAM_Connector.cpp new file mode 100644 index 00000000000..8992447c896 --- /dev/null +++ b/ACE/ace/SOCK_SCTP_STREAM_Connector.cpp @@ -0,0 +1,435 @@ +// $Id$ + +#include "ace/SOCK_SCTP_STREAM_Connector.h" + +#include "ace/INET_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/Time_Value.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_socket.h" +#include "ace/os_include/os_fcntl.h" + +#if defined (ACE_WIN32) +#include "ace/OS_NS_unistd.h" +#endif /* ACE_WIN32 */ + +#if !defined (__ACE_INLINE__) +#include "ace/SOCK_SCTP_STREAM_Connector.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, SOCK_SCTP_STREAM_Connector, "SOCK_SCTP_STREAM_Connector.cpp,v 4.35 2002/03/08 23:18:09 spark Exp") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_SCTP_STREAM_Connector) + +int +ACE_SOCK_SCTP_STREAM_Connector::shared_open (ACE_SOCK_SCTP_STREAM &new_association, + int protocol_family, + int protocol, + int reuse_addr) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::shared_open"); + + + + // Only open a new socket if we don't already have a valid handle. + if (new_association.get_handle () == ACE_INVALID_HANDLE && +#if defined (ACE_HAS_LKSCTP) + new_association.open (SOCK_STREAM, +#else + new_association.open (SOCK_SCTP_STREAMET, +#endif /* ACE_HAS_LKSCTP */ + protocol_family, + protocol, + reuse_addr) == -1) + return -1; + else + return 0; +} + +int +ACE_SOCK_SCTP_STREAM_Connector::shared_open (ACE_SOCK_SCTP_STREAM &new_association, + int protocol_family, + int protocol, + ACE_Protocol_Info *protocolinfo, + ACE_SOCK_GROUP g, + u_long flags, + int reuse_addr) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::shared_open"); + + // Only open a new socket if we don't already have a valid handle. + if (new_association.get_handle () == ACE_INVALID_HANDLE && +#if defined (ACE_HAS_LKSCTP) + new_association.open (SOCK_STREAM, +#else + new_association.open (SOCK_SCTP_STREAMET, +#endif /* ACE_HAS_LKSCTP */ + protocol_family, + protocol, + protocolinfo, + g, + flags, + reuse_addr) == -1) + return -1; + else + return 0; +} + +int +ACE_SOCK_SCTP_STREAM_Connector::shared_connect_start (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Time_Value *timeout, + const ACE_Addr &local_sap) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::shared_connect_start"); + + if (local_sap != ACE_Addr::sap_any) + { + sockaddr *laddr = reinterpret_cast<sockaddr *> (local_sap.get_addr ()); + int size = local_sap.get_size (); + + if (ACE_OS::bind (new_association.get_handle (), + laddr, + size) == -1) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + new_association.close (); + return -1; + } + } + + // Enable non-blocking, if required. + if (timeout != 0 + && new_association.enable (ACE_NONBLOCK) == -1) + return -1; + else + return 0; +} + +// Multihomed version of same +int +ACE_SOCK_SCTP_STREAM_Connector::shared_connect_start (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Time_Value *timeout, + const ACE_Multihomed_INET_Addr &local_sap) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::shared_connect_start"); + + if (local_sap.ACE_Addr::operator!= (ACE_Addr::sap_any)) + { + // The total number of addresses is the number of secondary + // addresses plus one. + size_t num_addresses = local_sap.get_num_secondary_addresses() + 1; + + // Create an array of sockaddr_in to hold the underlying + // representations of the primary and secondary + // addresses. + sockaddr_in* local_inet_addrs = 0; + ACE_NEW_NORETURN (local_inet_addrs, sockaddr_in[num_addresses]); + if (!local_inet_addrs) + return -1; + + // Populate the array by invoking the get_addresses method on + // the Multihomed_INET_Addr + local_sap.get_addresses(local_inet_addrs, num_addresses); + +#if defined (ACE_HAS_LKSCTP) + sockaddr_in *local_sockaddr = 0; + sockaddr_in portst; + int sn = sizeof(sockaddr); + + // bind to the primary addr first + if (ACE_OS::bind(new_association.get_handle (), + reinterpret_cast<sockaddr *> (&(local_inet_addrs[0])), + sizeof(sockaddr))) + { + ACE_Errno_Guard error (errno); + new_association.close (); + return -1; + } + + // do we need to bind multiple addrs + if (num_addresses > 1) + { + // allocate enough memory to hold the number of secondary addrs + ACE_NEW_NORETURN(local_sockaddr, + sockaddr_in[num_addresses - 1]); + + // get sockaddr_in for the local handle + if (ACE_OS::getsockname(new_association.get_handle (), + reinterpret_cast<sockaddr *> (&portst), + &sn)) + { + ACE_Errno_Guard error (errno); + new_association.close (); + return -1; + } + + // set the local port # assigned by the os to every secondary addr + for (size_t i = 1; i < num_addresses; i++) + { + local_inet_addrs[i].sin_port = portst.sin_port; + } + + // copy all of the secondary addrs into a sockaddr structure + for (size_t i = 0; i < num_addresses - 1; i++) + { + ACE_OS::memcpy(&(local_sockaddr[i]), + &(local_inet_addrs[i + 1]), + sizeof(sockaddr_in)); + } + + // bind other ifaces + if (sctp_bindx(new_association.get_handle(), + reinterpret_cast<sockaddr *> (local_sockaddr), + num_addresses - 1, + SCTP_BINDX_ADD_ADDR)) + { + ACE_Errno_Guard error (errno); + new_association.close (); + return -1; + } + + delete [] local_sockaddr; + } +#else + + // Call bind + size_t name_len = (sizeof (sockaddr_in)) * num_addresses; + if (ACE_OS::bind (new_association.get_handle (), + reinterpret_cast<sockaddr *> (local_inet_addrs), + static_cast<int> (name_len)) == -1) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + new_association.close (); + return -1; + } +#endif /* ACE_HAS_LKSCTP */ + + delete [] local_inet_addrs; + } + + // Enable non-blocking, if required. + if (timeout != 0 + && new_association.enable (ACE_NONBLOCK) == -1) + return -1; + else + return 0; +} + +int +ACE_SOCK_SCTP_STREAM_Connector::shared_connect_finish (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Time_Value *timeout, + int result) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::shared_connect_finish"); + // Save/restore errno. + ACE_Errno_Guard error (errno); + + if (result == -1 && timeout != 0) + { + // Check whether the connection is in progress. + if (error == EINPROGRESS || error == EWOULDBLOCK) + { + // This expression checks if we were polling. + if (timeout->sec () == 0 + && timeout->usec () == 0) + error = EWOULDBLOCK; + // Wait synchronously using timeout. + else if (this->complete (new_association, + 0, + timeout) == -1) + error = errno; + else + return 0; + } + } + + // EISCONN is treated specially since this routine may be used to + // check if we are already connected. + if (result != -1 || error == EISCONN) + // Start out with non-blocking disabled on the <new_association>. + new_association.disable (ACE_NONBLOCK); + else if (!(error == EWOULDBLOCK || error == ETIMEDOUT)) + new_association.close (); + + return result; +} + +// Actively connect and produce a new ACE_SOCK_SCTP_STREAM if things go well... + + +int +ACE_SOCK_SCTP_STREAM_Connector::connect (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Addr &remote_sap, + const ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int /* flags */, + int /* perms */, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::connect"); + + if (this->shared_open (new_association, + remote_sap.get_type (), + protocol, + reuse_addr) == -1) + return -1; + else if (this->shared_connect_start (new_association, + timeout, + local_sap) == -1) + return -1; + + int result = ACE_OS::connect (new_association.get_handle (), + reinterpret_cast<sockaddr *> (remote_sap.get_addr ()), + remote_sap.get_size ()); + + return this->shared_connect_finish (new_association, + timeout, + result); +} + +// Multihomed version of same +int +ACE_SOCK_SCTP_STREAM_Connector::connect (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Addr &remote_sap, + const ACE_Time_Value *timeout, + const ACE_Multihomed_INET_Addr &local_sap, + int reuse_addr, + int /* flags */, + int /* perms */, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::connect"); + + if (this->shared_open (new_association, + remote_sap.get_type (), + protocol, + reuse_addr) == -1) + return -1; + else if (this->shared_connect_start (new_association, + timeout, + local_sap) == -1) + return -1; + + int result = ACE_OS::connect (new_association.get_handle (), + reinterpret_cast<sockaddr *> (remote_sap.get_addr ()), + remote_sap.get_size ()); + + return this->shared_connect_finish (new_association, + timeout, + result); +} + +// Try to complete a non-blocking connection. + +int +ACE_SOCK_SCTP_STREAM_Connector::complete (ACE_SOCK_SCTP_STREAM &new_association, + ACE_Addr *remote_sap, + const ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::complete"); + ACE_HANDLE h = ACE::handle_timed_complete (new_association.get_handle (), + tv); + // We failed to get connected. + if (h == ACE_INVALID_HANDLE) + { +#if defined (ACE_WIN32) + // Win32 has a timing problem - if you check to see if the + // connection has completed too fast, it will fail - so wait + // <ACE_NON_BLOCKING_BUG_DELAY> microseconds to let it catch up + // then retry to see if it's a real failure. + ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY); + ACE_OS::sleep (time); + h = ACE::handle_timed_complete (new_association.get_handle (), + tv); + if (h == ACE_INVALID_HANDLE) + { +#endif /* ACE_WIN32 */ + // Save/restore errno. + ACE_Errno_Guard error (errno); + new_association.close (); + return -1; +#if defined (ACE_WIN32) + } +#endif /* ACE_WIN32 */ + } + + if (remote_sap != 0) + { + int len = remote_sap->get_size (); + sockaddr *addr = reinterpret_cast<sockaddr *> (remote_sap->get_addr ()); + if (ACE_OS::getpeername (h, + addr, + &len) == -1) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + new_association.close (); + return -1; + } + } + + // Start out with non-blocking disabled on the <new_association>. + new_association.disable (ACE_NONBLOCK); + return 0; +} + +ACE_SOCK_SCTP_STREAM_Connector::ACE_SOCK_SCTP_STREAM_Connector (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Addr &remote_sap, + const ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::ACE_SOCK_SCTP_STREAM_Connector"); + + if (this->connect (new_association, + remote_sap, + timeout, + local_sap, + reuse_addr, + flags, + perms, + protocol) == -1 + && timeout != 0 + && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT)) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_SOCK_SCTP_STREAM_Connector::ACE_SOCK_SCTP_STREAM_Connector"))); +} + +// Multihomed version of same +ACE_SOCK_SCTP_STREAM_Connector::ACE_SOCK_SCTP_STREAM_Connector (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Addr &remote_sap, + const ACE_Time_Value *timeout, + const ACE_Multihomed_INET_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::ACE_SOCK_SCTP_STREAM_Connector"); + + if (this->connect (new_association, + remote_sap, + timeout, + local_sap, + reuse_addr, + flags, + perms, + protocol) == -1 + && timeout != 0 + && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT)) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_SOCK_SCTP_STREAM_Connector::ACE_SOCK_SCTP_STREAM_Connector"))); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ACE/ace/SOCK_SCTP_STREAM_Connector.h b/ACE/ace/SOCK_SCTP_STREAM_Connector.h new file mode 100644 index 00000000000..a5417fca761 --- /dev/null +++ b/ACE/ace/SOCK_SCTP_STREAM_Connector.h @@ -0,0 +1,329 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file SOCK_SCTP_STREAM_Connector.h + * + * $Id$ + * + * @author Andrew J. Stafford <ajstafford@gmail.com> + * + * @author based on SOCK_SEQPACK_Connector by: + * @author Patrick J. Lardieri <plardier@atl.lmco.com> + * @author Gaurav Naik, Lockheed Martin ATL + * + */ +//============================================================================= + +#ifndef ACE_SOCK_SCTP_STREAM_CONNECTOR_H +#define ACE_SOCK_SCTP_STREAM_CONNECTOR_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#include "ace/SOCK_SCTP_STREAM.h" +#include "ace/Multihomed_INET_Addr.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations. +class ACE_Time_Value; + +/** + * @class ACE_SOCK_SCTP_STREAM_Connector + * + * @brief Defines a factory that actively connects to a remote IP + * address and TCP port, creating a new @c ACE_SOCK_SCTP_STREAM object. + * + * The @c ACE_SOCK_SCTP_STREAM_Connector doesn't have a socket of its own, + * i.e., it simply "borrows" the one from the @c ACE_SOCK_SCTP_STREAM + * that's being connected. The reason for this is that the + * underlying socket API doesn't use a factory socket to connect + * data mode sockets. Therefore, there's no need to inherit + * @c ACE_SOCK_SCTP_STREAM_Connector from @c ACE_SOCK. A nice side-effect of + * this is that @c ACE_SOCK_SCTP_STREAM_Connector objects do not store state so + * they can be used reentrantly in multithreaded programs. + */ +class ACE_Export ACE_SOCK_SCTP_STREAM_Connector +{ +public: + // = Initialization and termination methods. + /// Default constructor. + ACE_SOCK_SCTP_STREAM_Connector (void); + + /** + * Actively connect to a peer, producing a connected @c ACE_SOCK_SCTP_STREAM + * object if the connection succeeds. + * + * @param new_association The @c ACE_SOCK_SCTP_STREAM object that will be connected + * to the peer. + * @param remote_sap The address that we are trying to connect to. + * The protocol family of @c remote_sap is used for + * the connected socket. That is, if @c remote_sap + * contains an IPv6 address, a socket with family + * PF_INET6 will be used, else it will be PF_INET. + * @param timeout Pointer to an @c ACE_Time_Value object with amount + * of time to wait to connect. If the pointer is 0 + * then the call blocks until the connection attempt + * is complete, whether it succeeds or fails. If + * *timeout == {0, 0} then the connection is done + * using nonblocking mode. In this case, if the + * connection can't be made immediately, this method + * returns -1 and errno == EWOULDBLOCK. + * If *timeout > {0, 0} then this is the maximum amount + * of time to wait before timing out; if the specified + * amount of time passes before the connection is made, + * this method returns -1 and errno == ETIME. Note + * the difference between this case and when a blocking + * connect is attmpted that TCP times out - in the latter + * case, errno will be ETIMEDOUT. + * @param local_sap (optional) The local address to bind to. If it's + * the default value of @c ACE_Addr::sap_any then the + * OS will choose an unused port. + * @param reuse_addr (optional) If the value is 1, the local address + * (@c local_sap) is reused, even if it hasn't been + * cleaned up yet. + * @param flags Ignored. + * @param perms Ignored. + * @param protocol (optional) If value is 0, default SOCK_STREAM + * protocol is selected by kernel (typically TCP). + * + * @return Returns 0 if the connection succeeds. If it fails, + * -1 is returned and errno contains a specific error + * code. + */ + ACE_SOCK_SCTP_STREAM_Connector (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Addr &remote_sap, + const ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol = 132); + + /** + * Actively connect to a peer, producing a connected @c ACE_SOCK_SCTP_STREAM + * object if the connection succeeds. + * + * @param new_association The @c ACE_SOCK_SCTP_STREAM object that will be connected + * to the peer. + * @param remote_sap The address that we are trying to connect to. + * The protocol family of @c remote_sap is used for + * the connected socket. That is, if @c remote_sap + * contains an IPv6 address, a socket with family + * PF_INET6 will be used, else it will be PF_INET. + * @param timeout Pointer to an @c ACE_Time_Value object with amount + * of time to wait to connect. If the pointer is 0 + * then the call blocks until the connection attempt + * is complete, whether it succeeds or fails. If + * *timeout == {0, 0} then the connection is done + * using nonblocking mode. In this case, if the + * connection can't be made immediately, this method + * returns -1 and errno == EWOULDBLOCK. + * If *timeout > {0, 0} then this is the maximum amount + * of time to wait before timing out; if the specified + * amount of time passes before the connection is made, + * this method returns -1 and errno == ETIME. Note + * the difference between this case and when a blocking + * connect is attmpted that TCP times out - in the latter + * case, errno will be ETIMEDOUT. + * @param local_sap (optional) The set of local addresses for SCTP to + * bind to. + * @param reuse_addr (optional) If the value is 1, the local address + * (@c local_sap) is reused, even if it hasn't been + * cleaned up yet. + * @param flags Ignored. + * @param perms Ignored. + * @param protocol (optional) If value is 0, default SOCK_STREAM + * protocol is selected by kernel (typically TCP). + * + * @return Returns 0 if the connection succeeds. If it fails, + * -1 is returned and errno contains a specific error + * code. + */ + ACE_SOCK_SCTP_STREAM_Connector (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Addr &remote_sap, + const ACE_Time_Value *timeout, + const ACE_Multihomed_INET_Addr &local_sap, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol = 132); + + /** + * Actively connect to a peer, producing a connected @c ACE_SOCK_SCTP_STREAM + * object if the connection succeeds. + * + * @param new_association The @c ACE_SOCK_SCTP_STREAM object that will be connected + * to the peer. + * @param remote_sap The address that we are trying to connect to. + * The protocol family of @c remote_sap is used for + * the connected socket. That is, if @c remote_sap + * contains an IPv6 address, a socket with family + * PF_INET6 will be used, else it will be PF_INET. + * @param timeout Pointer to an @c ACE_Time_Value object with amount + * of time to wait to connect. If the pointer is 0 + * then the call blocks until the connection attempt + * is complete, whether it succeeds or fails. If + * *timeout == {0, 0} then the connection is done + * using nonblocking mode. In this case, if the + * connection can't be made immediately, this method + * returns -1 and errno == EWOULDBLOCK. + * If *timeout > {0, 0} then this is the maximum amount + * of time to wait before timing out; if the specified + * amount of time passes before the connection is made, + * this method returns -1 and errno == ETIME. Note + * the difference between this case and when a blocking + * connect is attmpted that TCP times out - in the latter + * case, errno will be ETIMEDOUT. + * @param local_sap (optional) The local address to bind to. If it's + * the default value of @c ACE_Addr::sap_any then the + * OS will choose an unused port. + * @param reuse_addr (optional) If the value is 1, the local address + * (@c local_sap) is reused, even if it hasn't been + * cleaned up yet. + * @param flags Ignored. + * @param perms Ignored. + * @param protocol (optional) If value is 0, default SOCK_STREAM + * protocol is selected by kernel (typically TCP). + * + * @return Returns 0 if the connection succeeds. If it fails, + * -1 is returned and errno contains a specific error + * code. + */ + int connect (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Addr &remote_sap, + const ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol = 132); + + /** + * Actively connect to a peer, producing a connected @c ACE_SOCK_SCTP_STREAM + * object if the connection succeeds. + * + * @param new_association The @c ACE_SOCK_SCTP_STREAM object that will be connected + * to the peer. + * @param remote_sap The address that we are trying to connect to. + * The protocol family of @c remote_sap is used for + * the connected socket. That is, if @c remote_sap + * contains an IPv6 address, a socket with family + * PF_INET6 will be used, else it will be PF_INET. + * @param timeout Pointer to an @c ACE_Time_Value object with amount + * of time to wait to connect. If the pointer is 0 + * then the call blocks until the connection attempt + * is complete, whether it succeeds or fails. If + * *timeout == {0, 0} then the connection is done + * using nonblocking mode. In this case, if the + * connection can't be made immediately, this method + * returns -1 and errno == EWOULDBLOCK. + * If *timeout > {0, 0} then this is the maximum amount + * of time to wait before timing out; if the specified + * amount of time passes before the connection is made, + * this method returns -1 and errno == ETIME. Note + * the difference between this case and when a blocking + * connect is attmpted that TCP times out - in the latter + * case, errno will be ETIMEDOUT. + * @param local_sap (optional) The set of local addresses for SCTP to + * bind to. + * @param reuse_addr (optional) If the value is 1, the local address + * (@c local_sap) is reused, even if it hasn't been + * cleaned up yet. + * @param flags Ignored. + * @param perms Ignored. + * @param protocol (optional) If value is 0, default SOCK_STREAM + * protocol is selected by kernel (typically TCP). + * + * @return Returns 0 if the connection succeeds. If it fails, + * -1 is returned and errno contains a specific error + * code. + */ + + int connect (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Addr &remote_sap, + const ACE_Time_Value *timeout, + const ACE_Multihomed_INET_Addr &local_sap, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol = 132); + + /// Default dtor. + ~ACE_SOCK_SCTP_STREAM_Connector (void); + + // = Completion routine. + /** + * Try to complete a nonblocking connection that was begun by a + * previous call to connect with a {0, 0} ACE_Time_Value timeout. + * @see connect(). + * + * @param new_association The @c ACE_SOCK_SCTP_STREAM object that will be connected + * to the peer. + * @param remote_sap If non-0, it points to the @c ACE_INET_Addr object + * that will contain the address of the connected peer. + * @param timeout Same values and return value possibilites as for + * connect(). @see connect(). + */ + int complete (ACE_SOCK_SCTP_STREAM &new_association, + ACE_Addr *remote_sap = 0, + const ACE_Time_Value *timeout = 0); + + /// Resets any event associations on this handle + int reset_new_handle (ACE_HANDLE handle); + + // = Meta-type info + typedef ACE_Multihomed_INET_Addr PEER_ADDR; + typedef ACE_SOCK_SCTP_STREAM PEER_STREAM; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Perform operations that ensure the socket is opened using + /// BSD-style semantics (no QoS). + int shared_open (ACE_SOCK_SCTP_STREAM &new_association, + int protocol_family, + int protocol, + int reuse_addr); + + /// Perform operations that ensure the socket is opened using + /// QoS-enabled semantics. + int shared_open (ACE_SOCK_SCTP_STREAM &new_association, + int protocol_family, + int protocol, + ACE_Protocol_Info *protocolinfo, + ACE_SOCK_GROUP g, + u_long flags, + int reuse_addr); + + /// Perform operations that must be called before <ACE_OS::connect>. + int shared_connect_start (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Time_Value *timeout, + const ACE_Addr &local_sap); + + int shared_connect_start (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Time_Value *timeout, + const ACE_Multihomed_INET_Addr &local_sap); + + /// Perform operations that must be called after <ACE_OS::connect>. + int shared_connect_finish (ACE_SOCK_SCTP_STREAM &new_association, + const ACE_Time_Value *timeout, + int result); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/SOCK_SCTP_STREAM_Connector.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_SOCK_SCTP_STREAM_CONNECTOR_H */ diff --git a/ACE/ace/SOCK_SCTP_STREAM_Connector.inl b/ACE/ace/SOCK_SCTP_STREAM_Connector.inl new file mode 100644 index 00000000000..48e5078d817 --- /dev/null +++ b/ACE/ace/SOCK_SCTP_STREAM_Connector.inl @@ -0,0 +1,38 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// This constructor is used by a client when it wants to connect to +// the specified REMOTE_SAP address using a blocking open. + +ACE_INLINE +ACE_SOCK_SCTP_STREAM_Connector::~ACE_SOCK_SCTP_STREAM_Connector (void) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::~ACE_SOCK_SCTP_STREAM_Connector"); +} + +// Do-nothing constructor... + +ACE_INLINE +ACE_SOCK_SCTP_STREAM_Connector::ACE_SOCK_SCTP_STREAM_Connector (void) +{ + ACE_TRACE ("ACE_SOCK_SCTP_STREAM_Connector::ACE_SOCK_SCTP_STREAM_Connector"); +} + +ACE_INLINE int +ACE_SOCK_SCTP_STREAM_Connector::reset_new_handle (ACE_HANDLE handle) +{ +#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) + // Reset the event association + return ::WSAEventSelect ((SOCKET) handle, + NULL, + 0); +#else /* !defined ACE_HAS_WINSOCK2 */ + ACE_UNUSED_ARG (handle); + return 0; +#endif /* ACE_WIN32 */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ACE/ace/ace.mpc b/ACE/ace/ace.mpc index b8e8aef1839..b7668274556 100644 --- a/ACE/ace/ace.mpc +++ b/ACE/ace/ace.mpc @@ -225,6 +225,7 @@ project(ACE) : acedefaults, install, other, codecs, token, svcconf, uuid, fileca SOCK_SCTP_SEQPACK_Acceptor.cpp SOCK_SCTP_STREAM.cpp SOCK_SCTP_STREAM_Acceptor.cpp + SOCK_SCTP_STREAM_Connector.cpp SOCK_SEQPACK_Acceptor.cpp SOCK_SEQPACK_Association.cpp SOCK_SEQPACK_Connector.cpp |