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 const uint8_t *data, size_t datalen); 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 const uint8_t *data, size_t datalen); 87 // Send Retry packet. |ini_dcid| is the destination Connection ID 88 // which appeared in Client Initial packet and its length is 89 // |dcidlen|. |ini_scid| is the source Connection ID which appeared 90 // in Client Initial packet and its length is |scidlen|. 91 int send_retry(const UpstreamAddr *faddr, uint32_t version, 92 const uint8_t *ini_dcid, size_t ini_dcidlen, 93 const uint8_t *ini_scid, size_t ini_scidlen, 94 const Address &remote_addr, const Address &local_addr, 95 size_t max_pktlen); 96 // Send Version Negotiation packet. |ini_dcid| is the destination 97 // Connection ID which appeared in Client Initial packet and its 98 // length is |dcidlen|. |ini_scid| is the source Connection ID 99 // which appeared in Client Initial packet and its length is 100 // |scidlen|. 101 int send_version_negotiation(const UpstreamAddr *faddr, uint32_t version, 102 const uint8_t *ini_dcid, size_t ini_dcidlen, 103 const uint8_t *ini_scid, size_t ini_scidlen, 104 const Address &remote_addr, 105 const Address &local_addr); 106 int send_stateless_reset(const UpstreamAddr *faddr, const uint8_t *dcid, 107 size_t dcidlen, const Address &remote_addr, 108 const Address &local_addr); 109 // Send Initial CONNECTION_CLOSE. |ini_dcid| is the destination 110 // Connection ID which appeared in Client Initial packet. 111 // |ini_scid| is the source Connection ID which appeared in Client 112 // Initial packet. 113 int send_connection_close(const UpstreamAddr *faddr, uint32_t version, 114 const ngtcp2_cid &ini_dcid, 115 const ngtcp2_cid &ini_scid, 116 const Address &remote_addr, 117 const Address &local_addr, uint64_t error_code, 118 size_t max_pktlen); 119 ClientHandler *handle_new_connection(const UpstreamAddr *faddr, 120 const Address &remote_addr, 121 const Address &local_addr, 122 const ngtcp2_pkt_hd &hd, 123 const ngtcp2_cid *odcid, 124 const uint8_t *token, size_t tokenlen); 125 void add_connection_id(const ngtcp2_cid &cid, ClientHandler *handler); 126 void remove_connection_id(const ngtcp2_cid &cid); 127 128 void add_close_wait(CloseWait *cw); 129 void remove_close_wait(const CloseWait *cw); 130 131 void on_stateless_reset_bucket_regen(); 132 133 private: 134 Worker *worker_; 135 std::unordered_map<ngtcp2_cid, ClientHandler *> connections_; 136 std::unordered_map<ngtcp2_cid, CloseWait *> close_waits_; 137 ev_timer stateless_reset_bucket_regen_timer_; 138 size_t stateless_reset_bucket_; 139 }; 140 141 } // namespace shrpx 142 143 #endif // SHRPX_QUIC_CONNECTION_HANDLER_H 144