YARP
Yet Another Robot Platform
SocketTwoWayStream.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4  * SPDX-FileCopyrightText: 2006 Anne van Rossum <anne@almende.com>
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
9 
14 #include <yarp/os/impl/TcpStream.h>
15 
16 #ifdef YARP_HAS_ACE
17 # include <ace/INET_Addr.h>
18 # include <ace/os_include/netinet/os_tcp.h>
19 // In one the ACE headers there is a definition of "main" for WIN32
20 # ifdef main
21 # undef main
22 # endif
23 #elif (__unix__)
24 # include <netinet/tcp.h>
25 #endif
26 
27 using namespace yarp::os;
28 using namespace yarp::os::impl;
29 
30 YARP_OS_LOG_COMPONENT(SOCKETTWOWAYSTREAM, "yarp.os.impl.SocketTwoWayStream")
31 
32 int SocketTwoWayStream::open(const Contact& address)
33 {
34  if (address.getPort() == -1) {
35  return -1;
36  }
37  std::string host = address.getHost();
38  yarp::os::impl::TcpConnector connector;
39 #ifdef YARP_HAS_ACE
40  if (address.getHost() == "localhost") {
41  // ACE does not like localhost. At all.
43  }
44  ACE_INET_Addr addr(address.getPort(), host.c_str());
45  YARP_timeval openTimeout;
46  YARP_timeval* timeout = nullptr;
47  if (address.hasTimeout()) {
48  openTimeout.set(address.getTimeout());
49  timeout = &openTimeout;
50  }
51  int result = connector.connect(stream, addr, timeout, ACE_Addr::sap_any, 1);
52 #else
53  int result;
54 
55  if (address.hasTimeout()) {
56  YARP_timeval timeout;
57  /* set timeout seconds and microseconds */
58  timeout.tv_sec = static_cast<int>(address.getTimeout());
59  timeout.tv_usec = (address.getTimeout() - timeout.tv_sec) * 1000000;
60  result = connector.connect(stream, address, &timeout);
61  } else {
62  result = connector.connect(stream, address, nullptr);
63  }
64 
65 
66 #endif
67  if (result >= 0) {
68  happy = true;
69  } else {
71  "TCP connection to tcp:/%s failed to open",
72  address.toURI(false).c_str());
73  }
74  updateAddresses();
75  return result;
76 }
77 
78 int SocketTwoWayStream::open(yarp::os::impl::TcpAcceptor& acceptor)
79 {
80  int result = acceptor.accept(stream);
81  if (result >= 0) {
82  happy = true;
83  }
84  updateAddresses();
85  return result;
86 }
87 
88 
89 void SocketTwoWayStream::updateAddresses()
90 {
91  int one = 1;
92  stream.set_option(IPPROTO_TCP, TCP_NODELAY, &one, sizeof(int));
93 #ifdef YARP_HAS_ACE
94  ACE_INET_Addr local;
95  ACE_INET_Addr remote;
96  stream.get_local_addr(local);
97  stream.get_remote_addr(remote);
98 
99  char localHostAddress[256];
100  char remoteHostAddress[256];
101  local.get_host_addr(localHostAddress, 256);
102  remote.get_host_addr(remoteHostAddress, 256);
103  localAddress = Contact(localHostAddress, local.get_port_number());
104  remoteAddress = Contact(remoteHostAddress, remote.get_port_number());
105 #else
106  struct sockaddr local;
107  struct sockaddr remote;
108  memset(&local, 0, sizeof(local));
109  memset(&remote, 0, sizeof(remote));
110  stream.get_local_addr(local);
111  stream.get_remote_addr(remote);
112  if (local.sa_family == AF_INET || local.sa_family == AF_INET6) {
113  char* localHostAddress = new char[local.sa_family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN];
114  char* remoteHostAddress = new char[remote.sa_family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN];
115  const char* ret = nullptr;
116  ret = inet_ntop(local.sa_family,
117  (local.sa_family == AF_INET ? reinterpret_cast<void*>(&reinterpret_cast<struct sockaddr_in*>(&local)->sin_addr) : reinterpret_cast<void*>(&reinterpret_cast<struct sockaddr_in6*>(&local)->sin6_addr)),
118  localHostAddress,
119  (local.sa_family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN));
120  if (ret) {
121  localAddress = Contact(localHostAddress, ntohs(reinterpret_cast<struct sockaddr_in*>(&local)->sin_port));
122  } else {
123  yCError(SOCKETTWOWAYSTREAM, "SocketTwoWayStream::updateAddresses failed getting local address");
124  }
125  ret = inet_ntop(remote.sa_family,
126  (remote.sa_family == AF_INET ? reinterpret_cast<void*>(&reinterpret_cast<struct sockaddr_in*>(&remote)->sin_addr) : reinterpret_cast<void*>(&reinterpret_cast<struct sockaddr_in6*>(&remote)->sin6_addr)),
127  remoteHostAddress,
128  (remote.sa_family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN));
129  if (ret) {
130  remoteAddress = Contact(remoteHostAddress, ntohs(reinterpret_cast<struct sockaddr_in*>(&remote)->sin_port));
131  } else {
132  yCError(SOCKETTWOWAYSTREAM, "SocketTwoWayStream::updateAddresses failed getting local address");
133  }
134  delete[] localHostAddress;
135  delete[] remoteHostAddress;
136  } else {
137  yCError(SOCKETTWOWAYSTREAM, "Unknown address type");
138  }
139 #endif
140 
141  yCDebug(SOCKETTWOWAYSTREAM, "updateAddresses: local address = %s", localAddress.getHost().c_str());
142  yCDebug(SOCKETTWOWAYSTREAM, "updateAddresses: remote address = %s", remoteAddress.getHost().c_str());
143 }
144 
146 {
147  yCDebug(SOCKETTWOWAYSTREAM, "Setting tos = %d", tos);
148  return (stream.set_option(IPPROTO_IP, IP_TOS, &tos, static_cast<int>(sizeof(tos))) == 0);
149 }
150 
152 {
153  int tos = -1;
154  int optlen;
155  stream.get_option(IPPROTO_IP, IP_TOS, &tos, &optlen);
156  return tos;
157 }
bool ret
const yarp::os::LogComponent & SOCKETTWOWAYSTREAM()
Represents how to reach a part of a YARP network.
Definition: Contact.h:36
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition: Contact.cpp:228
static std::string getHostName(bool prefer_loopback=false, const std::string &seed="")
Definition: NameConfig.cpp:208
A stream abstraction for socket communication.
int open(const Contact &address)
#define yCError(component,...)
Definition: LogComponent.h:154
#define yCDebug(component,...)
Definition: LogComponent.h:109
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:35
The components from which ports and connections are built.
struct timeval YARP_timeval
Definition: PlatformTime.h:32
An interface to the operating system, including Port based communication.