• 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 <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 SharedDownstreamAddr;
56 struct DownstreamAddr;
57 #ifdef ENABLE_HTTP3
58 class Http3Upstream;
59 #endif // ENABLE_HTTP3
60 
61 class ClientHandler {
62 public:
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 
200 private:
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