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