1 /* 2 * nghttp2 - HTTP/2 C Library 3 * 4 * Copyright (c) 2021 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_QUIC_CONNECTION_HANDLER_H 26 #define SHRPX_QUIC_CONNECTION_HANDLER_H 27 28 #include "shrpx.h" 29 30 #include <memory> 31 #include <unordered_map> 32 #include <string> 33 #include <vector> 34 35 #include <ngtcp2/ngtcp2.h> 36 37 #include <ev.h> 38 39 #include "shrpx_quic.h" 40 #include "network.h" 41 42 using namespace nghttp2; 43 44 namespace shrpx { 45 46 struct UpstreamAddr; 47 class ClientHandler; 48 class Worker; 49 50 // CloseWait handles packets received in close-wait (draining or 51 // closing period). 52 struct CloseWait { 53 CloseWait(Worker *worker, std::vector<ngtcp2_cid> scids, 54 std::vector<uint8_t> pkt, ev_tstamp period); 55 ~CloseWait(); 56 57 int handle_packet(const UpstreamAddr *faddr, const Address &remote_addr, 58 const Address &local_addr, const ngtcp2_pkt_info &pi, 59 std::span<const uint8_t> data); 60 61 Worker *worker; 62 // Source Connection IDs of the connection. 63 std::vector<ngtcp2_cid> scids; 64 // QUIC packet which is sent in response to the incoming packet. It 65 // might be empty. 66 std::vector<uint8_t> pkt; 67 // Close-wait (draining or closing period) timer. 68 ev_timer timer; 69 // The number of bytes received during close-wait period. 70 size_t bytes_recv; 71 // The number of bytes sent during close-wait period. 72 size_t bytes_sent; 73 // The number of packets received during close-wait period. 74 size_t num_pkts_recv; 75 // If the number of packets received reaches this number, send a 76 // QUIC packet. 77 size_t next_pkts_recv; 78 }; 79 80 class QUICConnectionHandler { 81 public: 82 QUICConnectionHandler(Worker *worker); 83 ~QUICConnectionHandler(); 84 int handle_packet(const UpstreamAddr *faddr, const Address &remote_addr, 85 const Address &local_addr, const ngtcp2_pkt_info &pi, 86 std::span<const uint8_t> data); 87 // Send Retry packet. |ini_dcid| is the destination Connection ID 88 // which appeared in Client Initial packet. |ini_scid| is the 89 // source Connection ID which appeared in Client Initial packet. 90 int send_retry(const UpstreamAddr *faddr, uint32_t version, 91 std::span<const uint8_t> ini_dcid, 92 std::span<const uint8_t> ini_scid, const Address &remote_addr, 93 const Address &local_addr, size_t max_pktlen); 94 // Send Version Negotiation packet. |ini_dcid| is the destination 95 // Connection ID which appeared in Client Initial packet. 96 // |ini_scid| is the source Connection ID which appeared in Client 97 // Initial packet. 98 int send_version_negotiation(const UpstreamAddr *faddr, uint32_t version, 99 std::span<const uint8_t> ini_dcid, 100 std::span<const uint8_t> ini_scid, 101 const Address &remote_addr, 102 const Address &local_addr); 103 int send_stateless_reset(const UpstreamAddr *faddr, size_t pktlen, 104 std::span<const uint8_t> dcid, 105 const Address &remote_addr, 106 const Address &local_addr); 107 // Send Initial CONNECTION_CLOSE. |ini_dcid| is the destination 108 // Connection ID which appeared in Client Initial packet. 109 // |ini_scid| is the source Connection ID which appeared in Client 110 // Initial packet. 111 int send_connection_close(const UpstreamAddr *faddr, uint32_t version, 112 const ngtcp2_cid &ini_dcid, 113 const ngtcp2_cid &ini_scid, 114 const Address &remote_addr, 115 const Address &local_addr, uint64_t error_code, 116 size_t max_pktlen); 117 ClientHandler * 118 handle_new_connection(const UpstreamAddr *faddr, const Address &remote_addr, 119 const Address &local_addr, const ngtcp2_pkt_hd &hd, 120 const ngtcp2_cid *odcid, std::span<const uint8_t> token, 121 ngtcp2_token_type token_type); 122 void add_connection_id(const ngtcp2_cid &cid, ClientHandler *handler); 123 void remove_connection_id(const ngtcp2_cid &cid); 124 125 void add_close_wait(CloseWait *cw); 126 void remove_close_wait(const CloseWait *cw); 127 128 void on_stateless_reset_bucket_regen(); 129 130 private: 131 Worker *worker_; 132 std::unordered_map<ngtcp2_cid, ClientHandler *> connections_; 133 std::unordered_map<ngtcp2_cid, CloseWait *> close_waits_; 134 ev_timer stateless_reset_bucket_regen_timer_; 135 size_t stateless_reset_bucket_; 136 }; 137 138 } // namespace shrpx 139 140 #endif // SHRPX_QUIC_CONNECTION_HANDLER_H 141