1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef PLATFORM_IMPL_TLS_DATA_ROUTER_POSIX_H_ 6 #define PLATFORM_IMPL_TLS_DATA_ROUTER_POSIX_H_ 7 8 #include <memory> 9 #include <mutex> 10 #include <unordered_map> 11 #include <vector> 12 13 #include "absl/base/thread_annotations.h" 14 #include "platform/api/time.h" 15 #include "platform/impl/socket_handle_waiter.h" 16 #include "util/osp_logging.h" 17 18 namespace openscreen { 19 20 class StreamSocketPosix; 21 class TlsConnectionPosix; 22 23 // This class is responsible for 3 operations: 24 // 1) Listen for incoming connections on registed StreamSockets. 25 // 2) Check all registered TlsConnections for read data via boringSSL call 26 // and pass all read data to the connection's observer. 27 // 3) Check all registered TlsConnections' write buffers for additional data 28 // to be written out. If any is present, write it using boringSSL. 29 // The above operations also imply that this class must support registration 30 // of StreamSockets and TlsConnections. 31 // These operations will be called repeatedly on the networking thread, so none 32 // of them should block. Additionally, this class must ensure that deletions of 33 // the above types do not occur while a socket/connection is currently being 34 // accessed from the networking thread. 35 class TlsDataRouterPosix : public SocketHandleWaiter::Subscriber { 36 public: 37 class SocketObserver { 38 public: 39 virtual ~SocketObserver() = default; 40 41 // Socket creation shouldn't occur on the Networking thread, so pass the 42 // socket to the observer and expect them to call socket->Accept() on the 43 // correct thread. 44 virtual void OnConnectionPending(StreamSocketPosix* socket) = 0; 45 }; 46 47 // The provided SocketHandleWaiter is expected to live for the duration of 48 // this object's lifetime. 49 TlsDataRouterPosix( 50 SocketHandleWaiter* waiter, 51 std::function<Clock::time_point()> now_function = Clock::now); 52 ~TlsDataRouterPosix() override; 53 54 // Register a TlsConnection that should be watched for readable and writable 55 // data. 56 void RegisterConnection(TlsConnectionPosix* connection); 57 58 // Deregister a TlsConnection. 59 void DeregisterConnection(TlsConnectionPosix* connection); 60 61 // Takes ownership of a StreamSocket and registers that it should be watched 62 // for incoming TCP connections with the SocketHandleWaiter. 63 void RegisterAcceptObserver(std::unique_ptr<StreamSocketPosix> socket, 64 SocketObserver* observer); 65 66 // Stops watching TCP sockets added by a particular observer for incoming 67 // connections. 68 void DeregisterAcceptObserver(SocketObserver* observer); 69 70 // SocketHandleWaiter::Subscriber overrides. 71 void ProcessReadyHandle(SocketHandleWaiter::SocketHandleRef handle, 72 uint32_t flags) override; 73 74 OSP_DISALLOW_COPY_AND_ASSIGN(TlsDataRouterPosix); 75 76 protected: 77 // Determines if the provided socket is currently being watched by this 78 // instance. 79 bool IsSocketWatched(StreamSocketPosix* socket) const; 80 81 virtual bool HasTimedOut(Clock::time_point start_time, 82 Clock::duration timeout); 83 84 friend class TestingDataRouter; 85 86 bool disable_locking_for_testing_ = false; 87 88 private: 89 SocketHandleWaiter* waiter_; 90 91 // Mutex guarding connections_ vector. 92 mutable std::mutex connections_mutex_; 93 94 // Mutex guarding |accept_socket_mappings_|. 95 mutable std::mutex accept_socket_mutex_; 96 97 // Function to get the current time. 98 std::function<Clock::time_point()> now_function_; 99 100 // Mapping from all sockets to the observer that should be called when the 101 // socket recognizes an incoming connection. 102 std::unordered_map<StreamSocketPosix*, SocketObserver*> 103 accept_socket_mappings_ GUARDED_BY(accept_socket_mutex_); 104 105 // Set of all TlsConnectionPosix objects currently registered. 106 std::vector<TlsConnectionPosix*> connections_ GUARDED_BY(connections_mutex_); 107 108 // StreamSockets currently owned by this object, being watched for 109 std::vector<std::unique_ptr<StreamSocketPosix>> accept_stream_sockets_ 110 GUARDED_BY(accept_socket_mutex_); 111 }; 112 113 } // namespace openscreen 114 115 #endif // PLATFORM_IMPL_TLS_DATA_ROUTER_POSIX_H_ 116