1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/*
* ngtcp2
*
* Copyright (c) 2020 ngtcp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef CLIENT_BASE_H
#define CLIENT_BASE_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif // HAVE_CONFIG_H
#include <vector>
#include <deque>
#include <string>
#include <string_view>
#include <functional>
#include <ngtcp2/ngtcp2_crypto.h>
#include "tls_client_session.h"
#include "network.h"
#include "shared.h"
using namespace ngtcp2;
struct Request {
std::string_view scheme;
std::string authority;
std::string path;
};
struct Config {
ngtcp2_cid dcid;
ngtcp2_cid scid;
bool scid_present;
// tx_loss_prob is probability of losing outgoing packet.
double tx_loss_prob;
// rx_loss_prob is probability of losing incoming packet.
double rx_loss_prob;
// fd is a file descriptor to read input for streams.
int fd;
// ciphers is the list of enabled ciphers.
const char *ciphers;
// groups is the list of supported groups.
const char *groups;
// nstreams is the number of streams to open.
size_t nstreams;
// data is the pointer to memory region which maps file denoted by
// fd.
uint8_t *data;
// datalen is the length of file denoted by fd.
size_t datalen;
// version is a QUIC version to use.
uint32_t version;
// quiet suppresses the output normally shown except for the error
// messages.
bool quiet;
// timeout is an idle timeout for QUIC connection.
ngtcp2_duration timeout;
// session_file is a path to a file to write, and read TLS session.
const char *session_file;
// tp_file is a path to a file to write, and read QUIC transport
// parameters.
const char *tp_file;
// show_secret is true if transport secrets should be printed out.
bool show_secret;
// change_local_addr is the duration after which client changes
// local address.
ngtcp2_duration change_local_addr;
// key_update is the duration after which client initiates key
// update.
ngtcp2_duration key_update;
// delay_stream is the duration after which client sends the first
// 1-RTT stream.
ngtcp2_duration delay_stream;
// nat_rebinding is true if simulated NAT rebinding is enabled.
bool nat_rebinding;
// no_preferred_addr is true if client do not follow preferred
// address offered by server.
bool no_preferred_addr;
std::string_view http_method;
// download is a path to a directory where a downloaded file is
// saved. If it is empty, no file is saved.
std::string_view download;
// requests contains URIs to request.
std::vector<Request> requests;
// no_quic_dump is true if hexdump of QUIC STREAM and CRYPTO data
// should be disabled.
bool no_quic_dump;
// no_http_dump is true if hexdump of HTTP response body should be
// disabled.
bool no_http_dump;
// qlog_file is the path to write qlog.
std::string_view qlog_file;
// qlog_dir is the path to directory where qlog is stored. qlog_dir
// and qlog_file are mutually exclusive.
std::string_view qlog_dir;
// max_data is the initial connection-level flow control window.
uint64_t max_data;
// max_stream_data_bidi_local is the initial stream-level flow
// control window for a bidirectional stream that the local endpoint
// initiates.
uint64_t max_stream_data_bidi_local;
// max_stream_data_bidi_remote is the initial stream-level flow
// control window for a bidirectional stream that the remote
// endpoint initiates.
uint64_t max_stream_data_bidi_remote;
// max_stream_data_uni is the initial stream-level flow control
// window for a unidirectional stream.
uint64_t max_stream_data_uni;
// max_streams_bidi is the number of the concurrent bidirectional
// streams.
uint64_t max_streams_bidi;
// max_streams_uni is the number of the concurrent unidirectional
// streams.
uint64_t max_streams_uni;
// max_window is the maximum connection-level flow control window
// size if auto-tuning is enabled.
uint64_t max_window;
// max_stream_window is the maximum stream-level flow control window
// size if auto-tuning is enabled.
uint64_t max_stream_window;
// exit_on_first_stream_close is the flag that if it is true, client
// exits when a first HTTP stream gets closed. It is not
// necessarily the same time when the underlying QUIC stream closes
// due to the QPACK synchronization.
bool exit_on_first_stream_close;
// exit_on_all_streams_close is the flag that if it is true, client
// exits when all HTTP streams get closed.
bool exit_on_all_streams_close;
// disable_early_data disables early data.
bool disable_early_data;
// static_secret is used to derive keying materials for Stateless
// Retry token.
std::array<uint8_t, 32> static_secret;
// cc_algo is the congestion controller algorithm.
ngtcp2_cc_algo cc_algo;
// token_file is a path to file to read or write token from
// NEW_TOKEN frame.
std::string_view token_file;
// sni is the value sent in TLS SNI, overriding DNS name of the
// remote host.
std::string_view sni;
// initial_rtt is an initial RTT.
ngtcp2_duration initial_rtt;
// max_udp_payload_size is the maximum UDP payload size that client
// transmits.
size_t max_udp_payload_size;
// handshake_timeout is the period of time before giving up QUIC
// connection establishment.
ngtcp2_duration handshake_timeout;
// preferred_versions includes QUIC versions in the order of
// preference. Client uses this field to select a version from the
// version set offered in Version Negotiation packet.
std::vector<uint32_t> preferred_versions;
// other_versions includes QUIC versions that are sent in
// other_versions field of version_information transport_parameter.
std::vector<uint32_t> other_versions;
// no_pmtud disables Path MTU Discovery.
bool no_pmtud;
// ack_thresh is the minimum number of the received ACK eliciting
// packets that triggers immediate acknowledgement.
size_t ack_thresh;
};
class ClientBase {
public:
ClientBase();
~ClientBase();
ngtcp2_conn *conn() const;
int write_transport_params(const char *path,
const ngtcp2_transport_params *params);
int read_transport_params(const char *path, ngtcp2_transport_params *params);
void write_qlog(const void *data, size_t datalen);
ngtcp2_crypto_conn_ref *conn_ref();
protected:
ngtcp2_crypto_conn_ref conn_ref_;
TLSClientSession tls_session_;
FILE *qlog_;
ngtcp2_conn *conn_;
ngtcp2_connection_close_error last_error_;
};
void qlog_write_cb(void *user_data, uint32_t flags, const void *data,
size_t datalen);
#endif // CLIENT_BASE_H
|