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_HTTP3_UPSTREAM_H 26 #define SHRPX_HTTP3_UPSTREAM_H 27 28 #include "shrpx.h" 29 30 #include <ngtcp2/ngtcp2.h> 31 #include <nghttp3/nghttp3.h> 32 33 #include "shrpx_upstream.h" 34 #include "shrpx_downstream_queue.h" 35 #include "quic.h" 36 #include "network.h" 37 38 using namespace nghttp2; 39 40 namespace shrpx { 41 42 struct UpstreamAddr; 43 44 class Http3Upstream : public Upstream { 45 public: 46 Http3Upstream(ClientHandler *handler); 47 virtual ~Http3Upstream(); 48 49 virtual int on_read(); 50 virtual int on_write(); 51 virtual int on_timeout(Downstream *downstream); 52 virtual int on_downstream_abort_request(Downstream *downstream, 53 unsigned int status_code); 54 virtual int 55 on_downstream_abort_request_with_https_redirect(Downstream *downstream); 56 virtual int downstream_read(DownstreamConnection *dconn); 57 virtual int downstream_write(DownstreamConnection *dconn); 58 virtual int downstream_eof(DownstreamConnection *dconn); 59 virtual int downstream_error(DownstreamConnection *dconn, int events); 60 virtual ClientHandler *get_client_handler() const; 61 62 virtual int on_downstream_header_complete(Downstream *downstream); 63 virtual int on_downstream_body(Downstream *downstream, const uint8_t *data, 64 size_t len, bool flush); 65 virtual int on_downstream_body_complete(Downstream *downstream); 66 67 virtual void on_handler_delete(); 68 virtual int on_downstream_reset(Downstream *downstream, bool no_retry); 69 70 virtual void pause_read(IOCtrlReason reason); 71 virtual int resume_read(IOCtrlReason reason, Downstream *downstream, 72 size_t consumed); 73 virtual int send_reply(Downstream *downstream, const uint8_t *body, 74 size_t bodylen); 75 76 virtual int initiate_push(Downstream *downstream, const StringRef &uri); 77 78 virtual int response_riovec(struct iovec *iov, int iovcnt) const; 79 virtual void response_drain(size_t n); 80 virtual bool response_empty() const; 81 82 virtual Downstream *on_downstream_push_promise(Downstream *downstream, 83 int32_t promised_stream_id); 84 virtual int 85 on_downstream_push_promise_complete(Downstream *downstream, 86 Downstream *promised_downstream); 87 virtual bool push_enabled() const; 88 virtual void cancel_premature_downstream(Downstream *promised_downstream); 89 90 int init(const UpstreamAddr *faddr, const Address &remote_addr, 91 const Address &local_addr, const ngtcp2_pkt_hd &initial_hd, 92 const ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen, 93 ngtcp2_token_type token_type); 94 95 int on_read(const UpstreamAddr *faddr, const Address &remote_addr, 96 const Address &local_addr, const ngtcp2_pkt_info &pi, 97 const uint8_t *data, size_t datalen); 98 99 int write_streams(); 100 101 int handle_error(); 102 103 int handle_expiry(); 104 void reset_timer(); 105 106 int setup_httpconn(); 107 void add_pending_downstream(std::unique_ptr<Downstream> downstream); 108 int recv_stream_data(uint32_t flags, int64_t stream_id, const uint8_t *data, 109 size_t datalen); 110 int acked_stream_data_offset(int64_t stream_id, uint64_t datalen); 111 int extend_max_stream_data(int64_t stream_id); 112 void extend_max_remote_streams_bidi(uint64_t max_streams); 113 int error_reply(Downstream *downstream, unsigned int status_code); 114 void http_begin_request_headers(int64_t stream_id); 115 int http_recv_request_header(Downstream *downstream, int32_t token, 116 nghttp3_rcbuf *name, nghttp3_rcbuf *value, 117 uint8_t flags, bool trailer); 118 int http_end_request_headers(Downstream *downstream, int fin); 119 int http_end_stream(Downstream *downstream); 120 void start_downstream(Downstream *downstream); 121 void initiate_downstream(Downstream *downstream); 122 int shutdown_stream(Downstream *downstream, uint64_t app_error_code); 123 int shutdown_stream_read(int64_t stream_id, uint64_t app_error_code); 124 int http_stream_close(Downstream *downstream, uint64_t app_error_code); 125 void consume(int64_t stream_id, size_t nconsumed); 126 void remove_downstream(Downstream *downstream); 127 int stream_close(int64_t stream_id, uint64_t app_error_code); 128 int stream_reset(int64_t stream_id); 129 void log_response_headers(Downstream *downstream, 130 const std::vector<nghttp3_nv> &nva) const; 131 int http_acked_stream_data(Downstream *downstream, uint64_t datalen); 132 int http_shutdown_stream_read(int64_t stream_id); 133 int http_reset_stream(int64_t stream_id, uint64_t app_error_code); 134 int http_stop_sending(int64_t stream_id, uint64_t app_error_code); 135 int http_recv_data(Downstream *downstream, const uint8_t *data, 136 size_t datalen); 137 int handshake_completed(); 138 int check_shutdown(); 139 int start_graceful_shutdown(); 140 int submit_goaway(); 141 int send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, 142 size_t remote_salen, const sockaddr *local_sa, 143 size_t local_salen, const ngtcp2_pkt_info &pi, 144 const uint8_t *data, size_t datalen, size_t gso_size); 145 146 void qlog_write(const void *data, size_t datalen, bool fin); 147 int open_qlog_file(const StringRef &dir, const ngtcp2_cid &scid) const; 148 149 void on_send_blocked(const UpstreamAddr *faddr, 150 const ngtcp2_addr &remote_addr, 151 const ngtcp2_addr &local_addr, const ngtcp2_pkt_info &pi, 152 const uint8_t *data, size_t datalen, size_t gso_size); 153 int send_blocked_packet(); 154 void signal_write_upstream_addr(const UpstreamAddr *faddr); 155 156 ngtcp2_conn *get_conn() const; 157 158 int send_new_token(const ngtcp2_addr *remote_addr); 159 160 private: 161 ClientHandler *handler_; 162 ev_timer timer_; 163 ev_timer shutdown_timer_; 164 ev_prepare prep_; 165 int qlog_fd_; 166 ngtcp2_cid hashed_scid_; 167 ngtcp2_conn *conn_; 168 ngtcp2_ccerr last_error_; 169 nghttp3_conn *httpconn_; 170 DownstreamQueue downstream_queue_; 171 bool retry_close_; 172 std::vector<uint8_t> conn_close_; 173 174 struct { 175 bool send_blocked; 176 size_t num_blocked; 177 size_t num_blocked_sent; 178 // blocked field is effective only when send_blocked is true. 179 struct { 180 const UpstreamAddr *faddr; 181 Address local_addr; 182 Address remote_addr; 183 ngtcp2_pkt_info pi; 184 const uint8_t *data; 185 size_t datalen; 186 size_t gso_size; 187 } blocked[2]; 188 std::unique_ptr<uint8_t[]> data; 189 } tx_; 190 }; 191 192 } // namespace shrpx 193 194 #endif // SHRPX_HTTP3_UPSTREAM_H 195