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
42using namespace nghttp2;
43
44namespace shrpx {
45
46struct UpstreamAddr;
47class ClientHandler;
48class Worker;
49
50// CloseWait handles packets received in close-wait (draining or
51// closing period).
52struct 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
80class QUICConnectionHandler {
81public:
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 *
120  handle_new_connection(const UpstreamAddr *faddr, const Address &remote_addr,
121                        const Address &local_addr, const ngtcp2_pkt_hd &hd,
122                        const ngtcp2_cid *odcid, const uint8_t *token,
123                        size_t tokenlen, ngtcp2_token_type token_type);
124  void add_connection_id(const ngtcp2_cid &cid, ClientHandler *handler);
125  void remove_connection_id(const ngtcp2_cid &cid);
126
127  void add_close_wait(CloseWait *cw);
128  void remove_close_wait(const CloseWait *cw);
129
130  void on_stateless_reset_bucket_regen();
131
132private:
133  Worker *worker_;
134  std::unordered_map<ngtcp2_cid, ClientHandler *> connections_;
135  std::unordered_map<ngtcp2_cid, CloseWait *> close_waits_;
136  ev_timer stateless_reset_bucket_regen_timer_;
137  size_t stateless_reset_bucket_;
138};
139
140} // namespace shrpx
141
142#endif // SHRPX_QUIC_CONNECTION_HANDLER_H
143