TCPTransportInterface.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. // Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #ifndef _FASTDDS_TCP_TRANSPORT_INTERFACE_H_
  15. #define _FASTDDS_TCP_TRANSPORT_INTERFACE_H_
  16. #include <fastdds/rtps/transport/TransportInterface.h>
  17. #include <fastdds/rtps/transport/TCPTransportDescriptor.h>
  18. #include <fastrtps/utils/IPFinder.h>
  19. #include <fastdds/rtps/transport/tcp/RTCPHeader.h>
  20. #include <fastdds/rtps/transport/TCPChannelResourceBasic.h>
  21. #include <fastdds/rtps/transport/TCPAcceptorBasic.h>
  22. #if TLS_FOUND
  23. #include <fastdds/rtps/transport/TCPAcceptorSecure.h>
  24. #include <asio/ssl.hpp>
  25. #endif
  26. #include <asio.hpp>
  27. #include <thread>
  28. #include <vector>
  29. #include <map>
  30. #include <memory>
  31. #include <mutex>
  32. namespace eprosima{
  33. namespace fastdds{
  34. namespace rtps{
  35. class RTCPMessageManager;
  36. class TCPChannelResource;
  37. /**
  38. * This is a default TCP Interface implementation.
  39. * - Opening an output channel by passing a remote locator will try to open a TCP conection with the endpoint.
  40. * If there is created a connection with the same endpoint, the transport will use the same one.
  41. *
  42. * - It is possible to provide a white list at construction, which limits the interfaces the transport
  43. * will ever be able to interact with. If left empty, all interfaces are allowed.
  44. *
  45. * - Opening an input channel by passing a locator will open a socket listening on the given physical port on every
  46. * whitelisted interface, it will wait for incomming connections until the receiver closes the channel.
  47. * Several endpoints can connect to other to the same physical port, because the OS creates a connection socket
  48. * after each establishment.
  49. * @ingroup TRANSPORT_MODULE
  50. */
  51. class TCPTransportInterface : public TransportInterface
  52. {
  53. class ReceiverInUseCV
  54. {
  55. public:
  56. bool in_use = false;
  57. std::condition_variable cv;
  58. };
  59. std::atomic<bool> alive_;
  60. protected:
  61. std::vector<fastrtps::rtps::IPFinder::info_IP> current_interfaces_;
  62. asio::io_service io_service_;
  63. asio::io_service io_service_timers_;
  64. #if TLS_FOUND
  65. asio::ssl::context ssl_context_;
  66. #endif
  67. std::shared_ptr<std::thread> io_service_thread_;
  68. std::shared_ptr<std::thread> io_service_timers_thread_;
  69. std::shared_ptr<RTCPMessageManager> rtcp_message_manager_;
  70. std::mutex rtcp_message_manager_mutex_;
  71. std::condition_variable rtcp_message_manager_cv_;
  72. mutable std::mutex sockets_map_mutex_;
  73. mutable std::mutex unbound_map_mutex_;
  74. std::map<fastrtps::rtps::Locator_t, std::shared_ptr<TCPChannelResource>> channel_resources_; // The key is the "Physical locator"
  75. std::vector<std::shared_ptr<TCPChannelResource>> unbound_channel_resources_;
  76. // The key is the logical port
  77. std::map<uint16_t, std::pair<TransportReceiverInterface*, ReceiverInUseCV*>> receiver_resources_;
  78. std::vector<std::pair<TCPChannelResource*, uint64_t>> sockets_timestamp_;
  79. asio::steady_timer keep_alive_event_;
  80. std::map<fastrtps::rtps::Locator_t, std::shared_ptr<TCPAcceptor>> acceptors_;
  81. TCPTransportInterface(int32_t transport_kind);
  82. virtual bool compare_locator_ip(
  83. const fastrtps::rtps::Locator_t& lh,
  84. const fastrtps::rtps::Locator_t& rh) const = 0;
  85. virtual bool compare_locator_ip_and_port(
  86. const fastrtps::rtps::Locator_t& lh,
  87. const fastrtps::rtps::Locator_t& rh) const = 0;
  88. virtual void fill_local_ip(fastrtps::rtps::Locator_t& loc) const = 0;
  89. //! Methods to manage the TCP headers and their CRC values.
  90. bool check_crc(
  91. const TCPHeader &header,
  92. const fastrtps::rtps::octet *data,
  93. uint32_t size) const;
  94. void calculate_crc(
  95. TCPHeader &header,
  96. const fastrtps::rtps::octet *data,
  97. uint32_t size) const;
  98. void fill_rtcp_header(
  99. TCPHeader& header,
  100. const fastrtps::rtps::octet* send_buffer,
  101. uint32_t send_buffer_size,
  102. uint16_t logical_port) const;
  103. //! Closes the given p_channel_resource and unbind it from every resource.
  104. void close_tcp_socket(std::shared_ptr<TCPChannelResource>& channel);
  105. //! Creates a TCP acceptor to wait for incomming connections by the given locator.
  106. bool create_acceptor_socket(const fastrtps::rtps::Locator_t& locator);
  107. virtual void get_ips(
  108. std::vector<fastrtps::rtps::IPFinder::info_IP>& loc_names,
  109. bool return_loopback = false) const = 0;
  110. bool is_input_port_open(uint16_t port) const;
  111. //! Functions to be called from new threads, which takes cares of performing a blocking receive
  112. void perform_listen_operation(
  113. std::weak_ptr<TCPChannelResource> channel,
  114. std::weak_ptr<RTCPMessageManager> rtcp_manager);
  115. bool read_body(
  116. fastrtps::rtps::octet* receive_buffer,
  117. uint32_t receive_buffer_capacity,
  118. uint32_t* bytes_received,
  119. std::shared_ptr<TCPChannelResource>& channel,
  120. std::size_t body_size);
  121. virtual void set_receive_buffer_size(uint32_t size) = 0;
  122. virtual void set_send_buffer_size(uint32_t size) = 0;
  123. void clean(); // Must be called on childs destructors!
  124. virtual void endpoint_to_locator(
  125. const asio::ip::tcp::endpoint& endpoint,
  126. fastrtps::rtps::Locator_t& locator) const = 0;
  127. /**
  128. * Shutdown method to close the connections of the transports.
  129. */
  130. virtual void shutdown() override;
  131. /**
  132. * Applies TLS configuration to ssl_context
  133. */
  134. void apply_tls_config();
  135. /**
  136. * Aux method to retrieve cert password as a callback
  137. */
  138. std::string get_password() const;
  139. /**
  140. * Send a buffer to a destination
  141. */
  142. bool send(
  143. const fastrtps::rtps::octet* send_buffer,
  144. uint32_t send_buffer_size,
  145. std::shared_ptr<TCPChannelResource>& channel,
  146. const fastrtps::rtps::Locator_t& remote_locator);
  147. public:
  148. friend class RTCPMessageManager;
  149. virtual ~TCPTransportInterface();
  150. //! Stores the binding between the given locator and the given TCP socket. Server side.
  151. void bind_socket(std::shared_ptr<TCPChannelResource>&);
  152. //! Removes the listening socket for the specified port.
  153. virtual bool CloseInputChannel(const fastrtps::rtps::Locator_t&) override;
  154. //! Removes all outbound sockets on the given port.
  155. void CloseOutputChannel(std::shared_ptr<TCPChannelResource>& channel);
  156. //! Reports whether Locators correspond to the same port.
  157. virtual bool DoInputLocatorsMatch(
  158. const fastrtps::rtps::Locator_t&,
  159. const fastrtps::rtps::Locator_t&) const override;
  160. virtual asio::ip::tcp::endpoint generate_endpoint(uint16_t port) const = 0;
  161. virtual asio::ip::tcp::endpoint generate_endpoint(
  162. const fastrtps::rtps::Locator_t& loc,
  163. uint16_t port) const = 0;
  164. virtual asio::ip::tcp::endpoint generate_local_endpoint(
  165. fastrtps::rtps::Locator_t& loc,
  166. uint16_t port) const = 0;
  167. virtual asio::ip::tcp generate_protocol() const = 0;
  168. virtual asio::ip::tcp get_protocol_type() const = 0;
  169. virtual uint16_t GetLogicalPortIncrement() const = 0;
  170. virtual uint16_t GetLogicalPortRange() const = 0;
  171. virtual uint16_t GetMaxLogicalPort() const = 0;
  172. bool init() override;
  173. //! Checks whether there are open and bound sockets for the given port.
  174. virtual bool IsInputChannelOpen(const fastrtps::rtps::Locator_t&) const override;
  175. //! Checks if the interfaces white list is empty.
  176. virtual bool is_interface_whitelist_empty() const = 0;
  177. /**
  178. * Checks if the given locator is allowed by the white list.
  179. * @param loc locator to check.
  180. * @return True if the locator passes the white list.
  181. */
  182. virtual bool is_interface_allowed(const fastrtps::rtps::Locator_t& loc) const = 0;
  183. virtual bool is_interface_allowed(const std::string& interface) const = 0;
  184. //! Checks for TCP kinds.
  185. virtual bool IsLocatorSupported(const fastrtps::rtps::Locator_t&) const override;
  186. //! Checks whether there are open and bound sockets for the given port.
  187. bool is_output_channel_open_for(const fastrtps::rtps::Locator_t&) const;
  188. /** Opens an input channel to receive incomming connections.
  189. * If there is an existing channel it registers the receiver resource.
  190. */
  191. virtual bool OpenInputChannel(
  192. const fastrtps::rtps::Locator_t&,
  193. TransportReceiverInterface*, uint32_t) override;
  194. //! Opens a socket on the given address and port (as long as they are white listed).
  195. virtual bool OpenOutputChannel(
  196. SendResourceList& send_resource_list,
  197. const fastrtps::rtps::Locator_t&) override;
  198. /**
  199. * Converts a given remote locator (that is, a locator referring to a remote
  200. * destination) to the main local locator whose channel can write to that
  201. * destination. In this case it will return a 0.0.0.0 address on that port.
  202. */
  203. virtual fastrtps::rtps::Locator_t RemoteToMainLocal(const fastrtps::rtps::Locator_t&) const override;
  204. /**
  205. * Transforms a remote locator into a locator optimized for local communications.
  206. *
  207. * If the remote locator corresponds to one of the local interfaces, it is converted
  208. * to the corresponding local address.
  209. *
  210. * @param [in] remote_locator Locator to be converted.
  211. * @param [out] result_locator Converted locator.
  212. *
  213. * @return false if the input locator is not supported/allowed by this transport, true otherwise.
  214. */
  215. virtual bool transform_remote_locator(
  216. const fastrtps::rtps::Locator_t& remote_locator,
  217. fastrtps::rtps::Locator_t& result_locator) const override;
  218. /**
  219. * Blocking Receive from the specified channel.
  220. * @param rtcp_manager pointer to the RTCP Manager.
  221. * @param channel pointer to the socket where the method is going to read the messages.
  222. * @param receive_buffer vector with enough capacity (not size) to accomodate a full receive buffer. That
  223. * capacity must not be less than the receive_buffer_size supplied to this class during construction.
  224. * @param receive_buffer_capacity maximum size of the buffer.
  225. * @param[out] receive_buffer_size Size of the packet received.
  226. * @param[out] remote_locator associated remote locator.
  227. */
  228. bool Receive(
  229. std::weak_ptr<RTCPMessageManager>& rtcp_manager,
  230. std::shared_ptr<TCPChannelResource>& channel,
  231. fastrtps::rtps::octet* receive_buffer,
  232. uint32_t receive_buffer_capacity,
  233. uint32_t& receive_buffer_size,
  234. fastrtps::rtps::Locator_t& remote_locator);
  235. /**
  236. * Blocking Send through the specified channel.
  237. * @param send_buffer Slice into the raw data to send.
  238. * @param send_buffer_size Size of the raw data. It will be used as a bounds check for the previous argument.
  239. * It must not exceed the send_buffer_size fed to this class during construction.
  240. * @param channel channel we're sending from.
  241. * @param destination_locators_begin pointer to destination locators iterator begin, the iterator can be advanced inside this fuction
  242. * so should not be reuse.
  243. * @param destination_locators_end pointer to destination locators iterator end, the iterator can be advanced inside this fuction
  244. * so should not be reuse.
  245. */
  246. bool send(
  247. const fastrtps::rtps::octet* send_buffer,
  248. uint32_t send_buffer_size,
  249. std::shared_ptr<TCPChannelResource>& channel,
  250. fastrtps::rtps::LocatorsIterator* destination_locators_begin,
  251. fastrtps::rtps::LocatorsIterator* destination_locators_end);
  252. /**
  253. * Performs the locator selection algorithm for this transport.
  254. *
  255. * It basically consists of the following steps
  256. * - selector.transport_starts is called
  257. * - transport handles the selection state of each locator
  258. * - if a locator from an entry is selected, selector.select is called for that entry
  259. *
  260. * In the case of TCP, multicast locators are never selected. All TCPv6 unicast locators
  261. * are selected. For TCPv4, only locators on the same WAN as the transport or with the
  262. * WAN address of a connected channel are selected.
  263. *
  264. * @param [in, out] selector Locator selector.
  265. */
  266. virtual void select_locators(fastrtps::rtps::LocatorSelector& selector) const override;
  267. //! Callback called each time that an incomming connection is accepted.
  268. void SocketAccepted(
  269. std::shared_ptr<asio::ip::tcp::socket> socket,
  270. const fastrtps::rtps::Locator_t& locator,
  271. const asio::error_code& error);
  272. #if TLS_FOUND
  273. //! Callback called each time that an incomming connection is accepted (secure).
  274. void SecureSocketAccepted(
  275. std::shared_ptr<asio::ssl::stream<asio::ip::tcp::socket>> socket,
  276. const fastrtps::rtps::Locator_t& locator,
  277. const asio::error_code& error);
  278. #endif
  279. //! Callback called each time that an outgoing connection is established.
  280. void SocketConnected(
  281. const std::weak_ptr<TCPChannelResource>& channel,
  282. const asio::error_code& error);
  283. /**
  284. * Method to get a list of binding interfaces.
  285. * @return Vector of interfaces in string format.
  286. */
  287. virtual std::vector<std::string> get_binding_interfaces_list() = 0;
  288. virtual bool getDefaultMetatrafficMulticastLocators(
  289. fastrtps::rtps::LocatorList_t &locators,
  290. uint32_t metatraffic_multicast_port) const override;
  291. virtual bool getDefaultMetatrafficUnicastLocators(
  292. fastrtps::rtps::LocatorList_t &locators,
  293. uint32_t metatraffic_unicast_port) const override;
  294. bool getDefaultUnicastLocators(
  295. fastrtps::rtps::LocatorList_t &locators,
  296. uint32_t unicast_port) const override;
  297. virtual bool fillMetatrafficMulticastLocator(
  298. fastrtps::rtps::Locator_t &locator,
  299. uint32_t metatraffic_multicast_port) const override;
  300. virtual bool fillMetatrafficUnicastLocator(
  301. fastrtps::rtps::Locator_t &locator,
  302. uint32_t metatraffic_unicast_port) const override;
  303. virtual bool configureInitialPeerLocator(
  304. fastrtps::rtps::Locator_t &locator,
  305. const fastrtps::rtps::PortParameters &port_params,
  306. uint32_t domainId,
  307. fastrtps::rtps::LocatorList_t& list) const override;
  308. virtual bool fillUnicastLocator(
  309. fastrtps::rtps::Locator_t &locator,
  310. uint32_t well_known_port) const override;
  311. virtual uint32_t max_recv_buffer_size() const override
  312. {
  313. return configuration()->maxMessageSize;
  314. }
  315. void DeleteSocket(TCPChannelResource *channelResource);
  316. virtual const TCPTransportDescriptor* configuration() const = 0;
  317. virtual TCPTransportDescriptor* configuration() = 0;
  318. void keep_alive();
  319. };
  320. } // namespace rtps
  321. } // namespace fastdds
  322. } // namespace eprosima
  323. #endif // _FASTDDS_TCP_TRANSPORT_INTERFACE_H_