1 // Copyright 2018 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_CONNECTION_FACTORY_POSIX_H_ 6 #define PLATFORM_IMPL_TLS_CONNECTION_FACTORY_POSIX_H_ 7 8 #include <openssl/ssl.h> 9 10 #include <memory> 11 12 #include "platform/api/tls_connection.h" 13 #include "platform/api/tls_connection_factory.h" 14 #include "platform/base/error.h" 15 #include "platform/impl/platform_client_posix.h" 16 #include "platform/impl/tls_data_router_posix.h" 17 #include "util/weak_ptr.h" 18 19 namespace openscreen { 20 21 class StreamSocket; 22 23 class TlsConnectionFactoryPosix : public TlsConnectionFactory, 24 public TlsDataRouterPosix::SocketObserver { 25 public: 26 TlsConnectionFactoryPosix(Client* client, 27 TaskRunner* task_runner, 28 PlatformClientPosix* platform_client = 29 PlatformClientPosix::GetInstance()); 30 ~TlsConnectionFactoryPosix() override; 31 32 // TlsConnectionFactory overrides. 33 // 34 // TODO(jophba, rwkeane): Determine how to handle multiple connection attempts 35 // to the same remote_address, and how to distinguish errors. 36 void Connect(const IPEndpoint& remote_address, 37 const TlsConnectOptions& options) override; 38 void SetListenCredentials(const TlsCredentials& credentials) override; 39 void Listen(const IPEndpoint& local_address, 40 const TlsListenOptions& options) override; 41 42 private: 43 // TlsDataRouterPosix::SocketObserver overrides. 44 void OnConnectionPending(StreamSocketPosix* socket) override; 45 46 // Configures a new SSL connection when a StreamSocket connection is accepted. 47 void OnSocketAccepted(std::unique_ptr<StreamSocket> socket); 48 49 // Configures the SSL connection for the provided TlsConnectionPosix, 50 // returning true if the process is successful, false otherwise. 51 bool ConfigureSsl(TlsConnectionPosix* connection); 52 53 // Ensures that SSL is initialized, then gets a new SSL connection. 54 ErrorOr<bssl::UniquePtr<SSL>> GetSslConnection(); 55 56 // Method wrapping the Initialize() private method, that can be safely called 57 // multiple times. 58 void EnsureInitialized(); 59 60 // Create the shared context used for all SSL connections created by this 61 // factory. 62 void Initialize(); 63 64 // Handles their respective SSL handshake calls. These will continue to be 65 // scheduled on |task_runner_| until the handshake completes. 66 void Connect(std::unique_ptr<TlsConnectionPosix> connection); 67 void Accept(std::unique_ptr<TlsConnectionPosix> connection); 68 69 // Called on any thread, to post a task to notify the Client that a connection 70 // failure or other error has occurred. 71 void DispatchConnectionFailed(const IPEndpoint& remote_endpoint); 72 void DispatchError(Error error); 73 74 // Thread-safe mechanism to ensure Initialize() is only called once. 75 std::once_flag init_instance_flag_; 76 77 // Are the Listen() credentials set? Getting the certificate directly 78 // from the SSL_CTX is non-trivial, so we store a property instead. 79 bool listen_credentials_set_ = false; 80 81 Client* const client_; 82 TaskRunner* const task_runner_; 83 PlatformClientPosix* const platform_client_; 84 85 // SSL context, for creating SSL Connections via BoringSSL. 86 bssl::UniquePtr<SSL_CTX> ssl_context_; 87 88 WeakPtrFactory<TlsConnectionFactoryPosix> weak_factory_{this}; 89 90 OSP_DISALLOW_COPY_AND_ASSIGN(TlsConnectionFactoryPosix); 91 }; 92 93 } // namespace openscreen 94 95 #endif // PLATFORM_IMPL_TLS_CONNECTION_FACTORY_POSIX_H_ 96