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