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