1 /* 2 * nghttp2 - HTTP/2 C Library 3 * 4 * Copyright (c) 2012 Tatsuhiro Tsujikawa 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef SHRPX_CONNECTION_HANDLER_H 26 #define SHRPX_CONNECTION_HANDLER_H 27 28 #include "shrpx.h" 29 30 #include <sys/types.h> 31 #ifdef HAVE_SYS_SOCKET_H 32 # include <sys/socket.h> 33 #endif // HAVE_SYS_SOCKET_H 34 35 #include <mutex> 36 #include <memory> 37 #include <vector> 38 #include <random> 39 #ifndef NOTHREADS 40 # include <future> 41 #endif // NOTHREADS 42 43 #include <openssl/ssl.h> 44 45 #include <ev.h> 46 47 #ifdef HAVE_NEVERBLEED 48 # include <neverbleed.h> 49 #endif // HAVE_NEVERBLEED 50 51 #include "shrpx_downstream_connection_pool.h" 52 #include "shrpx_config.h" 53 #include "shrpx_exec.h" 54 55 namespace shrpx { 56 57 class Http2Session; 58 class ConnectBlocker; 59 class AcceptHandler; 60 class Worker; 61 struct WorkerStat; 62 struct TicketKeys; 63 class MemcachedDispatcher; 64 struct UpstreamAddr; 65 66 namespace tls { 67 68 class CertLookupTree; 69 70 } // namespace tls 71 72 struct OCSPUpdateContext { 73 // ocsp response buffer 74 std::vector<uint8_t> resp; 75 // Process running fetch-ocsp-response script 76 Process proc; 77 // index to ConnectionHandler::all_ssl_ctx_, which points to next 78 // SSL_CTX to update ocsp response cache. 79 size_t next; 80 ev_child chldev; 81 ev_io rev; 82 // errno encountered while processing response 83 int error; 84 }; 85 86 // SerialEvent is an event sent from Worker thread. 87 enum class SerialEventType { 88 NONE, 89 REPLACE_DOWNSTREAM, 90 }; 91 92 struct SerialEvent { 93 // ctor for event uses DownstreamConfig SerialEventSerialEvent94 SerialEvent(SerialEventType type, 95 const std::shared_ptr<DownstreamConfig> &downstreamconf) 96 : type(type), downstreamconf(downstreamconf) {} 97 98 SerialEventType type; 99 std::shared_ptr<DownstreamConfig> downstreamconf; 100 }; 101 102 class ConnectionHandler { 103 public: 104 ConnectionHandler(struct ev_loop *loop, std::mt19937 &gen); 105 ~ConnectionHandler(); 106 int handle_connection(int fd, sockaddr *addr, int addrlen, 107 const UpstreamAddr *faddr); 108 // Creates Worker object for single threaded configuration. 109 int create_single_worker(); 110 // Creates |num| Worker objects for multi threaded configuration. 111 // The |num| must be strictly more than 1. 112 int create_worker_thread(size_t num); 113 void 114 set_ticket_keys_to_worker(const std::shared_ptr<TicketKeys> &ticket_keys); 115 void worker_reopen_log_files(); 116 void set_ticket_keys(std::shared_ptr<TicketKeys> ticket_keys); 117 const std::shared_ptr<TicketKeys> &get_ticket_keys() const; 118 struct ev_loop *get_loop() const; 119 Worker *get_single_worker() const; 120 void add_acceptor(std::unique_ptr<AcceptHandler> h); 121 void delete_acceptor(); 122 void enable_acceptor(); 123 void disable_acceptor(); 124 void sleep_acceptor(ev_tstamp t); 125 void accept_pending_connection(); 126 void graceful_shutdown_worker(); 127 void set_graceful_shutdown(bool f); 128 bool get_graceful_shutdown() const; 129 void join_worker(); 130 131 // Cancels ocsp update process 132 void cancel_ocsp_update(); 133 // Starts ocsp update for certficate |cert_file|. 134 int start_ocsp_update(const char *cert_file); 135 // Reads incoming data from ocsp update process 136 void read_ocsp_chunk(); 137 // Handles the completion of one ocsp update 138 void handle_ocsp_complete(); 139 // Resets ocsp_; 140 void reset_ocsp(); 141 // Proceeds to the next certificate's ocsp update. If all 142 // certificates' ocsp update has been done, schedule next ocsp 143 // update. 144 void proceed_next_cert_ocsp(); 145 146 void set_tls_ticket_key_memcached_dispatcher( 147 std::unique_ptr<MemcachedDispatcher> dispatcher); 148 149 MemcachedDispatcher *get_tls_ticket_key_memcached_dispatcher() const; 150 void on_tls_ticket_key_network_error(ev_timer *w); 151 void on_tls_ticket_key_not_found(ev_timer *w); 152 void 153 on_tls_ticket_key_get_success(const std::shared_ptr<TicketKeys> &ticket_keys, 154 ev_timer *w); 155 void schedule_next_tls_ticket_key_memcached_get(ev_timer *w); 156 SSL_CTX *create_tls_ticket_key_memcached_ssl_ctx(); 157 // Returns the SSL_CTX at all_ssl_ctx_[idx]. This does not perform 158 // array bound checking. 159 SSL_CTX *get_ssl_ctx(size_t idx) const; 160 161 const std::vector<SSL_CTX *> &get_indexed_ssl_ctx(size_t idx) const; 162 163 #ifdef HAVE_NEVERBLEED 164 void set_neverbleed(neverbleed_t *nb); 165 #endif // HAVE_NEVERBLEED 166 167 // Send SerialEvent SerialEventType::REPLACE_DOWNSTREAM to this 168 // object. 169 void send_replace_downstream( 170 const std::shared_ptr<DownstreamConfig> &downstreamconf); 171 // Internal function to send |ev| to this object. 172 void send_serial_event(SerialEvent ev); 173 // Handles SerialEvents received. 174 void handle_serial_event(); 175 // Sends WorkerEvent to make them replace downstream. 176 void 177 worker_replace_downstream(std::shared_ptr<DownstreamConfig> downstreamconf); 178 179 void set_enable_acceptor_on_ocsp_completion(bool f); 180 181 private: 182 // Stores all SSL_CTX objects. 183 std::vector<SSL_CTX *> all_ssl_ctx_; 184 // Stores all SSL_CTX objects in a way that its index is stored in 185 // cert_tree. The SSL_CTXs stored in the same index share the same 186 // hostname, but could have different signature algorithm. The 187 // selection among them are performed by hostname presented by SNI, 188 // and signature algorithm presented by client. 189 std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx_; 190 OCSPUpdateContext ocsp_; 191 std::mt19937 &gen_; 192 // ev_loop for each worker 193 std::vector<struct ev_loop *> worker_loops_; 194 // Worker instances when multi threaded mode (-nN, N >= 2) is used. 195 // If at least one frontend enables API request, we allocate 1 196 // additional worker dedicated to API request . 197 std::vector<std::unique_ptr<Worker>> workers_; 198 // mutex for serial event resive buffer handling 199 std::mutex serial_event_mu_; 200 // SerialEvent receive buffer 201 std::vector<SerialEvent> serial_events_; 202 // Worker instance used when single threaded mode (-n1) is used. 203 // Otherwise, nullptr and workers_ has instances of Worker instead. 204 std::unique_ptr<Worker> single_worker_; 205 std::unique_ptr<tls::CertLookupTree> cert_tree_; 206 std::unique_ptr<MemcachedDispatcher> tls_ticket_key_memcached_dispatcher_; 207 // Current TLS session ticket keys. Note that TLS connection does 208 // not refer to this field directly. They use TicketKeys object in 209 // Worker object. 210 std::shared_ptr<TicketKeys> ticket_keys_; 211 struct ev_loop *loop_; 212 std::vector<std::unique_ptr<AcceptHandler>> acceptors_; 213 #ifdef HAVE_NEVERBLEED 214 neverbleed_t *nb_; 215 #endif // HAVE_NEVERBLEED 216 ev_timer disable_acceptor_timer_; 217 ev_timer ocsp_timer_; 218 ev_async thread_join_asyncev_; 219 ev_async serial_event_asyncev_; 220 #ifndef NOTHREADS 221 std::future<void> thread_join_fut_; 222 #endif // NOTHREADS 223 size_t tls_ticket_key_memcached_get_retry_count_; 224 size_t tls_ticket_key_memcached_fail_count_; 225 unsigned int worker_round_robin_cnt_; 226 bool graceful_shutdown_; 227 // true if acceptors should be enabled after the initial ocsp update 228 // has finished. 229 bool enable_acceptor_on_ocsp_completion_; 230 }; 231 232 } // namespace shrpx 233 234 #endif // SHRPX_CONNECTION_HANDLER_H 235