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; }
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); }
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); }
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; }
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; }
int ACE_XTI_ATM_Mcast::add_leaf (ACE_TLI_Stream ¤t_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; }
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; }
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; }
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; }
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; }
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; } }
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); }
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; }
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; }
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; }
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 (); }
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; } }