1 /* 2 * ngtcp2 3 * 4 * Copyright (c) 2017 ngtcp2 contributors 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 H09CLIENT_H 26 #define H09CLIENT_H 27 28 #ifdef HAVE_CONFIG_H 29 # include <config.h> 30 #endif // HAVE_CONFIG_H 31 32 #include <vector> 33 #include <deque> 34 #include <map> 35 #include <string_view> 36 #include <memory> 37 #include <set> 38 39 #include <ngtcp2/ngtcp2.h> 40 #include <ngtcp2/ngtcp2_crypto.h> 41 42 #include <nghttp3/nghttp3.h> 43 44 #include <ev.h> 45 46 #include "client_base.h" 47 #include "tls_client_context.h" 48 #include "tls_client_session.h" 49 #include "network.h" 50 #include "shared.h" 51 52 using namespace ngtcp2; 53 54 struct Stream { 55 Stream(const Request &req, int64_t stream_id); 56 ~Stream(); 57 58 int open_file(const std::string_view &path); 59 60 Request req; 61 int64_t stream_id; 62 int fd; 63 std::string rawreqbuf; 64 nghttp3_buf reqbuf; 65 }; 66 67 struct StreamIDLess { operatorStreamIDLess68 constexpr bool operator()(const Stream *lhs, const Stream *rhs) const { 69 return lhs->stream_id < rhs->stream_id; 70 } 71 }; 72 73 class Client; 74 75 struct Endpoint { 76 Address addr; 77 ev_io rev; 78 Client *client; 79 int fd; 80 }; 81 82 class Client : public ClientBase { 83 public: 84 Client(struct ev_loop *loop); 85 ~Client(); 86 87 int init(int fd, const Address &local_addr, const Address &remote_addr, 88 const char *addr, const char *port, uint32_t version, 89 const TLSClientContext &tls_ctx); 90 void disconnect(); 91 92 void start_wev(); 93 94 int on_read(const Endpoint &ep); 95 int on_write(); 96 int write_streams(); 97 int feed_data(const Endpoint &ep, const sockaddr *sa, socklen_t salen, 98 const ngtcp2_pkt_info *pi, uint8_t *data, size_t datalen); 99 int handle_expiry(); 100 void schedule_retransmit(); 101 int handshake_completed(); 102 int handshake_confirmed(); 103 104 int send_packet(const Endpoint &ep, const ngtcp2_addr &remote_addr, 105 unsigned int ecn, const uint8_t *data, size_t datalen); 106 int on_stream_close(int64_t stream_id, uint64_t app_error_code); 107 int on_extend_max_streams(); 108 int handle_error(); 109 int make_stream_early(); 110 int change_local_addr(); 111 void start_change_local_addr_timer(); 112 int update_key(uint8_t *rx_secret, uint8_t *tx_secret, 113 ngtcp2_crypto_aead_ctx *rx_aead_ctx, uint8_t *rx_iv, 114 ngtcp2_crypto_aead_ctx *tx_aead_ctx, uint8_t *tx_iv, 115 const uint8_t *current_rx_secret, 116 const uint8_t *current_tx_secret, size_t secretlen); 117 int initiate_key_update(); 118 void start_key_update_timer(); 119 void start_delay_stream_timer(); 120 121 int select_preferred_address(Address &selected_addr, 122 const ngtcp2_preferred_addr *paddr); 123 124 std::optional<Endpoint *> endpoint_for(const Address &remote_addr); 125 126 void set_remote_addr(const ngtcp2_addr &remote_addr); 127 128 int submit_http_request(Stream *stream); 129 int recv_stream_data(uint32_t flags, int64_t stream_id, const uint8_t *data, 130 size_t datalen); 131 int acked_stream_data_offset(int64_t stream_id, uint64_t offset, 132 uint64_t datalen); 133 int extend_max_stream_data(int64_t stream_id, uint64_t max_data); 134 135 void reset_idle_timer(); 136 137 void write_qlog(const void *data, size_t datalen); 138 139 void idle_timeout(); 140 141 private: 142 std::vector<Endpoint> endpoints_; 143 Address remote_addr_; 144 ev_io wev_; 145 ev_timer timer_; 146 ev_timer rttimer_; 147 ev_timer change_local_addr_timer_; 148 ev_timer key_update_timer_; 149 ev_timer delay_stream_timer_; 150 ev_signal sigintev_; 151 struct ev_loop *loop_; 152 std::map<int64_t, std::unique_ptr<Stream>> streams_; 153 std::set<Stream *, StreamIDLess> sendq_; 154 // addr_ is the server host address. 155 const char *addr_; 156 // port_ is the server port. 157 const char *port_; 158 // nstreams_done_ is the number of streams opened. 159 size_t nstreams_done_; 160 // nstreams_closed_ is the number of streams get closed. 161 size_t nstreams_closed_; 162 // nkey_update_ is the number of key update occurred. 163 size_t nkey_update_; 164 uint32_t version_; 165 // early_data_ is true if client attempts to do 0RTT data transfer. 166 bool early_data_; 167 // should_exit_ is true if client should exit rather than waiting 168 // for timeout. 169 bool should_exit_; 170 // handshake_confirmed_ gets true after handshake has been 171 // confirmed. 172 bool handshake_confirmed_; 173 }; 174 175 #endif // CLIENT_H 176