12c593315Sopenharmony_ci/* 22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library 32c593315Sopenharmony_ci * 42c593315Sopenharmony_ci * Copyright (c) 2012 Tatsuhiro Tsujikawa 52c593315Sopenharmony_ci * 62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the 82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 122c593315Sopenharmony_ci * the following conditions: 132c593315Sopenharmony_ci * 142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be 152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software. 162c593315Sopenharmony_ci * 172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 242c593315Sopenharmony_ci */ 252c593315Sopenharmony_ci#ifndef SHRPX_CONNECTION_HANDLER_H 262c593315Sopenharmony_ci#define SHRPX_CONNECTION_HANDLER_H 272c593315Sopenharmony_ci 282c593315Sopenharmony_ci#include "shrpx.h" 292c593315Sopenharmony_ci 302c593315Sopenharmony_ci#include <sys/types.h> 312c593315Sopenharmony_ci#ifdef HAVE_SYS_SOCKET_H 322c593315Sopenharmony_ci# include <sys/socket.h> 332c593315Sopenharmony_ci#endif // HAVE_SYS_SOCKET_H 342c593315Sopenharmony_ci 352c593315Sopenharmony_ci#include <mutex> 362c593315Sopenharmony_ci#include <memory> 372c593315Sopenharmony_ci#include <vector> 382c593315Sopenharmony_ci#include <random> 392c593315Sopenharmony_ci#ifndef NOTHREADS 402c593315Sopenharmony_ci# include <future> 412c593315Sopenharmony_ci#endif // NOTHREADS 422c593315Sopenharmony_ci 432c593315Sopenharmony_ci#ifdef HAVE_LIBBPF 442c593315Sopenharmony_ci# include <bpf/libbpf.h> 452c593315Sopenharmony_ci#endif // HAVE_LIBBPF 462c593315Sopenharmony_ci 472c593315Sopenharmony_ci#include <openssl/ssl.h> 482c593315Sopenharmony_ci 492c593315Sopenharmony_ci#include <ev.h> 502c593315Sopenharmony_ci 512c593315Sopenharmony_ci#ifdef HAVE_NEVERBLEED 522c593315Sopenharmony_ci# include <neverbleed.h> 532c593315Sopenharmony_ci#endif // HAVE_NEVERBLEED 542c593315Sopenharmony_ci 552c593315Sopenharmony_ci#include "shrpx_downstream_connection_pool.h" 562c593315Sopenharmony_ci#include "shrpx_config.h" 572c593315Sopenharmony_ci#include "shrpx_exec.h" 582c593315Sopenharmony_ci 592c593315Sopenharmony_cinamespace shrpx { 602c593315Sopenharmony_ci 612c593315Sopenharmony_ciclass Http2Session; 622c593315Sopenharmony_ciclass ConnectBlocker; 632c593315Sopenharmony_ciclass AcceptHandler; 642c593315Sopenharmony_ciclass Worker; 652c593315Sopenharmony_cistruct WorkerStat; 662c593315Sopenharmony_cistruct TicketKeys; 672c593315Sopenharmony_ciclass MemcachedDispatcher; 682c593315Sopenharmony_cistruct UpstreamAddr; 692c593315Sopenharmony_ci 702c593315Sopenharmony_cinamespace tls { 712c593315Sopenharmony_ci 722c593315Sopenharmony_ciclass CertLookupTree; 732c593315Sopenharmony_ci 742c593315Sopenharmony_ci} // namespace tls 752c593315Sopenharmony_ci 762c593315Sopenharmony_cistruct OCSPUpdateContext { 772c593315Sopenharmony_ci // ocsp response buffer 782c593315Sopenharmony_ci std::vector<uint8_t> resp; 792c593315Sopenharmony_ci // Process running fetch-ocsp-response script 802c593315Sopenharmony_ci Process proc; 812c593315Sopenharmony_ci // index to ConnectionHandler::all_ssl_ctx_, which points to next 822c593315Sopenharmony_ci // SSL_CTX to update ocsp response cache. 832c593315Sopenharmony_ci size_t next; 842c593315Sopenharmony_ci ev_child chldev; 852c593315Sopenharmony_ci ev_io rev; 862c593315Sopenharmony_ci // errno encountered while processing response 872c593315Sopenharmony_ci int error; 882c593315Sopenharmony_ci}; 892c593315Sopenharmony_ci 902c593315Sopenharmony_ci// SerialEvent is an event sent from Worker thread. 912c593315Sopenharmony_cienum class SerialEventType { 922c593315Sopenharmony_ci NONE, 932c593315Sopenharmony_ci REPLACE_DOWNSTREAM, 942c593315Sopenharmony_ci}; 952c593315Sopenharmony_ci 962c593315Sopenharmony_cistruct SerialEvent { 972c593315Sopenharmony_ci // ctor for event uses DownstreamConfig 982c593315Sopenharmony_ci SerialEvent(SerialEventType type, 992c593315Sopenharmony_ci const std::shared_ptr<DownstreamConfig> &downstreamconf) 1002c593315Sopenharmony_ci : type(type), downstreamconf(downstreamconf) {} 1012c593315Sopenharmony_ci 1022c593315Sopenharmony_ci SerialEventType type; 1032c593315Sopenharmony_ci std::shared_ptr<DownstreamConfig> downstreamconf; 1042c593315Sopenharmony_ci}; 1052c593315Sopenharmony_ci 1062c593315Sopenharmony_ci#ifdef ENABLE_HTTP3 1072c593315Sopenharmony_ci# ifdef HAVE_LIBBPF 1082c593315Sopenharmony_cistruct BPFRef { 1092c593315Sopenharmony_ci bpf_object *obj; 1102c593315Sopenharmony_ci bpf_map *reuseport_array; 1112c593315Sopenharmony_ci bpf_map *cid_prefix_map; 1122c593315Sopenharmony_ci}; 1132c593315Sopenharmony_ci# endif // HAVE_LIBBPF 1142c593315Sopenharmony_ci 1152c593315Sopenharmony_ci// QUIC IPC message type. 1162c593315Sopenharmony_cienum class QUICIPCType { 1172c593315Sopenharmony_ci NONE, 1182c593315Sopenharmony_ci // Send forwarded QUIC UDP datagram and its metadata. 1192c593315Sopenharmony_ci DGRAM_FORWARD, 1202c593315Sopenharmony_ci}; 1212c593315Sopenharmony_ci 1222c593315Sopenharmony_ci// WorkerProcesses which are in graceful shutdown period. 1232c593315Sopenharmony_cistruct QUICLingeringWorkerProcess { 1242c593315Sopenharmony_ci QUICLingeringWorkerProcess( 1252c593315Sopenharmony_ci std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes, 1262c593315Sopenharmony_ci int quic_ipc_fd) 1272c593315Sopenharmony_ci : cid_prefixes{std::move(cid_prefixes)}, quic_ipc_fd{quic_ipc_fd} {} 1282c593315Sopenharmony_ci 1292c593315Sopenharmony_ci std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes; 1302c593315Sopenharmony_ci // Socket to send QUIC IPC message to this worker process. 1312c593315Sopenharmony_ci int quic_ipc_fd; 1322c593315Sopenharmony_ci}; 1332c593315Sopenharmony_ci#endif // ENABLE_HTTP3 1342c593315Sopenharmony_ci 1352c593315Sopenharmony_ciclass ConnectionHandler { 1362c593315Sopenharmony_cipublic: 1372c593315Sopenharmony_ci ConnectionHandler(struct ev_loop *loop, std::mt19937 &gen); 1382c593315Sopenharmony_ci ~ConnectionHandler(); 1392c593315Sopenharmony_ci int handle_connection(int fd, sockaddr *addr, int addrlen, 1402c593315Sopenharmony_ci const UpstreamAddr *faddr); 1412c593315Sopenharmony_ci // Creates Worker object for single threaded configuration. 1422c593315Sopenharmony_ci int create_single_worker(); 1432c593315Sopenharmony_ci // Creates |num| Worker objects for multi threaded configuration. 1442c593315Sopenharmony_ci // The |num| must be strictly more than 1. 1452c593315Sopenharmony_ci int create_worker_thread(size_t num); 1462c593315Sopenharmony_ci void 1472c593315Sopenharmony_ci set_ticket_keys_to_worker(const std::shared_ptr<TicketKeys> &ticket_keys); 1482c593315Sopenharmony_ci void worker_reopen_log_files(); 1492c593315Sopenharmony_ci void set_ticket_keys(std::shared_ptr<TicketKeys> ticket_keys); 1502c593315Sopenharmony_ci const std::shared_ptr<TicketKeys> &get_ticket_keys() const; 1512c593315Sopenharmony_ci struct ev_loop *get_loop() const; 1522c593315Sopenharmony_ci Worker *get_single_worker() const; 1532c593315Sopenharmony_ci void add_acceptor(std::unique_ptr<AcceptHandler> h); 1542c593315Sopenharmony_ci void delete_acceptor(); 1552c593315Sopenharmony_ci void enable_acceptor(); 1562c593315Sopenharmony_ci void disable_acceptor(); 1572c593315Sopenharmony_ci void sleep_acceptor(ev_tstamp t); 1582c593315Sopenharmony_ci void accept_pending_connection(); 1592c593315Sopenharmony_ci void graceful_shutdown_worker(); 1602c593315Sopenharmony_ci void set_graceful_shutdown(bool f); 1612c593315Sopenharmony_ci bool get_graceful_shutdown() const; 1622c593315Sopenharmony_ci void join_worker(); 1632c593315Sopenharmony_ci 1642c593315Sopenharmony_ci // Cancels ocsp update process 1652c593315Sopenharmony_ci void cancel_ocsp_update(); 1662c593315Sopenharmony_ci // Starts ocsp update for certificate |cert_file|. 1672c593315Sopenharmony_ci int start_ocsp_update(const char *cert_file); 1682c593315Sopenharmony_ci // Reads incoming data from ocsp update process 1692c593315Sopenharmony_ci void read_ocsp_chunk(); 1702c593315Sopenharmony_ci // Handles the completion of one ocsp update 1712c593315Sopenharmony_ci void handle_ocsp_complete(); 1722c593315Sopenharmony_ci // Resets ocsp_; 1732c593315Sopenharmony_ci void reset_ocsp(); 1742c593315Sopenharmony_ci // Proceeds to the next certificate's ocsp update. If all 1752c593315Sopenharmony_ci // certificates' ocsp update has been done, schedule next ocsp 1762c593315Sopenharmony_ci // update. 1772c593315Sopenharmony_ci void proceed_next_cert_ocsp(); 1782c593315Sopenharmony_ci 1792c593315Sopenharmony_ci void set_tls_ticket_key_memcached_dispatcher( 1802c593315Sopenharmony_ci std::unique_ptr<MemcachedDispatcher> dispatcher); 1812c593315Sopenharmony_ci 1822c593315Sopenharmony_ci MemcachedDispatcher *get_tls_ticket_key_memcached_dispatcher() const; 1832c593315Sopenharmony_ci void on_tls_ticket_key_network_error(ev_timer *w); 1842c593315Sopenharmony_ci void on_tls_ticket_key_not_found(ev_timer *w); 1852c593315Sopenharmony_ci void 1862c593315Sopenharmony_ci on_tls_ticket_key_get_success(const std::shared_ptr<TicketKeys> &ticket_keys, 1872c593315Sopenharmony_ci ev_timer *w); 1882c593315Sopenharmony_ci void schedule_next_tls_ticket_key_memcached_get(ev_timer *w); 1892c593315Sopenharmony_ci SSL_CTX *create_tls_ticket_key_memcached_ssl_ctx(); 1902c593315Sopenharmony_ci // Returns the SSL_CTX at all_ssl_ctx_[idx]. This does not perform 1912c593315Sopenharmony_ci // array bound checking. 1922c593315Sopenharmony_ci SSL_CTX *get_ssl_ctx(size_t idx) const; 1932c593315Sopenharmony_ci 1942c593315Sopenharmony_ci const std::vector<SSL_CTX *> &get_indexed_ssl_ctx(size_t idx) const; 1952c593315Sopenharmony_ci#ifdef ENABLE_HTTP3 1962c593315Sopenharmony_ci const std::vector<SSL_CTX *> &get_quic_indexed_ssl_ctx(size_t idx) const; 1972c593315Sopenharmony_ci 1982c593315Sopenharmony_ci int forward_quic_packet(const UpstreamAddr *faddr, const Address &remote_addr, 1992c593315Sopenharmony_ci const Address &local_addr, const ngtcp2_pkt_info &pi, 2002c593315Sopenharmony_ci const uint8_t *cid_prefix, const uint8_t *data, 2012c593315Sopenharmony_ci size_t datalen); 2022c593315Sopenharmony_ci 2032c593315Sopenharmony_ci void set_quic_keying_materials(std::shared_ptr<QUICKeyingMaterials> qkms); 2042c593315Sopenharmony_ci const std::shared_ptr<QUICKeyingMaterials> &get_quic_keying_materials() const; 2052c593315Sopenharmony_ci 2062c593315Sopenharmony_ci void set_cid_prefixes( 2072c593315Sopenharmony_ci const std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> 2082c593315Sopenharmony_ci &cid_prefixes); 2092c593315Sopenharmony_ci 2102c593315Sopenharmony_ci void set_quic_lingering_worker_processes( 2112c593315Sopenharmony_ci const std::vector<QUICLingeringWorkerProcess> &quic_lwps); 2122c593315Sopenharmony_ci 2132c593315Sopenharmony_ci // Return matching QUICLingeringWorkerProcess which has a CID prefix 2142c593315Sopenharmony_ci // such that |dcid| starts with it. If no such 2152c593315Sopenharmony_ci // QUICLingeringWorkerProcess, it returns nullptr. 2162c593315Sopenharmony_ci QUICLingeringWorkerProcess * 2172c593315Sopenharmony_ci match_quic_lingering_worker_process_cid_prefix(const uint8_t *dcid, 2182c593315Sopenharmony_ci size_t dcidlen); 2192c593315Sopenharmony_ci 2202c593315Sopenharmony_ci int forward_quic_packet_to_lingering_worker_process( 2212c593315Sopenharmony_ci QUICLingeringWorkerProcess *quic_lwp, const Address &remote_addr, 2222c593315Sopenharmony_ci const Address &local_addr, const ngtcp2_pkt_info &pi, const uint8_t *data, 2232c593315Sopenharmony_ci size_t datalen); 2242c593315Sopenharmony_ci 2252c593315Sopenharmony_ci void set_quic_ipc_fd(int fd); 2262c593315Sopenharmony_ci 2272c593315Sopenharmony_ci int quic_ipc_read(); 2282c593315Sopenharmony_ci 2292c593315Sopenharmony_ci# ifdef HAVE_LIBBPF 2302c593315Sopenharmony_ci std::vector<BPFRef> &get_quic_bpf_refs(); 2312c593315Sopenharmony_ci void unload_bpf_objects(); 2322c593315Sopenharmony_ci# endif // HAVE_LIBBPF 2332c593315Sopenharmony_ci#endif // ENABLE_HTTP3 2342c593315Sopenharmony_ci 2352c593315Sopenharmony_ci#ifdef HAVE_NEVERBLEED 2362c593315Sopenharmony_ci void set_neverbleed(neverbleed_t *nb); 2372c593315Sopenharmony_ci#endif // HAVE_NEVERBLEED 2382c593315Sopenharmony_ci 2392c593315Sopenharmony_ci // Send SerialEvent SerialEventType::REPLACE_DOWNSTREAM to this 2402c593315Sopenharmony_ci // object. 2412c593315Sopenharmony_ci void send_replace_downstream( 2422c593315Sopenharmony_ci const std::shared_ptr<DownstreamConfig> &downstreamconf); 2432c593315Sopenharmony_ci // Internal function to send |ev| to this object. 2442c593315Sopenharmony_ci void send_serial_event(SerialEvent ev); 2452c593315Sopenharmony_ci // Handles SerialEvents received. 2462c593315Sopenharmony_ci void handle_serial_event(); 2472c593315Sopenharmony_ci // Sends WorkerEvent to make them replace downstream. 2482c593315Sopenharmony_ci void 2492c593315Sopenharmony_ci worker_replace_downstream(std::shared_ptr<DownstreamConfig> downstreamconf); 2502c593315Sopenharmony_ci 2512c593315Sopenharmony_ci void set_enable_acceptor_on_ocsp_completion(bool f); 2522c593315Sopenharmony_ci 2532c593315Sopenharmony_ciprivate: 2542c593315Sopenharmony_ci // Stores all SSL_CTX objects. 2552c593315Sopenharmony_ci std::vector<SSL_CTX *> all_ssl_ctx_; 2562c593315Sopenharmony_ci // Stores all SSL_CTX objects in a way that its index is stored in 2572c593315Sopenharmony_ci // cert_tree. The SSL_CTXs stored in the same index share the same 2582c593315Sopenharmony_ci // hostname, but could have different signature algorithm. The 2592c593315Sopenharmony_ci // selection among them are performed by hostname presented by SNI, 2602c593315Sopenharmony_ci // and signature algorithm presented by client. 2612c593315Sopenharmony_ci std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx_; 2622c593315Sopenharmony_ci#ifdef ENABLE_HTTP3 2632c593315Sopenharmony_ci std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes_; 2642c593315Sopenharmony_ci std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> 2652c593315Sopenharmony_ci lingering_cid_prefixes_; 2662c593315Sopenharmony_ci int quic_ipc_fd_; 2672c593315Sopenharmony_ci std::vector<QUICLingeringWorkerProcess> quic_lingering_worker_processes_; 2682c593315Sopenharmony_ci# ifdef HAVE_LIBBPF 2692c593315Sopenharmony_ci std::vector<BPFRef> quic_bpf_refs_; 2702c593315Sopenharmony_ci# endif // HAVE_LIBBPF 2712c593315Sopenharmony_ci std::shared_ptr<QUICKeyingMaterials> quic_keying_materials_; 2722c593315Sopenharmony_ci std::vector<SSL_CTX *> quic_all_ssl_ctx_; 2732c593315Sopenharmony_ci std::vector<std::vector<SSL_CTX *>> quic_indexed_ssl_ctx_; 2742c593315Sopenharmony_ci#endif // ENABLE_HTTP3 2752c593315Sopenharmony_ci OCSPUpdateContext ocsp_; 2762c593315Sopenharmony_ci std::mt19937 &gen_; 2772c593315Sopenharmony_ci // ev_loop for each worker 2782c593315Sopenharmony_ci std::vector<struct ev_loop *> worker_loops_; 2792c593315Sopenharmony_ci // Worker instances when multi threaded mode (-nN, N >= 2) is used. 2802c593315Sopenharmony_ci // If at least one frontend enables API request, we allocate 1 2812c593315Sopenharmony_ci // additional worker dedicated to API request . 2822c593315Sopenharmony_ci std::vector<std::unique_ptr<Worker>> workers_; 2832c593315Sopenharmony_ci // mutex for serial event resive buffer handling 2842c593315Sopenharmony_ci std::mutex serial_event_mu_; 2852c593315Sopenharmony_ci // SerialEvent receive buffer 2862c593315Sopenharmony_ci std::vector<SerialEvent> serial_events_; 2872c593315Sopenharmony_ci // Worker instance used when single threaded mode (-n1) is used. 2882c593315Sopenharmony_ci // Otherwise, nullptr and workers_ has instances of Worker instead. 2892c593315Sopenharmony_ci std::unique_ptr<Worker> single_worker_; 2902c593315Sopenharmony_ci std::unique_ptr<tls::CertLookupTree> cert_tree_; 2912c593315Sopenharmony_ci#ifdef ENABLE_HTTP3 2922c593315Sopenharmony_ci std::unique_ptr<tls::CertLookupTree> quic_cert_tree_; 2932c593315Sopenharmony_ci#endif // ENABLE_HTTP3 2942c593315Sopenharmony_ci std::unique_ptr<MemcachedDispatcher> tls_ticket_key_memcached_dispatcher_; 2952c593315Sopenharmony_ci // Current TLS session ticket keys. Note that TLS connection does 2962c593315Sopenharmony_ci // not refer to this field directly. They use TicketKeys object in 2972c593315Sopenharmony_ci // Worker object. 2982c593315Sopenharmony_ci std::shared_ptr<TicketKeys> ticket_keys_; 2992c593315Sopenharmony_ci struct ev_loop *loop_; 3002c593315Sopenharmony_ci std::vector<std::unique_ptr<AcceptHandler>> acceptors_; 3012c593315Sopenharmony_ci#ifdef HAVE_NEVERBLEED 3022c593315Sopenharmony_ci neverbleed_t *nb_; 3032c593315Sopenharmony_ci#endif // HAVE_NEVERBLEED 3042c593315Sopenharmony_ci ev_timer disable_acceptor_timer_; 3052c593315Sopenharmony_ci ev_timer ocsp_timer_; 3062c593315Sopenharmony_ci ev_async thread_join_asyncev_; 3072c593315Sopenharmony_ci ev_async serial_event_asyncev_; 3082c593315Sopenharmony_ci#ifndef NOTHREADS 3092c593315Sopenharmony_ci std::future<void> thread_join_fut_; 3102c593315Sopenharmony_ci#endif // NOTHREADS 3112c593315Sopenharmony_ci size_t tls_ticket_key_memcached_get_retry_count_; 3122c593315Sopenharmony_ci size_t tls_ticket_key_memcached_fail_count_; 3132c593315Sopenharmony_ci unsigned int worker_round_robin_cnt_; 3142c593315Sopenharmony_ci bool graceful_shutdown_; 3152c593315Sopenharmony_ci // true if acceptors should be enabled after the initial ocsp update 3162c593315Sopenharmony_ci // has finished. 3172c593315Sopenharmony_ci bool enable_acceptor_on_ocsp_completion_; 3182c593315Sopenharmony_ci}; 3192c593315Sopenharmony_ci 3202c593315Sopenharmony_ci} // namespace shrpx 3212c593315Sopenharmony_ci 3222c593315Sopenharmony_ci#endif // SHRPX_CONNECTION_HANDLER_H 323