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