• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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