示例#1
0
ssize_t
ACE_SOCK_Netlink::recv (iovec iov[],
                        int n,
                        ACE_Addr &addr,
                        int flags) const
{
  ACE_TRACE ("ACE_SOCK_Netlink::recv");
  msghdr recv_msg;

  recv_msg.msg_iov = (iovec *) iov;
  recv_msg.msg_iovlen = n;
  recv_msg.msg_name = (char *) addr.get_addr ();
  recv_msg.msg_namelen = addr.get_size ();
  recv_msg.msg_control = 0;
  recv_msg.msg_controllen = 0;
  recv_msg.msg_flags = 0;

  ssize_t status = ACE_OS::recvmsg (this->get_handle (),
                                    &recv_msg,
                                    flags);

  if (recv_msg.msg_flags & MSG_TRUNC)
    return -1;

  addr.set_size (recv_msg.msg_namelen);
  addr.set_type (((sockaddr_in *) addr.get_addr())->sin_family);

  return status;
}
示例#2
0
int
ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
                             const ACE_Addr &remote_sap,
                             ACE_QoS_Params qos_params,
                             const ACE_Time_Value *timeout,
                             const ACE_Addr &local_sap,
                             ACE_Protocol_Info * protocolinfo,
                             ACE_SOCK_GROUP g,
                             u_long flags,
                             int reuse_addr,
                             int /* perms */)
{
  ACE_TRACE ("ACE_SOCK_Connector::connect");

  if (this->shared_open (new_stream,
                         remote_sap.get_type (),
                         0,
                         protocolinfo,
                         g,
                         flags,
                         reuse_addr) == -1)
    return -1;
  else if (this->shared_connect_start (new_stream,
                                       timeout,
                                       local_sap) == -1)
    return -1;

  int result = ACE_OS::connect (new_stream.get_handle (),
                                reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
                                remote_sap.get_size (),
                                qos_params);

  return this->shared_connect_finish (new_stream, timeout, result);
}
示例#3
0
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_WIN64)
  // 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_WIN64 */
  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;
    }
