1 /* 2 * nghttp2 - HTTP/2 C Library 3 * 4 * Copyright (c) 2014 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 H2LOAD_H 26 #define H2LOAD_H 27 28 #include "nghttp2_config.h" 29 30 #include <sys/types.h> 31 #ifdef HAVE_SYS_SOCKET_H 32 # include <sys/socket.h> 33 #endif // HAVE_SYS_SOCKET_H 34 #ifdef HAVE_NETDB_H 35 # include <netdb.h> 36 #endif // HAVE_NETDB_H 37 #include <sys/un.h> 38 39 #include <vector> 40 #include <string> 41 #include <unordered_map> 42 #include <memory> 43 #include <chrono> 44 #include <array> 45 46 #include <nghttp2/nghttp2.h> 47 48 #ifdef ENABLE_HTTP3 49 # include <ngtcp2/ngtcp2.h> 50 # include <ngtcp2/ngtcp2_crypto.h> 51 #endif // ENABLE_HTTP3 52 53 #include <ev.h> 54 55 #include <openssl/ssl.h> 56 57 #include "http2.h" 58 #ifdef ENABLE_HTTP3 59 # include "quic.h" 60 #endif // ENABLE_HTTP3 61 #include "memchunk.h" 62 #include "template.h" 63 64 using namespace nghttp2; 65 66 namespace h2load { 67 68 constexpr auto BACKOFF_WRITE_BUFFER_THRES = 16_k; 69 70 class Session; 71 struct Worker; 72 73 struct Config { 74 std::vector<std::vector<nghttp2_nv>> nva; 75 std::vector<std::string> h1reqs; 76 std::vector<ev_tstamp> timings; 77 nghttp2::Headers custom_headers; 78 std::string scheme; 79 std::string host; 80 std::string connect_to_host; 81 std::string ifile; 82 std::string ciphers; 83 std::string tls13_ciphers; 84 // supported groups (or curves). 85 std::string groups; 86 // length of upload data 87 int64_t data_length; 88 // memory mapped upload data 89 uint8_t *data; 90 addrinfo *addrs; 91 size_t nreqs; 92 size_t nclients; 93 size_t nthreads; 94 // The maximum number of concurrent streams per session. 95 ssize_t max_concurrent_streams; 96 size_t window_bits; 97 size_t connection_window_bits; 98 size_t max_frame_size; 99 // rate at which connections should be made 100 size_t rate; 101 ev_tstamp rate_period; 102 // amount of time for main measurements in timing-based test 103 ev_tstamp duration; 104 // amount of time to wait before starting measurements in timing-based test 105 ev_tstamp warm_up_time; 106 // amount of time to wait for activity on a given connection 107 ev_tstamp conn_active_timeout; 108 // amount of time to wait after the last request is made on a connection 109 ev_tstamp conn_inactivity_timeout; 110 enum { PROTO_HTTP2, PROTO_HTTP1_1 } no_tls_proto; 111 uint32_t header_table_size; 112 uint32_t encoder_header_table_size; 113 // file descriptor for upload data 114 int data_fd; 115 // file descriptor to write per-request stats to. 116 int log_fd; 117 // base file name of qlog output files 118 std::string qlog_file_base; 119 uint16_t port; 120 uint16_t default_port; 121 uint16_t connect_to_port; 122 bool verbose; 123 bool timing_script; 124 std::string base_uri; 125 // true if UNIX domain socket is used. In this case, base_uri is 126 // not used in usual way. 127 bool base_uri_unix; 128 // used when UNIX domain socket is used (base_uri_unix is true). 129 sockaddr_un unix_addr; 130 // list of supported NPN/ALPN protocol strings in the order of 131 // preference. 132 std::vector<std::string> npn_list; 133 // The number of request per second for each client. 134 double rps; 135 // Disables GSO for UDP connections. 136 bool no_udp_gso; 137 // The maximum UDP datagram payload size to send. 138 size_t max_udp_payload_size; 139 // Enable ktls. 140 bool ktls; 141 142 Config(); 143 ~Config(); 144 145 bool is_rate_mode() const; 146 bool is_timing_based_mode() const; 147 bool has_base_uri() const; 148 bool rps_enabled() const; 149 bool is_quic() const; 150 }; 151 152 struct RequestStat { 153 // time point when request was sent 154 std::chrono::steady_clock::time_point request_time; 155 // same, but in wall clock reference frame 156 std::chrono::system_clock::time_point request_wall_time; 157 // time point when stream was closed 158 std::chrono::steady_clock::time_point stream_close_time; 159 // upload data length sent so far 160 int64_t data_offset; 161 // HTTP status code 162 int status; 163 // true if stream was successfully closed. This means stream was 164 // not reset, but it does not mean HTTP level error (e.g., 404). 165 bool completed; 166 }; 167 168 struct ClientStat { 169 // time client started (i.e., first connect starts) 170 std::chrono::steady_clock::time_point client_start_time; 171 // time client end (i.e., client somehow processed all requests it 172 // is responsible for, and disconnected) 173 std::chrono::steady_clock::time_point client_end_time; 174 // The number of requests completed successful, but not necessarily 175 // means successful HTTP status code. 176 size_t req_success; 177 178 // The following 3 numbers are overwritten each time when connection 179 // is made. 180 181 // time connect starts 182 std::chrono::steady_clock::time_point connect_start_time; 183 // time to connect 184 std::chrono::steady_clock::time_point connect_time; 185 // time to first byte (TTFB) 186 std::chrono::steady_clock::time_point ttfb; 187 }; 188 189 struct SDStat { 190 // min, max, mean and sd (standard deviation) 191 double min, max, mean, sd; 192 // percentage of samples inside mean -/+ sd 193 double within_sd; 194 }; 195 196 struct SDStats { 197 // time for request 198 SDStat request; 199 // time for connect 200 SDStat connect; 201 // time to first byte (TTFB) 202 SDStat ttfb; 203 // request per second for each client 204 SDStat rps; 205 }; 206 207 struct Stats { 208 Stats(size_t req_todo, size_t nclients); 209 // The total number of requests 210 size_t req_todo; 211 // The number of requests issued so far 212 size_t req_started; 213 // The number of requests finished 214 size_t req_done; 215 // The number of requests completed successful, but not necessarily 216 // means successful HTTP status code. 217 size_t req_success; 218 // The number of requests marked as success. HTTP status code is 219 // also considered as success. This is subset of req_done. 220 size_t req_status_success; 221 // The number of requests failed. This is subset of req_done. 222 size_t req_failed; 223 // The number of requests failed due to network errors. This is 224 // subset of req_failed. 225 size_t req_error; 226 // The number of requests that failed due to timeout. 227 size_t req_timedout; 228 // The number of bytes received on the "wire". If SSL/TLS is used, 229 // this is the number of decrypted bytes the application received. 230 int64_t bytes_total; 231 // The number of bytes received for header fields. This is 232 // compressed version. 233 int64_t bytes_head; 234 // The number of bytes received for header fields after they are 235 // decompressed. 236 int64_t bytes_head_decomp; 237 // The number of bytes received in DATA frame. 238 int64_t bytes_body; 239 // The number of each HTTP status category, status[i] is status code 240 // in the range [i*100, (i+1)*100). 241 std::array<size_t, 6> status; 242 // The statistics per request 243 std::vector<RequestStat> req_stats; 244 // The statistics per client 245 std::vector<ClientStat> client_stats; 246 // The number of UDP datagrams received. 247 size_t udp_dgram_recv; 248 // The number of UDP datagrams sent. 249 size_t udp_dgram_sent; 250 }; 251 252 enum ClientState { CLIENT_IDLE, CLIENT_CONNECTED }; 253 254 // This type tells whether the client is in warmup phase or not or is over 255 enum class Phase { 256 INITIAL_IDLE, // Initial idle state before warm-up phase 257 WARM_UP, // Warm up phase when no measurements are done 258 MAIN_DURATION, // Main measurement phase; if timing-based 259 // test is not run, this is the default phase 260 DURATION_OVER // This phase occurs after the measurements are over 261 }; 262 263 struct Client; 264 265 // We use reservoir sampling method 266 struct Sampling { 267 // maximum number of samples 268 size_t max_samples; 269 // number of samples seen, including discarded samples. 270 size_t n; 271 }; 272 273 struct Worker { 274 MemchunkPool mcpool; 275 std::mt19937 randgen; 276 Stats stats; 277 Sampling request_times_smp; 278 Sampling client_smp; 279 struct ev_loop *loop; 280 SSL_CTX *ssl_ctx; 281 Config *config; 282 size_t progress_interval; 283 uint32_t id; 284 bool tls_info_report_done; 285 bool app_info_report_done; 286 size_t nconns_made; 287 // number of clients this worker handles 288 size_t nclients; 289 // number of requests each client issues 290 size_t nreqs_per_client; 291 // at most nreqs_rem clients get an extra request 292 size_t nreqs_rem; 293 size_t rate; 294 // maximum number of samples in this worker thread 295 size_t max_samples; 296 ev_timer timeout_watcher; 297 // The next client ID this worker assigns 298 uint32_t next_client_id; 299 // Keeps track of the current phase (for timing-based experiment) for the 300 // worker 301 Phase current_phase; 302 // We need to keep track of the clients in order to stop them when needed 303 std::vector<Client *> clients; 304 // This is only active when there is not a bounded number of requests 305 // specified 306 ev_timer duration_watcher; 307 ev_timer warmup_watcher; 308 309 Worker(uint32_t id, SSL_CTX *ssl_ctx, size_t nreq_todo, size_t nclients, 310 size_t rate, size_t max_samples, Config *config); 311 ~Worker(); 312 Worker(Worker &&o) = default; 313 void run(); 314 void sample_req_stat(RequestStat *req_stat); 315 void sample_client_stat(ClientStat *cstat); 316 void report_progress(); 317 void report_rate_progress(); 318 // This function calls the destructors of all the clients. 319 void stop_all_clients(); 320 // This function frees a client from the list of clients for this Worker. 321 void free_client(Client *); 322 }; 323 324 struct Stream { 325 RequestStat req_stat; 326 int status_success; 327 Stream(); 328 }; 329 330 struct Client { 331 DefaultMemchunks wb; 332 std::unordered_map<int32_t, Stream> streams; 333 ClientStat cstat; 334 std::unique_ptr<Session> session; 335 ev_io wev; 336 ev_io rev; 337 std::function<int(Client &)> readfn, writefn; 338 Worker *worker; 339 SSL *ssl; 340 #ifdef ENABLE_HTTP3 341 struct { 342 ngtcp2_crypto_conn_ref conn_ref; 343 ev_timer pkt_timer; 344 ngtcp2_conn *conn; 345 ngtcp2_connection_close_error last_error; 346 bool close_requested; 347 FILE *qlog_file; 348 349 struct { 350 bool send_blocked; 351 size_t num_blocked; 352 size_t num_blocked_sent; 353 struct { 354 Address remote_addr; 355 const uint8_t *data; 356 size_t datalen; 357 size_t gso_size; 358 } blocked[2]; 359 std::unique_ptr<uint8_t[]> data; 360 } tx; 361 } quic; 362 #endif // ENABLE_HTTP3 363 ev_timer request_timeout_watcher; 364 addrinfo *next_addr; 365 // Address for the current address. When try_new_connection() is 366 // used and current_addr is not nullptr, it is used instead of 367 // trying next address though next_addr. To try new address, set 368 // nullptr to current_addr before calling connect(). 369 addrinfo *current_addr; 370 size_t reqidx; 371 ClientState state; 372 // The number of requests this client has to issue. 373 size_t req_todo; 374 // The number of requests left to issue 375 size_t req_left; 376 // The number of requests currently have started, but not abandoned 377 // or finished. 378 size_t req_inflight; 379 // The number of requests this client has issued so far. 380 size_t req_started; 381 // The number of requests this client has done so far. 382 size_t req_done; 383 // The client id per worker 384 uint32_t id; 385 int fd; 386 Address local_addr; 387 ev_timer conn_active_watcher; 388 ev_timer conn_inactivity_watcher; 389 std::string selected_proto; 390 bool new_connection_requested; 391 // true if the current connection will be closed, and no more new 392 // request cannot be processed. 393 bool final; 394 // rps_watcher is a timer to invoke callback periodically to 395 // generate a new request. 396 ev_timer rps_watcher; 397 // The timestamp that starts the period which contributes to the 398 // next request generation. 399 ev_tstamp rps_duration_started; 400 // The number of requests allowed by rps, but limited by stream 401 // concurrency. 402 size_t rps_req_pending; 403 // The number of in-flight streams. req_inflight has similar value 404 // but it only measures requests made during Phase::MAIN_DURATION. 405 // rps_req_inflight measures the number of requests in all phases, 406 // and it is only used if --rps is given. 407 size_t rps_req_inflight; 408 409 enum { ERR_CONNECT_FAIL = -100 }; 410 411 Client(uint32_t id, Worker *worker, size_t req_todo); 412 ~Client(); 413 int make_socket(addrinfo *addr); 414 int connect(); 415 void disconnect(); 416 void fail(); 417 // Call this function when do_read() returns -1. This function 418 // tries to connect to the remote host again if it is requested. If 419 // so, this function returns 0, and this object should be retained. 420 // Otherwise, this function returns -1, and this object should be 421 // deleted. 422 int try_again_or_fail(); 423 void timeout(); 424 void restart_timeout(); 425 int submit_request(); 426 void process_request_failure(); 427 void process_timedout_streams(); 428 void process_abandoned_streams(); 429 void report_tls_info(); 430 void report_app_info(); 431 void terminate_session(); 432 // Asks client to create new connection, instead of just fail. 433 void try_new_connection(); 434 435 int do_read(); 436 int do_write(); 437 438 // low-level I/O callback functions called by do_read/do_write 439 int connected(); 440 int read_clear(); 441 int write_clear(); 442 int tls_handshake(); 443 int read_tls(); 444 int write_tls(); 445 446 int on_read(const uint8_t *data, size_t len); 447 int on_write(); 448 449 int connection_made(); 450 451 void on_request(int32_t stream_id); 452 void on_header(int32_t stream_id, const uint8_t *name, size_t namelen, 453 const uint8_t *value, size_t valuelen); 454 void on_status_code(int32_t stream_id, uint16_t status); 455 // |success| == true means that the request/response was exchanged 456 // |successfully, but it does not mean response carried successful 457 // |HTTP status code. 458 void on_stream_close(int32_t stream_id, bool success, bool final = false); 459 // Returns RequestStat for |stream_id|. This function must be 460 // called after on_request(stream_id), and before 461 // on_stream_close(stream_id, ...). Otherwise, this will return 462 // nullptr. 463 RequestStat *get_req_stat(int32_t stream_id); 464 465 void record_request_time(RequestStat *req_stat); 466 void record_connect_start_time(); 467 void record_connect_time(); 468 void record_ttfb(); 469 void clear_connect_times(); 470 void record_client_start_time(); 471 void record_client_end_time(); 472 473 void signal_write(); 474 475 #ifdef ENABLE_HTTP3 476 // QUIC 477 int quic_init(const sockaddr *local_addr, socklen_t local_addrlen, 478 const sockaddr *remote_addr, socklen_t remote_addrlen); 479 void quic_free(); 480 int read_quic(); 481 int write_quic(); 482 int write_udp(const sockaddr *addr, socklen_t addrlen, const uint8_t *data, 483 size_t datalen, size_t gso_size); 484 void on_send_blocked(const ngtcp2_addr &remote_addr, const uint8_t *data, 485 size_t datalen, size_t gso_size); 486 int send_blocked_packet(); 487 void quic_close_connection(); 488 489 int quic_handshake_completed(); 490 int quic_recv_stream_data(uint32_t flags, int64_t stream_id, 491 const uint8_t *data, size_t datalen); 492 int quic_acked_stream_data_offset(int64_t stream_id, size_t datalen); 493 int quic_stream_close(int64_t stream_id, uint64_t app_error_code); 494 int quic_stream_reset(int64_t stream_id, uint64_t app_error_code); 495 int quic_stream_stop_sending(int64_t stream_id, uint64_t app_error_code); 496 int quic_extend_max_local_streams(); 497 498 int quic_write_client_handshake(ngtcp2_crypto_level level, 499 const uint8_t *data, size_t datalen); 500 int quic_pkt_timeout(); 501 void quic_restart_pkt_timer(); 502 void quic_write_qlog(const void *data, size_t datalen); 503 int quic_make_http3_session(); 504 #endif // ENABLE_HTTP3 505 }; 506 507 } // namespace h2load 508 509 #endif // H2LOAD_H 510