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 94 int on_read(const UpstreamAddr *faddr, const Address &remote_addr, 95 const Address &local_addr, const ngtcp2_pkt_info &pi, 96 const uint8_t *data, size_t datalen); 97 98 int write_streams(); 99 100 int handle_error(); 101 102 int handle_expiry(); 103 void reset_timer(); 104 105 int setup_httpconn(); 106 void add_pending_downstream(std::unique_ptr<Downstream> downstream); 107 int recv_stream_data(uint32_t flags, int64_t stream_id, const uint8_t *data, 108 size_t datalen); 109 int acked_stream_data_offset(int64_t stream_id, uint64_t datalen); 110 int extend_max_stream_data(int64_t stream_id); 111 void extend_max_remote_streams_bidi(uint64_t max_streams); 112 int error_reply(Downstream *downstream, unsigned int status_code); 113 void http_begin_request_headers(int64_t stream_id); 114 int http_recv_request_header(Downstream *downstream, int32_t token, 115 nghttp3_rcbuf *name, nghttp3_rcbuf *value, 116 uint8_t flags, bool trailer); 117 int http_end_request_headers(Downstream *downstream, int fin); 118 int http_end_stream(Downstream *downstream); 119 void start_downstream(Downstream *downstream); 120 void initiate_downstream(Downstream *downstream); 121 int shutdown_stream(Downstream *downstream, uint64_t app_error_code); 122 int shutdown_stream_read(int64_t stream_id, uint64_t app_error_code); 123 int http_stream_close(Downstream *downstream, uint64_t app_error_code); 124 void consume(int64_t stream_id, size_t nconsumed); 125 void remove_downstream(Downstream *downstream); 126 int stream_close(int64_t stream_id, uint64_t app_error_code); 127 void log_response_headers(Downstream *downstream, 128 const std::vector<nghttp3_nv> &nva) const; 129 int http_acked_stream_data(Downstream *downstream, uint64_t datalen); 130 int http_shutdown_stream_read(int64_t stream_id); 131 int http_reset_stream(int64_t stream_id, uint64_t app_error_code); 132 int http_stop_sending(int64_t stream_id, uint64_t app_error_code); 133 int http_recv_data(Downstream *downstream, const uint8_t *data, 134 size_t datalen); 135 int handshake_completed(); 136 int check_shutdown(); 137 int start_graceful_shutdown(); 138 int submit_goaway(); 139 int send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, 140 size_t remote_salen, const sockaddr *local_sa, 141 size_t local_salen, const ngtcp2_pkt_info &pi, 142 const uint8_t *data, size_t datalen, size_t gso_size); 143 144 void qlog_write(const void *data, size_t datalen, bool fin); 145 int open_qlog_file(const StringRef &dir, const ngtcp2_cid &scid) const; 146 147 void on_send_blocked(const UpstreamAddr *faddr, 148 const ngtcp2_addr &remote_addr, 149 const ngtcp2_addr &local_addr, const ngtcp2_pkt_info &pi, 150 const uint8_t *data, size_t datalen, size_t gso_size); 151 int send_blocked_packet(); 152 void signal_write_upstream_addr(const UpstreamAddr *faddr); 153 154 ngtcp2_conn *get_conn() const; 155 156 int send_new_token(const ngtcp2_addr *remote_addr); 157 158 private: 159 ClientHandler *handler_; 160 ev_timer timer_; 161 ev_timer shutdown_timer_; 162 ev_prepare prep_; 163 int qlog_fd_; 164 ngtcp2_cid hashed_scid_; 165 ngtcp2_conn *conn_; 166 ngtcp2_ccerr last_error_; 167 nghttp3_conn *httpconn_; 168 DownstreamQueue downstream_queue_; 169 bool retry_close_; 170 std::vector<uint8_t> conn_close_; 171 172 struct { 173 bool send_blocked; 174 size_t num_blocked; 175 size_t num_blocked_sent; 176 // blocked field is effective only when send_blocked is true. 177 struct { 178 const UpstreamAddr *faddr; 179 Address local_addr; 180 Address remote_addr; 181 ngtcp2_pkt_info pi; 182 const uint8_t *data; 183 size_t datalen; 184 size_t gso_size; 185 } blocked[2]; 186 std::unique_ptr<uint8_t[]> data; 187 } tx_; 188 }; 189 190 } // namespace shrpx 191 192 #endif // SHRPX_HTTP3_UPSTREAM_H 193