示例#4
0
int
ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
                             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_Connector::connect");

  if (this->shared_open (new_stream,
                         remote_sap.get_type (),
                         protocol,
                         reuse_addr) == -1)
    return -1;
  else if (this->shared_connect_start (new_stream,
                                       timeout,
                                       local_sap) == -1)
    return -1;

  int result = ACE_OS::connect (new_stream.get_handle (),
                                reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
                                remote_sap.get_size ());

  return this->shared_connect_finish (new_stream,
                                      timeout,
                                      result);
}
示例#5
0
int
ACE_SOCK_Connector::shared_connect_start (ACE_SOCK_Stream &new_stream,
                                          const ACE_Time_Value *timeout,
                                          const ACE_Addr &local_sap)
{
  ACE_TRACE ("ACE_SOCK_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_stream.get_handle (),
                        laddr,
                        size) == -1)
        {
          // Save/restore errno.
          ACE_Errno_Guard error (errno);
          new_stream.close ();
          return -1;
        }
    }

  // Enable non-blocking, if required.
  if (timeout != 0
      && new_stream.enable (ACE_NONBLOCK) == -1)
    return -1;
  else
    return 0;
}
示例#6
0
int
ACE_XTI_ATM_Mcast::add_leaf (ACE_TLI_Stream &current_stream,
                             const ACE_Addr &remote_sap,
                             ACE_INT32 leaf_id,
                             ACE_Time_Value *timeout)
{
  ACE_TRACE ("ACE_XTI_ATM_Mcast::add_leaf");

  struct netbuf call_req;
  memset(&call_req, 0, sizeof(call_req));
  call_req.len = remote_sap.get_size ();
  call_req.buf = (char *)remote_sap.get_addr ();

  if (::t_addleaf(current_stream.get_handle(),
                  leaf_id,
                  &call_req) < 0)
    {
      // Check for asynchronous event
      if (t_errno == TLOOK)
        {
          int const event = ACE_OS::t_look(current_stream.get_handle());
          if (event != TNODATA && event != T_DATA)
            return -1;
          else
            // If this doesn't work for asynchronous calls we need to call
            // the XTI/ATM t_rcvleafchange() function to check for t_addleaf
            // completion.
            return complete (current_stream, 0, timeout);
        }
      else
        return -1;
    }

  return 0;
}
ACE_CLASSIX_Port::ACE_CLASSIX_Port(ACE_Addr const& theAddr)
    : ACE_CLASSIX_Addr (sizeof (ACE_CLASSIX_Port_Core::Addr))
{
    if (theAddr.get_size() == this->get_size() &&
	theAddr.get_type() == this->get_type())
	this->set_(theAddr);
    else
	this->clear();
}
示例#8
0
int
ACE_TLI_Stream::get_remote_addr (ACE_Addr &sa) const
{
  ACE_TRACE ("ACE_TLI_Stream::get_remote_addr");

  struct netbuf name;
  name.maxlen = sa.get_size ();
  name.buf = (char *) sa.get_addr ();

  if(ACE_OS::t_getname (this->get_handle (), &name, REMOTENAME) == -1)
    return -1;
  else
    return 0;
}
示例#9
0
int
ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
                         int reuse_addr,
                         int protocol_family,
                         int backlog,
                         int protocol)
{
  ACE_TRACE ("ACE_SOCK_Acceptor::open");

  if (local_sap != ACE_Addr::sap_any)
    protocol_family = local_sap.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_STREAM,
                      protocol_family,
                      protocol,
                      reuse_addr) == -1)
    return -1;
  else
    return this->shared_open (local_sap,
                              protocol_family,
                              backlog);
}
示例#10
0
int
ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
                         ACE_Protocol_Info *protocolinfo,
                         ACE_SOCK_GROUP g,
                         u_long flags,
                         int reuse_addr,
                         int protocol_family,
                         int backlog,
                         int protocol)
{
  ACE_TRACE ("ACE_SOCK_Acceptor::open");

  if (protocol_family == PF_UNSPEC)
    protocol_family = local_sap.get_type ();

  if (ACE_SOCK::open (SOCK_STREAM,
                      protocol_family,
                      protocol,
                      protocolinfo,
                      g,
                      flags,
                      reuse_addr) == -1)
    return -1;
  else
    return this->shared_open (local_sap,
                              protocol_family,
                              backlog);
}
示例#11
0
文件: SOCK.cpp 项目: Adeer/OregonCore
int
ACE_SOCK::get_local_addr (ACE_Addr &sa) const
{
  ACE_TRACE ("ACE_SOCK::get_local_addr");

  int len = sa.get_size ();
  sockaddr *addr = reinterpret_cast<sockaddr *> (sa.get_addr ());

  if (ACE_OS::getsockname (this->get_handle (),
                           addr,
                           &len) == -1)
    return -1;

  sa.set_type (addr->sa_family);
  sa.set_size (len);
  return 0;
}
示例#12
0
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)
  if( ACE::handle_read_ready (this->get_handle (), timeout) != 1 )
    {
      return -1;
    }

  sockaddr *saddr = (sockaddr *) addr.get_addr ();
  int addr_len = addr.get_size ();
  int inlen;

  if (ACE_OS::ioctl (this->get_handle (),
                     FIONREAD,
                     &inlen) == -1)
    return -1;
  else if (inlen > 0)
    {
      ACE_NEW_RETURN (io_vec->iov_base,
                      char[inlen],
                      -1);
      ssize_t rcv_len = ACE_OS::recvfrom (this->get_handle (),
                                          (char *) io_vec->iov_base,
                                          inlen,
                                          flags,
                                          (sockaddr *) saddr,
                                          &addr_len);
      if (rcv_len < 0)
        {
          delete [] (char *)io_vec->iov_base;
          io_vec->iov_base = 0;
        }
      else
        {
          io_vec->iov_len = ACE_Utils::truncate_cast<u_long> (rcv_len);
          addr.set_size (addr_len);
        }
      return rcv_len;
    }
