Apache Mesos
openssl_socket.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License
12 
13 #ifndef __SSL_SOCKET_WRAPPER__
14 #define __SSL_SOCKET_WRAPPER__
15 
16 #include <process/loop.hpp>
17 #include <process/once.hpp>
18 #include <process/queue.hpp>
19 #include <process/socket.hpp>
20 
21 #include "poll_socket.hpp"
22 
23 namespace process {
24 namespace network {
25 namespace internal {
26 
28 {
29 public:
30  // See 'Socket::create()'.
32 
34  ~OpenSSLSocketImpl() override;
35 
36  // Implement 'SocketImpl' interface.
37  Future<Nothing> connect(const Address& address) override;
39  const Address& address,
40  const openssl::TLSClientConfig& config) override;
41 
42  Future<size_t> recv(char* data, size_t size) override;
43  Future<size_t> send(const char* data, size_t size) override;
44  Future<size_t> sendfile(int_fd fd, off_t offset, size_t size) override;
46  SocketImpl::Kind kind() const override { return SocketImpl::Kind::SSL; }
47 
48  // Shuts down the socket.
49  //
50  // NOTE: Although this method accepts an integer which specifies the
51  // shutdown mode, this parameter is ignored because SSL connections
52  // do not have a concept of read/write-only shutdown. If either end
53  // of the socket is closed, then the futures of any outstanding read
54  // requests will be completed (possibly as failures).
55  Try<Nothing, SocketError> shutdown(int how) override;
56 
57 protected:
58  // Verifies incoming sockets and initiates the SSL handshake.
59  // Upon completion or failure of the SSL handshake, the peer socket
60  // (or Failure object) will be enqueued on the server socket's accept queue.
61  void handle_accept_callback(const std::shared_ptr<SocketImpl>& socket);
62 
63  // Takes ownership of the given SSL object and performs an SSL handshake
64  // with the context of the SSL object. Either `SSL_set_connect_state`
65  // or `SSL_set_accept_state` must be called on the context beforehand,
66  // so that the handshake is done from the correct perspective.
68 
69  // Used to check the result of `SSL_do_handshake`, `SSL_read`,
70  // or `SSL_write` in a `process::loop`.
71  // `handle_as_read` should be set to `true` when this helper is called
72  // from `SSL_read` to handle the EOF event differently. Our socket
73  // API expects a return value of `0` when reading EOF, and a failure
74  // otherwise.
76  int result,
77  bool handle_as_read);
78 
79 private:
80  SSL* ssl;
81  Option<net::IP> peer_ip;
83 
84  Once accept_loop_started;
85 
86  // This queue stores accepted sockets that are considered connected
87  // (either the SSL handshake has completed or the socket has been
88  // downgraded). The 'accept()' call returns sockets from this queue.
89  // We wrap the socket in a 'Future' so that we can pass failures or
90  // discards through.
92 
93  // Set to true whenever the connection is terminated before a proper
94  // SSL shutdown can be sent. This will also prevent `shutdown` from
95  // doing anything, as the connection will be presumed dead.
96  bool dirty_shutdown;
97 
98  // An actor used to dispatch the compute-heavy work of encryption and
99  // decryption, like `SSL_read` and `SSL_write`.
100  Option<UPID> compute_thread;
101 };
102 
103 } // namespace internal {
104 } // namespace network {
105 } // namespace process {
106 
107 #endif // __SSL_SOCKET_WRAPPER__
Definition: openssl_socket.hpp:27
Future< Nothing > connect(const Address &address) override
Try< Nothing, SocketError > shutdown(int how) override
Shuts down the socket.
Future< ControlFlow< size_t > > handle_ssl_return_result(int result, bool handle_as_read)
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:130
Definition: check.hpp:33
int_fd s
Definition: socket.hpp:246
Kind
Available kinds of implementations.
Definition: socket.hpp:67
Definition: address.hpp:324
Future< size_t > send(const char *data, size_t size) override
Try< Address > address() const
Returns the Address with the assigned ip and assigned port.
Future< std::shared_ptr< SocketImpl > > accept() override
Returns an implementation corresponding to the next pending connection for the listening socket...
Future< size_t > set_ssl_and_do_handshake(SSL *_ssl)
Definition: poll_socket.hpp:27
void handle_accept_callback(const std::shared_ptr< SocketImpl > &socket)
Definition: once.hpp:25
SocketImpl::Kind kind() const override
Definition: openssl_socket.hpp:46
Future< size_t > recv(char *data, size_t size) override
Definition: attributes.hpp:24
Definition: queue.hpp:29
Definition: executor.hpp:48
static Try< std::shared_ptr< SocketImpl > > create(int_fd s)
Try< Netlink< struct nl_sock > > socket(int protocol=NETLINK_ROUTE)
Definition: internal.hpp:91
int int_fd
Definition: int_fd.hpp:35
Future< size_t > sendfile(int_fd fd, off_t offset, size_t size) override