12c593315Sopenharmony_ci/* 22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library 32c593315Sopenharmony_ci * 42c593315Sopenharmony_ci * Copyright (c) 2021 Tatsuhiro Tsujikawa 52c593315Sopenharmony_ci * 62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the 82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 122c593315Sopenharmony_ci * the following conditions: 132c593315Sopenharmony_ci * 142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be 152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software. 162c593315Sopenharmony_ci * 172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 242c593315Sopenharmony_ci */ 252c593315Sopenharmony_ci#ifndef SHRPX_HTTP3_UPSTREAM_H 262c593315Sopenharmony_ci#define SHRPX_HTTP3_UPSTREAM_H 272c593315Sopenharmony_ci 282c593315Sopenharmony_ci#include "shrpx.h" 292c593315Sopenharmony_ci 302c593315Sopenharmony_ci#include <ngtcp2/ngtcp2.h> 312c593315Sopenharmony_ci#include <nghttp3/nghttp3.h> 322c593315Sopenharmony_ci 332c593315Sopenharmony_ci#include "shrpx_upstream.h" 342c593315Sopenharmony_ci#include "shrpx_downstream_queue.h" 352c593315Sopenharmony_ci#include "quic.h" 362c593315Sopenharmony_ci#include "network.h" 372c593315Sopenharmony_ci 382c593315Sopenharmony_ciusing namespace nghttp2; 392c593315Sopenharmony_ci 402c593315Sopenharmony_cinamespace shrpx { 412c593315Sopenharmony_ci 422c593315Sopenharmony_cistruct UpstreamAddr; 432c593315Sopenharmony_ci 442c593315Sopenharmony_ciclass Http3Upstream : public Upstream { 452c593315Sopenharmony_cipublic: 462c593315Sopenharmony_ci Http3Upstream(ClientHandler *handler); 472c593315Sopenharmony_ci virtual ~Http3Upstream(); 482c593315Sopenharmony_ci 492c593315Sopenharmony_ci virtual int on_read(); 502c593315Sopenharmony_ci virtual int on_write(); 512c593315Sopenharmony_ci virtual int on_timeout(Downstream *downstream); 522c593315Sopenharmony_ci virtual int on_downstream_abort_request(Downstream *downstream, 532c593315Sopenharmony_ci unsigned int status_code); 542c593315Sopenharmony_ci virtual int 552c593315Sopenharmony_ci on_downstream_abort_request_with_https_redirect(Downstream *downstream); 562c593315Sopenharmony_ci virtual int downstream_read(DownstreamConnection *dconn); 572c593315Sopenharmony_ci virtual int downstream_write(DownstreamConnection *dconn); 582c593315Sopenharmony_ci virtual int downstream_eof(DownstreamConnection *dconn); 592c593315Sopenharmony_ci virtual int downstream_error(DownstreamConnection *dconn, int events); 602c593315Sopenharmony_ci virtual ClientHandler *get_client_handler() const; 612c593315Sopenharmony_ci 622c593315Sopenharmony_ci virtual int on_downstream_header_complete(Downstream *downstream); 632c593315Sopenharmony_ci virtual int on_downstream_body(Downstream *downstream, const uint8_t *data, 642c593315Sopenharmony_ci size_t len, bool flush); 652c593315Sopenharmony_ci virtual int on_downstream_body_complete(Downstream *downstream); 662c593315Sopenharmony_ci 672c593315Sopenharmony_ci virtual void on_handler_delete(); 682c593315Sopenharmony_ci virtual int on_downstream_reset(Downstream *downstream, bool no_retry); 692c593315Sopenharmony_ci 702c593315Sopenharmony_ci virtual void pause_read(IOCtrlReason reason); 712c593315Sopenharmony_ci virtual int resume_read(IOCtrlReason reason, Downstream *downstream, 722c593315Sopenharmony_ci size_t consumed); 732c593315Sopenharmony_ci virtual int send_reply(Downstream *downstream, const uint8_t *body, 742c593315Sopenharmony_ci size_t bodylen); 752c593315Sopenharmony_ci 762c593315Sopenharmony_ci virtual int initiate_push(Downstream *downstream, const StringRef &uri); 772c593315Sopenharmony_ci 782c593315Sopenharmony_ci virtual int response_riovec(struct iovec *iov, int iovcnt) const; 792c593315Sopenharmony_ci virtual void response_drain(size_t n); 802c593315Sopenharmony_ci virtual bool response_empty() const; 812c593315Sopenharmony_ci 822c593315Sopenharmony_ci virtual Downstream *on_downstream_push_promise(Downstream *downstream, 832c593315Sopenharmony_ci int32_t promised_stream_id); 842c593315Sopenharmony_ci virtual int 852c593315Sopenharmony_ci on_downstream_push_promise_complete(Downstream *downstream, 862c593315Sopenharmony_ci Downstream *promised_downstream); 872c593315Sopenharmony_ci virtual bool push_enabled() const; 882c593315Sopenharmony_ci virtual void cancel_premature_downstream(Downstream *promised_downstream); 892c593315Sopenharmony_ci 902c593315Sopenharmony_ci int init(const UpstreamAddr *faddr, const Address &remote_addr, 912c593315Sopenharmony_ci const Address &local_addr, const ngtcp2_pkt_hd &initial_hd, 922c593315Sopenharmony_ci const ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen, 932c593315Sopenharmony_ci ngtcp2_token_type token_type); 942c593315Sopenharmony_ci 952c593315Sopenharmony_ci int on_read(const UpstreamAddr *faddr, const Address &remote_addr, 962c593315Sopenharmony_ci const Address &local_addr, const ngtcp2_pkt_info &pi, 972c593315Sopenharmony_ci const uint8_t *data, size_t datalen); 982c593315Sopenharmony_ci 992c593315Sopenharmony_ci int write_streams(); 1002c593315Sopenharmony_ci 1012c593315Sopenharmony_ci int handle_error(); 1022c593315Sopenharmony_ci 1032c593315Sopenharmony_ci int handle_expiry(); 1042c593315Sopenharmony_ci void reset_timer(); 1052c593315Sopenharmony_ci 1062c593315Sopenharmony_ci int setup_httpconn(); 1072c593315Sopenharmony_ci void add_pending_downstream(std::unique_ptr<Downstream> downstream); 1082c593315Sopenharmony_ci int recv_stream_data(uint32_t flags, int64_t stream_id, const uint8_t *data, 1092c593315Sopenharmony_ci size_t datalen); 1102c593315Sopenharmony_ci int acked_stream_data_offset(int64_t stream_id, uint64_t datalen); 1112c593315Sopenharmony_ci int extend_max_stream_data(int64_t stream_id); 1122c593315Sopenharmony_ci void extend_max_remote_streams_bidi(uint64_t max_streams); 1132c593315Sopenharmony_ci int error_reply(Downstream *downstream, unsigned int status_code); 1142c593315Sopenharmony_ci void http_begin_request_headers(int64_t stream_id); 1152c593315Sopenharmony_ci int http_recv_request_header(Downstream *downstream, int32_t token, 1162c593315Sopenharmony_ci nghttp3_rcbuf *name, nghttp3_rcbuf *value, 1172c593315Sopenharmony_ci uint8_t flags, bool trailer); 1182c593315Sopenharmony_ci int http_end_request_headers(Downstream *downstream, int fin); 1192c593315Sopenharmony_ci int http_end_stream(Downstream *downstream); 1202c593315Sopenharmony_ci void start_downstream(Downstream *downstream); 1212c593315Sopenharmony_ci void initiate_downstream(Downstream *downstream); 1222c593315Sopenharmony_ci int shutdown_stream(Downstream *downstream, uint64_t app_error_code); 1232c593315Sopenharmony_ci int shutdown_stream_read(int64_t stream_id, uint64_t app_error_code); 1242c593315Sopenharmony_ci int http_stream_close(Downstream *downstream, uint64_t app_error_code); 1252c593315Sopenharmony_ci void consume(int64_t stream_id, size_t nconsumed); 1262c593315Sopenharmony_ci void remove_downstream(Downstream *downstream); 1272c593315Sopenharmony_ci int stream_close(int64_t stream_id, uint64_t app_error_code); 1282c593315Sopenharmony_ci int stream_reset(int64_t stream_id); 1292c593315Sopenharmony_ci void log_response_headers(Downstream *downstream, 1302c593315Sopenharmony_ci const std::vector<nghttp3_nv> &nva) const; 1312c593315Sopenharmony_ci int http_acked_stream_data(Downstream *downstream, uint64_t datalen); 1322c593315Sopenharmony_ci int http_shutdown_stream_read(int64_t stream_id); 1332c593315Sopenharmony_ci int http_reset_stream(int64_t stream_id, uint64_t app_error_code); 1342c593315Sopenharmony_ci int http_stop_sending(int64_t stream_id, uint64_t app_error_code); 1352c593315Sopenharmony_ci int http_recv_data(Downstream *downstream, const uint8_t *data, 1362c593315Sopenharmony_ci size_t datalen); 1372c593315Sopenharmony_ci int handshake_completed(); 1382c593315Sopenharmony_ci int check_shutdown(); 1392c593315Sopenharmony_ci int start_graceful_shutdown(); 1402c593315Sopenharmony_ci int submit_goaway(); 1412c593315Sopenharmony_ci int send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, 1422c593315Sopenharmony_ci size_t remote_salen, const sockaddr *local_sa, 1432c593315Sopenharmony_ci size_t local_salen, const ngtcp2_pkt_info &pi, 1442c593315Sopenharmony_ci const uint8_t *data, size_t datalen, size_t gso_size); 1452c593315Sopenharmony_ci 1462c593315Sopenharmony_ci void qlog_write(const void *data, size_t datalen, bool fin); 1472c593315Sopenharmony_ci int open_qlog_file(const StringRef &dir, const ngtcp2_cid &scid) const; 1482c593315Sopenharmony_ci 1492c593315Sopenharmony_ci void on_send_blocked(const UpstreamAddr *faddr, 1502c593315Sopenharmony_ci const ngtcp2_addr &remote_addr, 1512c593315Sopenharmony_ci const ngtcp2_addr &local_addr, const ngtcp2_pkt_info &pi, 1522c593315Sopenharmony_ci const uint8_t *data, size_t datalen, size_t gso_size); 1532c593315Sopenharmony_ci int send_blocked_packet(); 1542c593315Sopenharmony_ci void signal_write_upstream_addr(const UpstreamAddr *faddr); 1552c593315Sopenharmony_ci 1562c593315Sopenharmony_ci ngtcp2_conn *get_conn() const; 1572c593315Sopenharmony_ci 1582c593315Sopenharmony_ci int send_new_token(const ngtcp2_addr *remote_addr); 1592c593315Sopenharmony_ci 1602c593315Sopenharmony_ciprivate: 1612c593315Sopenharmony_ci ClientHandler *handler_; 1622c593315Sopenharmony_ci ev_timer timer_; 1632c593315Sopenharmony_ci ev_timer shutdown_timer_; 1642c593315Sopenharmony_ci ev_prepare prep_; 1652c593315Sopenharmony_ci int qlog_fd_; 1662c593315Sopenharmony_ci ngtcp2_cid hashed_scid_; 1672c593315Sopenharmony_ci ngtcp2_conn *conn_; 1682c593315Sopenharmony_ci ngtcp2_ccerr last_error_; 1692c593315Sopenharmony_ci nghttp3_conn *httpconn_; 1702c593315Sopenharmony_ci DownstreamQueue downstream_queue_; 1712c593315Sopenharmony_ci bool retry_close_; 1722c593315Sopenharmony_ci std::vector<uint8_t> conn_close_; 1732c593315Sopenharmony_ci 1742c593315Sopenharmony_ci struct { 1752c593315Sopenharmony_ci bool send_blocked; 1762c593315Sopenharmony_ci size_t num_blocked; 1772c593315Sopenharmony_ci size_t num_blocked_sent; 1782c593315Sopenharmony_ci // blocked field is effective only when send_blocked is true. 1792c593315Sopenharmony_ci struct { 1802c593315Sopenharmony_ci const UpstreamAddr *faddr; 1812c593315Sopenharmony_ci Address local_addr; 1822c593315Sopenharmony_ci Address remote_addr; 1832c593315Sopenharmony_ci ngtcp2_pkt_info pi; 1842c593315Sopenharmony_ci const uint8_t *data; 1852c593315Sopenharmony_ci size_t datalen; 1862c593315Sopenharmony_ci size_t gso_size; 1872c593315Sopenharmony_ci } blocked[2]; 1882c593315Sopenharmony_ci std::unique_ptr<uint8_t[]> data; 1892c593315Sopenharmony_ci } tx_; 1902c593315Sopenharmony_ci}; 1912c593315Sopenharmony_ci 1922c593315Sopenharmony_ci} // namespace shrpx 1932c593315Sopenharmony_ci 1942c593315Sopenharmony_ci#endif // SHRPX_HTTP3_UPSTREAM_H 195