1/*
2 * nghttp2 - HTTP/2 C Library
3 *
4 * Copyright (c) 2012 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_CLIENT_HANDLER_H
26#define SHRPX_CLIENT_HANDLER_H
27
28#include "shrpx.h"
29
30#include <memory>
31
32#include <ev.h>
33
34#include <openssl/ssl.h>
35
36#include "shrpx_rate_limit.h"
37#include "shrpx_connection.h"
38#include "buffer.h"
39#include "memchunk.h"
40#include "allocator.h"
41
42using namespace nghttp2;
43
44namespace shrpx {
45
46class Upstream;
47class DownstreamConnection;
48class HttpsUpstream;
49class ConnectBlocker;
50class DownstreamConnectionPool;
51class Worker;
52class Downstream;
53struct WorkerStat;
54struct DownstreamAddrGroup;
55struct SharedDownstreamAddr;
56struct DownstreamAddr;
57#ifdef ENABLE_HTTP3
58class Http3Upstream;
59#endif // ENABLE_HTTP3
60
61class ClientHandler {
62public:
63  ClientHandler(Worker *worker, int fd, SSL *ssl, const StringRef &ipaddr,
64                const StringRef &port, int family, const UpstreamAddr *faddr);
65  ~ClientHandler();
66
67  int noop();
68  // Performs clear text I/O
69  int read_clear();
70  int write_clear();
71  // Specialized for PROXY-protocol use; peek data from socket.
72  int proxy_protocol_peek_clear();
73  // Performs TLS handshake
74  int tls_handshake();
75  // Performs TLS I/O
76  int read_tls();
77  int write_tls();
78
79  int upstream_noop();
80  int upstream_read();
81  int upstream_http2_connhd_read();
82  int upstream_http1_connhd_read();
83  int upstream_write();
84
85  int proxy_protocol_read();
86  int proxy_protocol_v2_read();
87  int on_proxy_protocol_finish();
88
89  // Performs I/O operation.  Internally calls on_read()/on_write().
90  int do_read();
91  int do_write();
92
93  // Processes buffers.  No underlying I/O operation will be done.
94  int on_read();
95  int on_write();
96
97  struct ev_loop *get_loop() const;
98  void reset_upstream_read_timeout(ev_tstamp t);
99  void reset_upstream_write_timeout(ev_tstamp t);
100
101  int validate_next_proto();
102  const StringRef &get_ipaddr() const;
103  bool get_should_close_after_write() const;
104  void set_should_close_after_write(bool f);
105  Upstream *get_upstream();
106
107  void pool_downstream_connection(std::unique_ptr<DownstreamConnection> dconn);
108  void remove_downstream_connection(DownstreamConnection *dconn);
109  DownstreamAddr *get_downstream_addr(int &err, DownstreamAddrGroup *group,
110                                      Downstream *downstream);
111  // Returns DownstreamConnection object based on request path.  This
112  // function returns non-null DownstreamConnection, and assigns 0 to
113  // |err| if it succeeds, or returns nullptr, and assigns negative
114  // error code to |err|.
115  std::unique_ptr<DownstreamConnection>
116  get_downstream_connection(int &err, Downstream *downstream);
117  MemchunkPool *get_mcpool();
118  SSL *get_ssl() const;
119  // Call this function when HTTP/2 connection header is received at
120  // the start of the connection.
121  void direct_http2_upgrade();
122  // Performs HTTP/2 Upgrade from the connection managed by
123  // |http|. If this function fails, the connection must be
124  // terminated. This function returns 0 if it succeeds, or -1.
125  int perform_http2_upgrade(HttpsUpstream *http);
126  bool get_http2_upgrade_allowed() const;
127  // Returns upstream scheme, either "http" or "https"
128  StringRef get_upstream_scheme() const;
129  void start_immediate_shutdown();
130
131  // Writes upstream accesslog using |downstream|.  The |downstream|
132  // must not be nullptr.
133  void write_accesslog(Downstream *downstream);
134
135  Worker *get_worker() const;
136
137  // Initializes forwarded_for_.
138  void init_forwarded_for(int family, const StringRef &ipaddr);
139
140  using ReadBuf = DefaultMemchunkBuffer;
141
142  ReadBuf *get_rb();
143
144  RateLimit *get_rlimit();
145  RateLimit *get_wlimit();
146
147  void signal_write();
148  ev_io *get_wev();
149
150  void setup_upstream_io_callback();
151
152#ifdef ENABLE_HTTP3
153  void setup_http3_upstream(std::unique_ptr<Http3Upstream> &&upstream);
154  int read_quic(const UpstreamAddr *faddr, const Address &remote_addr,
155                const Address &local_addr, const ngtcp2_pkt_info &pi,
156                const uint8_t *data, size_t datalen);
157  int write_quic();
158#endif // ENABLE_HTTP3
159
160  // Returns string suitable for use in "by" parameter of Forwarded
161  // header field.
162  StringRef get_forwarded_by() const;
163  // Returns string suitable for use in "for" parameter of Forwarded
164  // header field.
165  StringRef get_forwarded_for() const;
166
167  Http2Session *
168  get_http2_session(const std::shared_ptr<DownstreamAddrGroup> &group,
169                    DownstreamAddr *addr);
170
171  // Returns an affinity cookie value for |downstream|.  |cookie_name|
172  // is used to inspect cookie header field in request header fields.
173  uint32_t get_affinity_cookie(Downstream *downstream,
174                               const StringRef &cookie_name);
175
176  DownstreamAddr *get_downstream_addr_strict_affinity(
177      int &err, const std::shared_ptr<SharedDownstreamAddr> &shared_addr,
178      Downstream *downstream);
179
180  const UpstreamAddr *get_upstream_addr() const;
181
182  void repeat_read_timer();
183  void stop_read_timer();
184
185  Connection *get_connection();
186
187  // Stores |sni| which is TLS SNI extension value client sent in this
188  // connection.
189  void set_tls_sni(const StringRef &sni);
190  // Returns TLS SNI extension value client sent in this connection.
191  StringRef get_tls_sni() const;
192
193  // Returns ALPN negotiated in this connection.
194  StringRef get_alpn() const;
195
196  BlockAllocator &get_block_allocator();
197
198  void set_alpn_from_conn();
199
200private:
201  // Allocator to allocate memory for connection-wide objects.  Make
202  // sure that the allocations must be bounded, and not proportional
203  // to the number of requests.
204  BlockAllocator balloc_;
205  DefaultMemchunkBuffer rb_;
206  Connection conn_;
207  ev_timer reneg_shutdown_timer_;
208  std::unique_ptr<Upstream> upstream_;
209  // IP address of client.  If UNIX domain socket is used, this is
210  // "localhost".
211  StringRef ipaddr_;
212  StringRef port_;
213  // The ALPN identifier negotiated for this connection.
214  StringRef alpn_;
215  // The client address used in "for" parameter of Forwarded header
216  // field.
217  StringRef forwarded_for_;
218  // lowercased TLS SNI which client sent.
219  StringRef sni_;
220  std::function<int(ClientHandler &)> read_, write_;
221  std::function<int(ClientHandler &)> on_read_, on_write_;
222  // Address of frontend listening socket
223  const UpstreamAddr *faddr_;
224  Worker *worker_;
225  // The number of bytes of HTTP/2 client connection header to read
226  size_t left_connhd_len_;
227  // hash for session affinity using client IP
228  uint32_t affinity_hash_;
229  bool should_close_after_write_;
230  // true if affinity_hash_ is computed
231  bool affinity_hash_computed_;
232};
233
234} // namespace shrpx
235
236#endif // SHRPX_CLIENT_HANDLER_H
237