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