Move SSL socket to folly
[folly.git] / folly / io / async / AsyncSSLServerSocket.h
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 #pragma once
20
21 #include <folly/io/async/SSLContext.h>
22 #include <folly/io/async/AsyncServerSocket.h>
23
24
25 namespace folly {
26 class SocketAddress;
27 class AsyncSSLSocket;
28
29 class AsyncSSLServerSocket : public DelayedDestruction,
30                              private AsyncServerSocket::AcceptCallback {
31  public:
32   class SSLAcceptCallback {
33    public:
34     virtual ~SSLAcceptCallback() {}
35
36     /**
37      * connectionAccepted() is called whenever a new client connection is
38      * received.
39      *
40      * The SSLAcceptCallback will remain installed after connectionAccepted()
41      * returns.
42      *
43      * @param sock        The newly accepted client socket.  The
44      *                    SSLAcceptCallback
45      *                    assumes ownership of this socket, and is responsible
46      *                    for closing it when done.
47      */
48     virtual void connectionAccepted(
49       const std::shared_ptr<AsyncSSLSocket> &sock)
50       noexcept = 0;
51
52     /**
53      * acceptError() is called if an error occurs while accepting.
54      *
55      * The SSLAcceptCallback will remain installed even after an accept error.
56      * If the callback wants to uninstall itself and stop trying to accept new
57      * connections, it must explicit call setAcceptCallback(nullptr).
58      *
59      * @param ex  An exception representing the error.
60      */
61     virtual void acceptError(const std::exception& ex) noexcept = 0;
62   };
63
64   /**
65    * Create a new TAsyncSSLServerSocket with the specified EventBase.
66    *
67    * @param eventBase  The EventBase to use for driving the asynchronous I/O.
68    *                   If this parameter is nullptr, attachEventBase() must be
69    *                   called before this socket can begin accepting
70    *                   connections.  All TAsyncSSLSocket objects accepted by
71    *                   this server socket will be attached to this EventBase
72    *                   when they are created.
73    */
74   explicit AsyncSSLServerSocket(
75     const std::shared_ptr<folly::SSLContext>& ctx,
76     EventBase* eventBase = nullptr);
77
78   /**
79    * Destroy the socket.
80    *
81    * destroy() must be called to destroy the socket.  The normal destructor is
82    * private, and should not be invoked directly.  This prevents callers from
83    * deleting a TAsyncSSLServerSocket while it is invoking a callback.
84    */
85   virtual void destroy();
86
87   virtual void bind(const folly::SocketAddress& address) {
88     serverSocket_->bind(address);
89   }
90   virtual void bind(uint16_t port) {
91     serverSocket_->bind(port);
92   }
93   void getAddress(folly::SocketAddress* addressReturn) {
94     serverSocket_->getAddress(addressReturn);
95   }
96   virtual void listen(int backlog) {
97     serverSocket_->listen(backlog);
98   }
99
100   /**
101    * Helper function to create a shared_ptr<TAsyncSSLServerSocket>.
102    *
103    * This passes in the correct destructor object, since TAsyncSSLServerSocket's
104    * destructor is protected and cannot be invoked directly.
105    */
106   static std::shared_ptr<AsyncSSLServerSocket> newSocket(
107     const std::shared_ptr<folly::SSLContext>& ctx,
108         EventBase* evb) {
109     return std::shared_ptr<AsyncSSLServerSocket>(
110       new AsyncSSLServerSocket(ctx, evb),
111       Destructor());
112   }
113
114   /**
115    * Set the accept callback.
116    *
117    * This method may only be invoked from the EventBase's loop thread.
118    *
119    * @param callback The callback to invoke when a new socket
120    *                 connection is accepted and a new TAsyncSSLSocket is
121    *                 created.
122    *
123    * Throws TTransportException on error.
124    */
125   void setSSLAcceptCallback(SSLAcceptCallback* callback);
126
127   SSLAcceptCallback *getSSLAcceptCallback() const {
128     return sslCallback_;
129   }
130
131   void attachEventBase(EventBase* eventBase);
132   void detachEventBase();
133
134   /**
135    * Returns the EventBase that the handler is currently attached to.
136    */
137   EventBase* getEventBase() const {
138     return eventBase_;
139   }
140
141  protected:
142   /**
143    * Protected destructor.
144    *
145    * Invoke destroy() instead to destroy the TAsyncSSLServerSocket.
146    */
147   virtual ~AsyncSSLServerSocket();
148
149  protected:
150   virtual void connectionAccepted(int fd,
151                                   const folly::SocketAddress& clientAddr)
152     noexcept;
153   virtual void acceptError(const std::exception& ex) noexcept;
154
155   EventBase* eventBase_;
156   AsyncServerSocket* serverSocket_;
157   // SSL context
158   std::shared_ptr<folly::SSLContext> ctx_;
159   // The accept callback
160   SSLAcceptCallback* sslCallback_;
161 };
162
163 } // namespace