int
ACE_CLASSIX_Port::set_(const ACE_Addr& theAddr)
{
    ACE_CLASSIX_Port_Core::Addr *src = 
	((ACE_CLASSIX_Port_Core::Addr*) theAddr.get_addr());
    this->addr_.id = src->id;
    this->addr_.handle = src->handle;
	
    return 0;
}
示例#14
0
ssize_t
ACE_SOCK_Netlink::send (const iovec iov[],
                        int n,
                        const ACE_Addr &addr,
                        int flags) const
{
  ACE_TRACE ("ACE_SOCK_Netlink::send");
  msghdr send_msg;

  send_msg.msg_iov = (iovec *) iov;
  send_msg.msg_iovlen = n;
  send_msg.msg_name = (char *) addr.get_addr ();
  send_msg.msg_namelen = addr.get_size ();
  send_msg.msg_control = 0;
  send_msg.msg_controllen = 0;
  send_msg.msg_flags = 0;

  return ACE_OS::sendmsg (this->get_handle (),
                          &send_msg,
                          flags);
}
int
ACE_SOCK_Connector::shared_connect_start (ACE_SOCK_Stream &new_stream,
                                          const ACE_Time_Value *timeout,
                                          const ACE_Addr &local_sap)
{
  ACE_TRACE ("ACE_SOCK_Connector::shared_connect_start");

  if (local_sap != ACE_Addr::sap_any)
    {
      sockaddr *laddr = ACE_reinterpret_cast (sockaddr *,
                                              local_sap.get_addr ());
      int size = local_sap.get_size ();

      if (ACE_OS::bind (new_stream.get_handle (),
                        laddr,
                        size) == -1)
        {
          // Save/restore errno.
          ACE_Errno_Guard error (errno);
          new_stream.close ();
          return -1;
        }
    }
示例#16
0
int
SCTP_Connector::connect (ACE_SOCK_SEQPACK_Association &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 ("SCTP_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;

  if (new_association.set_option(SOL_SCTP,
                                 SCTP_HEARTBEAT_ITVL,
                                 &heart_beat_,
                                 sizeof(heart_beat_)) == -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);
}
示例#17
0
int
ACE_SOCK_Acceptor::shared_open (const ACE_Addr &local_sap,
                                int protocol_family,
                                int backlog)
{
  ACE_TRACE ("ACE_SOCK_Acceptor::shared_open");
  int error = 0;

#if defined (ACE_HAS_IPV6)
  if (protocol_family == PF_INET6)
    {
      sockaddr_in6 local_inet6_addr;
      ACE_OS::memset (reinterpret_cast<void *> (&local_inet6_addr),
                      0,
                      sizeof local_inet6_addr);

      if (local_sap == ACE_Addr::sap_any)
        {
          local_inet6_addr.sin6_family = AF_INET6;
          local_inet6_addr.sin6_port = 0;
          local_inet6_addr.sin6_addr = in6addr_any;
        }
      else
        local_inet6_addr = *reinterpret_cast<sockaddr_in6 *> (local_sap.get_addr ());

# if defined (ACE_WIN32)
      // on windows vista and later, Winsock can support dual stack sockets
      // but this must be explicitly set prior to the bind. Since this
      // behavior is the default on *nix platforms, it should be benigh to
      // just do it here. On older platforms the setsockopt will fail, but
      // that should be OK.
      int zero = 0;
      ACE_OS::setsockopt (this->get_handle (),
                          IPPROTO_IPV6,
                          IPV6_V6ONLY,
                          (char *)&zero,
                          sizeof (zero));
# endif /* ACE_WIN32 */
      // We probably don't need a bind_port written here.
      // There are currently no supported OS's that define
      // ACE_LACKS_WILDCARD_BIND.
      if (ACE_OS::bind (this->get_handle (),
                        reinterpret_cast<sockaddr *> (&local_inet6_addr),
                        sizeof local_inet6_addr) == -1)
        error = 1;
    }
  else
#endif
  if (protocol_family == PF_INET)
    {
      sockaddr_in local_inet_addr;
      ACE_OS::memset (reinterpret_cast<void *> (&local_inet_addr),
                      0,
                      sizeof local_inet_addr);

      if (local_sap == ACE_Addr::sap_any)
        {
          local_inet_addr.sin_port = 0;
        }
      else
        local_inet_addr = *reinterpret_cast<sockaddr_in *> (local_sap.get_addr ());
      if (local_inet_addr.sin_port == 0)
        {
          if (ACE::bind_port (this->get_handle (),
                              ACE_NTOHL (ACE_UINT32 (local_inet_addr.sin_addr.s_addr))) == -1)
            error = 1;
        }
      else if (ACE_OS::bind (this->get_handle (),
                             reinterpret_cast<sockaddr *> (&local_inet_addr),
                             sizeof local_inet_addr) == -1)
        error = 1;
    }
  else if (ACE_OS::bind (this->get_handle (),
                         (sockaddr *) local_sap.get_addr (),
                         local_sap.get_size ()) == -1)
    error = 1;

  if (error != 0
      || ACE_OS::listen (this->get_handle (),
                         backlog) == -1)
    {
      ACE_Errno_Guard g (errno);    // Preserve across close() below.
      error = 1;
      this->close ();
    }

  return error ? -1 : 0;
}
示例#18
0
int
ACE_TLI_Connector::connect (ACE_TLI_Stream &new_stream,
                            const ACE_Addr &remote_sap,
                            ACE_Time_Value *timeout,
                            const ACE_Addr &local_sap,
                            int reuse_addr,
                            int flags,
                            int /* perms */,
                            const char device[],
                            struct t_info *info,
                            int rwf,
                            struct netbuf *udata,
                            struct netbuf *opt)
{
  ACE_TRACE ("ACE_TLI_Connector::connect");
  int result = 0;

  // Only open a new endpoint if we don't already have a valid handle.

  if (new_stream.get_handle () == ACE_INVALID_HANDLE
      && new_stream.open (device, flags, info) == ACE_INVALID_HANDLE)
    return -1;

  if (local_sap != ACE_Addr::sap_any)
    {
      // Bind the local endpoint to a specific addr.

      struct t_bind *localaddr;

      localaddr = (struct t_bind *)
        ACE_OS::t_alloc (new_stream.get_handle (), T_BIND, T_ADDR);

      if (localaddr == 0)
        result = -1;
      else
        {
          int one = 1;
#if !defined (ACE_HAS_FORE_ATM_XTI)
          // Reusing the address causes problems with FORE's API. The
          // issue may be that t_optmgmt isn't fully supported by
          // FORE. t_errno is TBADOPT after the t_optmgmt call so
          // maybe options are configured differently for XTI than for
          // TLI (at least for FORE's implementation - XTI is supposed
          // to be a superset of TLI).
          if (reuse_addr
              && new_stream.set_option (SOL_SOCKET,
                                        SO_REUSEADDR,
                                        &one,
                                        sizeof one) == -1)
            result = -1;
          else
#endif /* ACE_HAS_FORE_ATM_XTI */
            {
              void *addr_buf = local_sap.get_addr ();
              localaddr->addr.len = local_sap.get_size ();
              ACE_OS::memcpy(localaddr->addr.buf,
                             addr_buf,
                             localaddr->addr.len);

              if (ACE_OS::t_bind (new_stream.get_handle (),
                                  localaddr,
                                  localaddr) == -1)
                result = -1;

              ACE_OS::t_free ((char *) localaddr,
                              T_BIND);
            }
        }

      if (result == -1)
        {
          new_stream.close ();
          return -1;
        }
    }
  // Let TLI select the local endpoint addr.
  else if (ACE_OS::t_bind (new_stream.get_handle (), 0, 0) == -1)
    return -1;

  struct t_call *callptr = 0;

  callptr = (struct t_call *)
    ACE_OS::t_alloc (new_stream.get_handle (), T_CALL, T_ADDR);

  if (callptr == 0)
    {
      new_stream.close ();
      return -1;
    }

  void *addr_buf = remote_sap.get_addr ();
  callptr->addr.len = remote_sap.get_size ();
  ACE_OS::memcpy (callptr->addr.buf,
                  addr_buf,
                  callptr->addr.len);
  //callptr->addr.buf = (char *) remote_sap.get_addr ();

  if (udata != 0)
    ACE_OS::memcpy ((void *) &callptr->udata, (void *) udata, sizeof *udata);
  if (opt != 0)
    ACE_OS::memcpy ((void *) &callptr->opt, (void *) opt, sizeof *opt);

  // Connect to remote endpoint.
#if defined (ACE_HAS_FORE_ATM_XTI)
  // FORE's XTI/ATM driver has problems with ioctl/fcntl calls so (at least
  // for now) always have blocking calls.
  timeout = 0;
#endif /* ACE_HAS_FORE_ATM_XTI */

  if (timeout != 0)   // Enable non-blocking, if required.
    {
      if (new_stream.enable (ACE_NONBLOCK) == -1)
        result = -1;

      // Do a non-blocking connect.
      if (ACE_OS::t_connect (new_stream.get_handle (), callptr, 0) == -1)
        {
          result = -1;

          // Check to see if we simply haven't connected yet on a
          // non-blocking handle or whether there's really an error.
          if (t_errno == TNODATA)
            {
              if (*timeout == ACE_Time_Value::zero)
                errno = EWOULDBLOCK;
              else
                result = this->complete (new_stream, 0, timeout);
            }
          else if (t_errno == TLOOK && new_stream.look () == T_DISCONNECT)
            new_stream.rcvdis ();
        }
    }
  // Do a blocking connect to the server.
  else if (ACE_OS::t_connect (new_stream.get_handle (), callptr, 0) == -1)
    result = -1;

  if (result != -1)
    {
      new_stream.set_rwflag (rwf);
#if defined (I_PUSH) && !defined (ACE_HAS_FORE_ATM_XTI)
      if (new_stream.get_rwflag ())
        result = ACE_OS::ioctl (new_stream.get_handle (),
                                I_PUSH,
                                const_cast<char *> ("tirdwr"));
#endif /* I_PUSH */
    }
  else if (!(errno == EWOULDBLOCK || errno == ETIME))
    {
      // If things have gone wrong, close down and return an error.
      new_stream.close ();
      new_stream.set_handle (ACE_INVALID_HANDLE);
    }

  if (ACE_OS::t_free ((char *) callptr, T_CALL) == -1)
    return -1;
  return result;
}
示例#19
0
int
ACE_SOCK_CODgram::open (const ACE_Addr &remote, const ACE_Addr &local,
                        int protocol_family, int protocol,
                        int reuse_addr)
{
  ACE_TRACE ("ACE_SOCK_CODgram::open");
  // Depending on the addresses passed as described above, figure out what
  // address family to specify for the new socket. If either address is
  // !ACE_Addr::sap_any, use that family. If they don't match, it's an error.
  if (remote != ACE_Addr::sap_any)
    {
      if (local == ACE_Addr::sap_any)
        protocol_family = remote.get_type ();
      else
        { // Both specified; family must match
          if (local.get_type () != remote.get_type ())
            {
              errno = EAFNOSUPPORT;
              return -1;
            }
          protocol_family = remote.get_type ();
        }
    }
  else
    {
      if (local != ACE_Addr::sap_any)
        {
          protocol_family = local.get_type ();
        }
    }
  if (ACE_SOCK::open (SOCK_DGRAM,
                      protocol_family,
                      protocol,
                      reuse_addr) == -1)
    {
      return -1;
    }
  else
    {
      bool error = false;

      if (local == ACE_Addr::sap_any && remote == ACE_Addr::sap_any)
        {
          // Assign an arbitrary port number from the transient range!!
          if ((protocol_family == PF_INET
#if defined (ACE_HAS_IPV6)
               || protocol_family == PF_INET6
#endif /* ACE_HAS_IPV6 */
              ) && ACE::bind_port (this->get_handle ()) == -1)
            error = true;
        }
      // We are binding just the local address.
      else if (local != ACE_Addr::sap_any && remote == ACE_Addr::sap_any)
        {
          if (ACE_OS::bind (this->get_handle (),
                            (sockaddr *) local.get_addr (),
                            local.get_size ()) == -1)
            error = true;
        }
      // We are connecting to the remote address.
      else if (local == ACE_Addr::sap_any && remote != ACE_Addr::sap_any)
        {
          if (ACE_OS::connect (this->get_handle (),
                               (sockaddr *) remote.get_addr (),
                               remote.get_size ()) == -1)
            error = true;
        }
      // We are binding to the local address and connecting to the
      // remote addresses.
      else
        {
          if (ACE_OS::bind (this->get_handle (),
                            (sockaddr *) local.get_addr (),
                            local.get_size ()) == -1
              || ACE_OS::connect (this->get_handle (),
                                  (sockaddr *) remote.get_addr (),
                                  remote.get_size ()) == -1)
            error = true;
        }
      if (error)
        {
          this->close ();
          this->set_handle (ACE_INVALID_HANDLE);
        }
      return error ? -1 : 0;
    }
}
示例#20
0
ACE_HANDLE
ACE_TLI_Acceptor::open (const ACE_Addr &remote_sap,
                        int reuse_addr,
                        int oflag,
                        struct t_info *info,
                        int qlen,
                        const char dev[])
{
  ACE_TRACE ("ACE_TLI_Acceptor::open");
  ACE_HANDLE res = 0;
  int one = 1;

  this->disp_ = 0;

  ACE_ALLOCATOR_RETURN (this->device_,
                        ACE_OS::strdup (dev),
                        ACE_INVALID_HANDLE);
  if (this->ACE_TLI::open (dev,
                           oflag,
                           info) == ACE_INVALID_HANDLE)
    res = ACE_INVALID_HANDLE;
#if !defined (ACE_HAS_FORE_ATM_XTI)
  // Reusing the address causes problems with FORE's API. The issue
  // may be that t_optmgmt isn't fully supported by FORE. t_errno is
  // TBADOPT after the t_optmgmt call so maybe options are configured
  // differently for XTI than for TLI (at least for FORE's
  // implementation - XTI is supposed to be a superset of TLI).
  else if (reuse_addr
           && this->set_option (SOL_SOCKET,
                                SO_REUSEADDR,
                                &one,
                                sizeof one) == -1)
    res = ACE_INVALID_HANDLE;
#endif /* ACE_HAS_FORE_ATM_XTI */
  else if ((this->disp_ =
            (struct t_discon *) ACE_OS::t_alloc (this->get_handle (),
                                                 T_DIS,
                                                 T_ALL)) == 0)
    res = ACE_INVALID_HANDLE;
  else
    {
      struct t_bind req;

#if defined (ACE_HAS_FORE_ATM_XTI)
      // Not sure why but FORE's t_bind call won't work if t_bind.qlen
      // != 1 Adjust the backlog accordingly.
      this->backlog_ = 1;
      req.qlen = 1;
#else
      this->backlog_ = qlen;
      req.qlen = qlen;
#endif /* ACE_HAS_FORE_ATM_XTI */
      req.addr.maxlen = remote_sap.get_size ();

      if (remote_sap == ACE_Addr::sap_any)
        // Note that if addr.len == 0 then ACE_TLI selects the port
        // number.
        req.addr.len = 0;
      else
        {
          req.addr.buf = (char *) remote_sap.get_addr ();
          req.addr.len = remote_sap.get_size ();
        }

      res = (ACE_HANDLE) ACE_OS::t_bind (this->get_handle (),
                                         &req,
                                         0);
      if (res != ACE_INVALID_HANDLE)
        {
          ACE_NEW_RETURN (this->queue_,
                          ACE_TLI_Request_Queue,
                          ACE_INVALID_HANDLE);
          res = this->queue_->open (this->get_handle (),
                                    this->backlog_);
        }
    }
  if (res == ACE_INVALID_HANDLE)
    this->close ();
  return this->get_handle ();
}
示例#21
0
int
ACE_SOCK_Acceptor::shared_open (const ACE_Addr &local_sap,
                                int protocol_family,
                                int backlog)
{
  ACE_TRACE ("ACE_SOCK_Acceptor::shared_open");
  int error = 0;

#if defined (ACE_HAS_IPV6)
  if (protocol_family == PF_INET6)
    {
      sockaddr_in6 local_inet6_addr;
      ACE_OS::memset (reinterpret_cast<void *> (&local_inet6_addr),
                      0,
                      sizeof local_inet6_addr);

      if (local_sap == ACE_Addr::sap_any)
        {
          local_inet6_addr.sin6_family = AF_INET6;
          local_inet6_addr.sin6_port = 0;
          local_inet6_addr.sin6_addr = in6addr_any;
        }
      else
        local_inet6_addr = *reinterpret_cast<sockaddr_in6 *> (local_sap.get_addr ());

      // We probably don't need a bind_port written here.
      // There are currently no supported OS's that define
      // ACE_LACKS_WILDCARD_BIND.
      if (ACE_OS::bind (this->get_handle (),
                        reinterpret_cast<sockaddr *> (&local_inet6_addr),
                        sizeof local_inet6_addr) == -1)
        error = 1;
    }
  else
#endif
  if (protocol_family == PF_INET)
    {
      sockaddr_in local_inet_addr;
      ACE_OS::memset (reinterpret_cast<void *> (&local_inet_addr),
                      0,
                      sizeof local_inet_addr);

      if (local_sap == ACE_Addr::sap_any)
        {
          local_inet_addr.sin_port = 0;
        }
      else
        local_inet_addr = *reinterpret_cast<sockaddr_in *> (local_sap.get_addr ());
      if (local_inet_addr.sin_port == 0)
        {
          if (ACE::bind_port (this->get_handle (),
                              ACE_NTOHL (ACE_UINT32 (local_inet_addr.sin_addr.s_addr))) == -1)
            error = 1;
        }
      else if (ACE_OS::bind (this->get_handle (),
                             reinterpret_cast<sockaddr *> (&local_inet_addr),
                             sizeof local_inet_addr) == -1)
        error = 1;
    }
  else if (ACE_OS::bind (this->get_handle (),
                         (sockaddr *) local_sap.get_addr (),
                         local_sap.get_size ()) == -1)
    error = 1;

  if (error != 0
      || ACE_OS::listen (this->get_handle (),
                         backlog) == -1)
    {
      ACE_Errno_Guard g (errno);    // Preserve across close() below.
      error = 1;
      this->close ();
    }

  return error ? -1 : 0;
}