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