* SPDX-License-Identifier: curl
*
***************************************************************************/
-
#include "curl_setup.h"
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY) && \
- defined(USE_PROXY_HTTP3) && defined(USE_NGHTTP3) && \
- defined(USE_NGTCP2) && defined(USE_OPENSSL)
+ defined(USE_PROXY_HTTP3) && defined(USE_NGHTTP3) && \
+ defined(USE_NGTCP2) && defined(USE_OPENSSL)
#include <ngtcp2/ngtcp2.h>
-#include <ngtcp2/ngtcp2_crypto.h>
+
#ifdef USE_OPENSSL
#include <openssl/err.h>
-#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+#if defined(OPENSSL_IS_AWSLC) || defined(OPENSSL_IS_BORINGSSL)
#include <ngtcp2/ngtcp2_crypto_boringssl.h>
#elif defined(OPENSSL_QUIC_API2)
#include <ngtcp2/ngtcp2_crypto_ossl.h>
#include <ngtcp2/ngtcp2_crypto_quictls.h>
#endif
#include "vtls/openssl.h"
-#endif /* USE_OPENSSL */
+#endif
#include <nghttp3/nghttp3.h>
#include "urldata.h"
+#include "url.h"
+#include "uint-hash.h"
+#include "curl_trc.h"
+#include "rand.h"
#include "hash.h"
#include "sendf.h"
#include "multiif.h"
#include "dynhds.h"
#include "http_proxy.h"
#include "select.h"
-#include "uint-hash.h"
#include "vquic/vquic.h"
#include "vquic/vquic_int.h"
#include "vquic/vquic-tls.h"
#include "vtls/vtls.h"
#include "vtls/vtls_scache.h"
-#include "curl_trc.h"
#include "cf-h3-proxy.h"
-#include "url.h"
#include "capsule.h"
-#include "rand.h"
/* A stream window is the maximum amount we need to buffer for
* each active transfer. We use HTTP/3 flow control and only ACK
/* The pool keeps spares around and half of a full stream window
* seems good. More does not seem to improve performance.
- * The benefit of the pool is that stream buffer to not keep
+ * The benefit of the pool is that stream buffers do not keep
* spares. Memory consumption goes down when streams run empty,
* have a large upload done, etc. */
#define PROXY_H3_STREAM_POOL_SPARES \
#define PROXY_H3_STREAM_SEND_CHUNKS \
(PROXY_H3_STREAM_WINDOW_SIZE / PROXY_H3_STREAM_CHUNK_SIZE)
-#define PROXY_QUIC_MAX_STREAMS (256*1024)
-#define PROXY_QUIC_HANDSHAKE_TIMEOUT (10*NGTCP2_SECONDS)
+#define PROXY_QUIC_MAX_STREAMS (256 * 1024)
+#define PROXY_QUIC_HANDSHAKE_TIMEOUT (10 * NGTCP2_SECONDS)
-typedef enum
-{
+typedef enum {
H3_TUNNEL_INIT, /* init/default/no tunnel state */
H3_TUNNEL_CONNECT, /* CONNECT request is being sent */
H3_TUNNEL_RESPONSE, /* CONNECT response received completely */
struct h3_proxy_stream_ctx;
-struct h3_tunnel_stream
-{
+struct h3_tunnel_stream {
struct http_resp *resp;
char *authority;
struct h3_proxy_stream_ctx *stream;
struct curl_tls_ctx tls;
#ifdef OPENSSL_QUIC_API2
ngtcp2_crypto_ossl_ctx *ossl_ctx;
-#endif /* OPENSSL_QUIC_API2 */
+#endif
ngtcp2_path connected_path;
ngtcp2_conn *qconn;
ngtcp2_cid dcid;
struct cf_call_data call_data;
nghttp3_conn *h3conn;
nghttp3_settings h3settings;
- struct curltime started_at; /* time the current attempt started */
- struct curltime handshake_at; /* time connect handshake finished */
- struct bufc_pool stream_bufcp; /* chunk pool for streams */
- struct dynbuf scratch; /* temp buffer for header construction */
- struct uint_hash streams;
- /* hash `data->mid` to `h3_proxy_stream_ctx` */
- uint64_t used_bidi_streams; /* bidi streams we have opened */
- uint64_t max_bidi_streams; /* max bidi streams we can open */
- size_t earlydata_max; /* max amount of early data supported by
- server on session reuse */
- size_t earlydata_skip; /* sending bytes to skip when earlydata
- is accepted by peer */
- CURLcode tls_vrfy_result; /* result of TLS peer verification */
+ struct curltime started_at; /* time the current attempt started */
+ struct curltime handshake_at; /* time connect handshake finished */
+ struct bufc_pool stream_bufcp; /* chunk pool for streams */
+ struct dynbuf scratch; /* temp buffer for header construction */
+ struct uint_hash streams; /* hash data->mid to h3_proxy_stream_ctx */
+ uint64_t used_bidi_streams; /* bidi streams we have opened */
+ uint64_t max_bidi_streams; /* max bidi streams we can open */
+ size_t earlydata_max; /* max amount of early data supported by
+ server on session reuse */
+ size_t earlydata_skip; /* sending bytes to skip when earlydata
+ is accepted by peer */
+ CURLcode tls_vrfy_result; /* result of TLS peer verification */
int qlogfd;
BIT(initialized);
- BIT(tls_handshake_complete); /* TLS handshake is done */
- BIT(use_earlydata); /* Using 0RTT data */
- BIT(earlydata_accepted); /* 0RTT was accepted by server */
- BIT(shutdown_started); /* queued shutdown packets */
+ BIT(tls_handshake_complete); /* TLS handshake is done */
+ BIT(use_earlydata); /* Using 0RTT data */
+ BIT(earlydata_accepted); /* 0RTT was accepted by server */
+ BIT(shutdown_started); /* queued shutdown packets */
};
-struct cf_h3_proxy_ctx
-{
+struct cf_h3_proxy_ctx {
struct cf_ngtcp2_proxy_ctx *ngtcp2_ctx;
- struct cf_call_data call_data; /* fallback before backend ctx exists */
- struct bufq inbufq; /* network receive buffer */
- struct Curl_peer *dest; /* where to tunnel to */
+ struct cf_call_data call_data; /* fallback before backend ctx exists */
+ struct bufq inbufq; /* network receive buffer */
+ struct Curl_peer *dest; /* where to tunnel to */
struct h3_tunnel_stream tunnel; /* our tunnel CONNECT stream */
BIT(connected);
BIT(udp_tunnel);
/**
* All about the H3 internals of a stream
*/
-struct h3_proxy_stream_ctx
-{
- int64_t id; /* HTTP/3 stream identifier */
+struct h3_proxy_stream_ctx {
+ int64_t id; /* HTTP/3 stream identifier */
struct bufq sendbuf; /* h3 request body */
size_t sendbuf_len_in_flight; /* sendbuf amount "in flight" */
- uint64_t error3; /* HTTP/3 stream error code */
+ uint64_t error3; /* HTTP/3 stream error code */
curl_off_t upload_left; /* number of request bytes left to upload */
curl_off_t tun_data_recvd; /* number of bytes received over tunnel */
uint64_t rx_offset; /* current receive offset */
BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */
};
-#define H3_PROXY_STREAM_CTX(ctx, data) \
+#define H3_PROXY_STREAM_CTX(ctx, data) \
((data) ? Curl_uint32_hash_get(&(ctx)->streams, (data)->mid) : NULL)
#define H3_STREAM_ID(stream) ((stream)->id)
ngtcp2_crypto_ossl_ctx_del(ctx->ossl_ctx);
ctx->ossl_ctx = NULL;
}
-#endif /* OPENSSL_QUIC_API2 */
+#endif
ctx->call_data = save;
}
static void cf_ngtcp2_proxy_setup_keep_alive(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ struct Curl_easy *data)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
ngtcp2_conn_set_keep_alive_timeout(ctx->qconn, keep_ns);
CURL_TRC_CF(data, cf, "peer idle timeout is %" PRIu64 "ms, "
"set keep-alive to %" PRIu64 " ms.",
- (uint64_t)(rp->max_idle_timeout / NGTCP2_MILLISECONDS),
- (uint64_t)(keep_ns / NGTCP2_MILLISECONDS));
+ rp->max_idle_timeout / NGTCP2_MILLISECONDS,
+ keep_ns / NGTCP2_MILLISECONDS);
}
}
va_end(ap);
curl_mfprintf(stderr, "\n");
}
-#endif /* DEBUG_NGTCP2 */
+#endif
static void proxy_qlog_callback(void *user_data, uint32_t flags,
- const void *data, size_t datalen)
+ const void *data, size_t datalen)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
s->log_printf = proxy_quic_printf;
#else
s->log_printf = NULL;
-#endif /* DEBUG_NGTCP2 */
+#endif
s->initial_ts = pktx->ts;
s->handshake_timeout = (data->set.connecttimeout > 0) ?
/* try ten times the ngtcp2 defaults here for problems with Caddy */
s->glitch_ratelim_burst = 1000 * 10;
s->glitch_ratelim_rate = 33 * 10;
-#endif /* NGTCP2_SETTINGS_V3 */
+#endif
t->initial_max_data = 10 * PROXY_H3_STREAM_WINDOW_SIZE;
t->initial_max_stream_data_bidi_local = PROXY_H3_STREAM_WINDOW_SIZE;
t->initial_max_stream_data_bidi_remote = PROXY_H3_STREAM_WINDOW_SIZE;
}
static void cf_ngtcp2_proxy_conn_close(struct Curl_cfilter *cf,
- struct Curl_easy *data);
+ struct Curl_easy *data);
static bool cf_ngtcp2_proxy_err_is_fatal(int code)
{
}
static void cf_ngtcp2_proxy_err_set(struct Curl_cfilter *cf,
- struct Curl_easy *data, int code)
+ struct Curl_easy *data, int code)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
}
static void cf_ngtcp2_proxy_h3_err_set(struct Curl_cfilter *cf,
- struct Curl_easy *data, int code)
+ struct Curl_easy *data, int code)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
}
/* How to access `call_data` from a cf_h3_proxy filter */
-#undef CF_CTX_CALL_DATA
static struct cf_call_data *cf_h3_proxy_call_data(struct Curl_cfilter *cf)
{
struct cf_h3_proxy_ctx *ctx = cf ? cf->ctx : NULL;
return &ctx->call_data;
}
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) (*cf_h3_proxy_call_data(cf))
static void cf_h3_proxy_ctx_clear(struct cf_h3_proxy_ctx *ctx)
}
static CURLcode h3_proxy_data_setup(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ struct Curl_easy *data)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
}
static int cb_h3_proxy_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
- uint64_t datalen, void *user_data,
- void *stream_user_data)
+ uint64_t datalen, void *user_data,
+ void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
}
static int cb_h3_proxy_stream_close(nghttp3_conn *conn, int64_t stream_id,
- uint64_t app_error_code, void *user_data,
- void *stream_user_data)
+ uint64_t app_error_code, void *user_data,
+ void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
if(!stream->rx_offset)
return;
- avail = Curl_rlimit_avail(&data->progress.dl.rlimit,
- Curl_pgrs_now(data));
+ avail = Curl_rlimit_avail(&data->progress.dl.rlimit, Curl_pgrs_now(data));
if(avail <= 0) {
/* nothing available, do not extend the rx offset */
CURL_TRC_CF(data, cf, "[%" PRId64 "] dl rate limit exhausted (%" PRId64
}
static int cb_h3_proxy_recv_data(nghttp3_conn *conn, int64_t stream3_id,
- const uint8_t *buf, size_t buflen,
- void *user_data, void *stream_user_data)
+ const uint8_t *buf, size_t buflen,
+ void *user_data, void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
}
static int cb_h3_proxy_deferred_consume(nghttp3_conn *conn, int64_t stream_id,
- size_t consumed, void *user_data,
- void *stream_user_data)
+ size_t consumed, void *user_data,
+ void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
return 0;
}
-static int cb_h3_proxy_recv_header(nghttp3_conn *conn, int64_t sid,
- int32_t token, nghttp3_rcbuf *name,
- nghttp3_rcbuf *value, uint8_t flags,
- void *user_data, void *stream_user_data)
+static int cb_h3_proxy_recv_header(nghttp3_conn *conn, int64_t stream_id,
+ int32_t token, nghttp3_rcbuf *name,
+ nghttp3_rcbuf *value, uint8_t flags,
+ void *user_data, void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
- int64_t stream_id = sid;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
}
else {
/* store as an HTTP1-style header */
- CURL_TRC_CF(data, cf, "[%" PRId64 "] header: %.*s: %.*s",
- stream_id, (int)h3name.len, h3name.base,
- (int)h3val.len, h3val.base);
+ CURL_TRC_CF(data, cf, "[%" PRId64 "] header: %.*s: %.*s", stream_id,
+ (int)h3name.len, h3name.base, (int)h3val.len, h3val.base);
result = Curl_dynhds_add(&proxy_ctx->tunnel.resp->headers,
- (const char *)h3name.base, h3name.len,
- (const char *)h3val.base, h3val.len);
+ (const char *)h3name.base, h3name.len,
+ (const char *)h3val.base, h3val.len);
if(result) {
return -1;
}
return 0;
}
-static int cb_h3_proxy_end_headers(nghttp3_conn *conn, int64_t sid,
- int fin, void *user_data, void *stream_user_data)
+static int cb_h3_proxy_end_headers(nghttp3_conn *conn, int64_t stream_id,
+ int fin, void *user_data,
+ void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
struct Curl_easy *data = stream_user_data;
- int64_t stream_id = sid;
struct h3_proxy_stream_ctx *stream;
(void)conn;
(void)stream_id;
if(!stream)
return 0;
- CURL_TRC_CF(data, cf, "[%" PRId64 "] end_headers, status=%d",
- stream_id, stream->status_code);
+ CURL_TRC_CF(data, cf, "[%" PRId64 "] end_headers, status=%d", stream_id,
+ stream->status_code);
if(!proxy_ctx->tunnel.has_final_response) {
if(stream->status_code / 100 != 1) {
return 0;
}
-static int cb_h3_proxy_stop_sending(nghttp3_conn *conn, int64_t sid,
- uint64_t app_error_code, void *user_data,
- void *stream_user_data)
+static int cb_h3_proxy_stop_sending(nghttp3_conn *conn, int64_t stream_id,
+ uint64_t app_error_code, void *user_data,
+ void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
(void)stream_user_data;
if(ctx) {
- int rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, 0, sid,
+ int rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, 0, stream_id,
app_error_code);
if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
return 0;
}
-static int cb_h3_proxy_reset_stream(nghttp3_conn *conn, int64_t sid,
- uint64_t app_error_code, void *user_data,
- void *stream_user_data)
+static int cb_h3_proxy_reset_stream(nghttp3_conn *conn, int64_t stream_id,
+ uint64_t app_error_code, void *user_data,
+ void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
struct Curl_easy *data = stream_user_data;
- int64_t stream_id = sid;
int rv;
(void)conn;
return 0;
}
-static nghttp3_ssize
-cb_h3_read_data_for_tunnel_stream(nghttp3_conn *conn, int64_t stream_id,
- nghttp3_vec *vec, size_t veccnt,
- uint32_t *pflags, void *user_data,
- void *stream_user_data)
+static nghttp3_ssize cb_h3_read_data_for_tunnel_stream(nghttp3_conn *conn,
+ int64_t stream_id,
+ nghttp3_vec *vec,
+ size_t veccnt,
+ uint32_t *pflags,
+ void *user_data,
+ void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
cb_h3_proxy_reset_stream,
NULL, /* shutdown */
NULL, /* recv_settings (deprecated) */
-#ifdef NGHTTP3_CALLBACKS_V2 /* nghttp3 v1.11.0+ */
+#ifdef NGHTTP3_CALLBACKS_V2 /* nghttp3 v1.11.0+ */
NULL, /* recv_origin */
NULL, /* end_origin */
NULL, /* rand */
-#endif /* NGHTTP3_CALLBACKS_V2 */
+#endif
#ifdef NGHTTP3_CALLBACKS_V3 /* nghttp3 v1.14.0+ */
NULL, /* recv_settings2 */
-#endif /* NGHTTP3_CALLBACKS_V3 */
+#endif
};
#if NGTCP2_VERSION_NUM < 0x011100
uint32_t mid;
};
-static bool cf_ngtcp2_proxy_sfind(uint32_t mid, void *value,
- void *user_data)
+static bool cf_ngtcp2_proxy_sfind(uint32_t mid, void *value, void *user_data)
{
struct cf_ngtcp2_proxy_sfind_ctx *fctx = user_data;
struct h3_proxy_stream_ctx *stream = value;
return TRUE; /* continue */
}
-static struct h3_proxy_stream_ctx *
-cf_ngtcp2_proxy_get_stream(struct cf_ngtcp2_proxy_ctx *ctx, int64_t stream_id)
+static struct h3_proxy_stream_ctx *cf_ngtcp2_proxy_get_stream(
+ struct cf_ngtcp2_proxy_ctx *ctx, int64_t stream_id)
{
struct cf_ngtcp2_proxy_sfind_ctx fctx;
fctx.stream_id = stream_id;
return fctx.stream;
}
#else
-static struct h3_proxy_stream_ctx *
-cf_ngtcp2_proxy_get_stream(struct cf_ngtcp2_proxy_ctx *ctx, int64_t stream_id)
+static struct h3_proxy_stream_ctx *cf_ngtcp2_proxy_get_stream(
+ struct cf_ngtcp2_proxy_ctx *ctx, int64_t stream_id)
{
struct Curl_easy *data =
ngtcp2_conn_get_stream_user_data(ctx->qconn, stream_id);
rc = nghttp3_conn_bind_qpack_streams(ctx->h3conn, qpack_enc_stream_id,
qpack_dec_stream_id);
if(rc) {
- failf(data, "error binding HTTP/3 qpack streams: %s",
- ngtcp2_strerror(rc));
+ failf(data, "error binding HTTP/3 qpack streams: %s", ngtcp2_strerror(rc));
return CURLE_QUIC_CONNECT_ERROR;
}
#ifdef USE_GNUTLS
int flags = gnutls_session_get_flags(ctx->tls.gtls.session);
ctx->earlydata_accepted = !!(flags & GNUTLS_SFLAGS_EARLY_DATA);
-#endif /* USE_GNUTLS */
+#endif
#ifdef USE_WOLFSSL
#ifdef WOLFSSL_EARLY_DATA
ctx->earlydata_accepted =
DEBUGASSERT(0); /* should not come here if ED is disabled. */
ctx->earlydata_accepted = FALSE;
#endif /* WOLFSSL_EARLY_DATA */
-#endif /* USE_WOLFSSL */
+#endif
CURL_TRC_CF(data, cf, "server did%s accept %zu bytes of early data",
ctx->earlydata_accepted ? "" : " not", ctx->earlydata_skip);
Curl_pgrsEarlyData(data, ctx->earlydata_accepted ?
}
static int cb_ngtcp2_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
- int64_t sid, uint64_t offset,
+ int64_t stream_id, uint64_t offset,
const uint8_t *buf, size_t buflen,
void *user_data, void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
- int64_t stream_id = (int64_t)sid;
nghttp3_ssize nconsumed;
int fin = (flags & NGTCP2_STREAM_DATA_FLAG_FIN) ? 1 : 0;
struct Curl_easy *data = stream_user_data;
* including QPACK HEADERS. In other words, it does not consume payload of
* DATA frame. */
if(nconsumed) {
- ngtcp2_conn_extend_max_stream_offset(tconn, stream_id,
- (uint64_t)nconsumed);
- ngtcp2_conn_extend_max_offset(tconn, (uint64_t)nconsumed);
+ ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed);
+ ngtcp2_conn_extend_max_offset(tconn, nconsumed);
}
return 0;
}
static int cb_ngtcp2_stream_close(ngtcp2_conn *tconn, uint32_t flags,
- int64_t sid, uint64_t app_error_code,
+ int64_t stream_id, uint64_t app_error_code,
void *user_data, void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
struct Curl_easy *data = stream_user_data;
- int64_t stream_id = (int64_t)sid;
int rv;
(void)tconn;
rv = nghttp3_conn_close_stream(ctx->h3conn, stream_id, app_error_code);
CURL_TRC_CF(data, cf, "[%" PRId64 "] quic close(app_error=%"
- PRIu64 ") -> %d", stream_id, (uint64_t)app_error_code,
- rv);
+ PRIu64 ") -> %d", stream_id, app_error_code, rv);
if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) {
cf_ngtcp2_proxy_h3_err_set(cf, data, rv);
return NGTCP2_ERR_CALLBACK_FAILURE;
(void)tconn;
ctx->max_bidi_streams = max_streams;
if(data)
- CURL_TRC_CF(data, cf, "max bidi streams now %" PRIu64
- ", used %" PRIu64, (uint64_t)ctx->max_bidi_streams,
- (uint64_t)ctx->used_bidi_streams);
+ CURL_TRC_CF(data, cf, "max bidi streams now %" PRIu64 ", used %" PRIu64,
+ ctx->max_bidi_streams, ctx->used_bidi_streams);
return 0;
}
}
#endif
-static int cb_ngtcp2_stream_reset(ngtcp2_conn *tconn, int64_t sid,
+static int cb_ngtcp2_stream_reset(ngtcp2_conn *tconn, int64_t stream_id,
uint64_t final_size, uint64_t app_error_code,
void *user_data, void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
- int64_t stream_id = (int64_t)sid;
struct Curl_easy *data = stream_user_data;
int rv;
(void)tconn;
stream = H3_PROXY_STREAM_CTX(ctx, s_data);
if(stream && stream->quic_flow_blocked) {
CURL_TRC_CF(s_data, cf, "[%" PRId64 "] unblock quic flow",
- (int64_t)stream_id);
+ stream_id);
stream->quic_flow_blocked = FALSE;
Curl_multi_mark_dirty(s_data);
}
NULL, /* early_data_rejected */
#ifdef NGTCP2_CALLBACKS_V2 /* ngtcp2 v1.14.0+ */
NULL, /* begin_path_validation */
-#endif /* NGTCP2_CALLBACKS_V2 */
+#endif
#ifdef NGTCP2_CALLBACKS_V3 /* ngtcp2 v1.22.0+ */
NULL, /* recv_stateless_reset2 */
cb_ngtcp2_get_new_connection_id2, /* get_new_connection_id2 */
NULL, /* dcid_status2 */
ngtcp2_crypto_get_path_challenge_data2_cb, /* get_path_challenge_data2 */
-#endif /* NGTCP2_CALLBACKS_V3 */
+#endif
};
#if defined(_MSC_VER) && defined(_DLL)
CURL_TRC_CF(pktx->data, pktx->cf, "vquic_recv(len=%zu, gso=%zu, ecn=%x)",
buflen, gso_size, ecn);
ngtcp2_addr_init(&path.local, (struct sockaddr *)&ctx->q.local_addr,
- (socklen_t)ctx->q.local_addrlen);
+ ctx->q.local_addrlen);
ngtcp2_addr_init(&path.remote, (struct sockaddr *)remote_addr,
remote_addrlen);
pi.ecn = (uint8_t)ecn;
* Return number of bytes written or -1 with *err set.
*/
static CURLcode proxy_read_pkt_to_send(void *userp,
- unsigned char *buf, size_t buflen,
- size_t *pnread)
+ unsigned char *buf, size_t buflen,
+ size_t *pnread)
{
struct proxy_pkt_io_ctx *x = userp;
struct cf_h3_proxy_ctx *proxy_ctx = x->cf->ctx;
else if(n < 0) {
switch(n) {
case NGTCP2_ERR_STREAM_DATA_BLOCKED: {
- struct h3_proxy_stream_ctx *stream = NULL;
+ struct h3_proxy_stream_ctx *stream;
DEBUGASSERT(ndatalen == -1);
nghttp3_conn_block_stream(ctx->h3conn, stream_id);
CURL_TRC_CF(x->data, x->cf, "[%" PRId64 "] block quic flow",
- (int64_t)stream_id);
+ stream_id);
stream = cf_ngtcp2_proxy_get_stream(ctx, stream_id);
if(stream) /* it might be not one of our h3 streams? */
stream->quic_flow_blocked = TRUE;
*/
max_payload_size = ngtcp2_conn_get_max_tx_udp_payload_size(ctx->qconn);
path_max_payload_size =
- ngtcp2_conn_get_path_max_tx_udp_payload_size(ctx->qconn);
+ ngtcp2_conn_get_path_max_tx_udp_payload_size(ctx->qconn);
send_quantum = ngtcp2_conn_get_send_quantum(ctx->qconn);
CURL_TRC_CF(data, cf, "egress, collect and send packets, quantum=%zu",
send_quantum);
size_t buflen = Curl_bufq_len(&ctx->q.sendbuf);
if((buflen >= send_quantum) ||
((buflen + gsolen) >= ctx->q.sendbuf.chunk_size))
- break;
+ break;
DEBUGASSERT(nread > 0);
++pktcnt;
if(pktcnt == 1) {
}
static CURLcode cf_ngtcp2_proxy_shutdown(struct Curl_cfilter *cf,
- struct Curl_easy *data, bool *done)
+ struct Curl_easy *data, bool *done)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
&ctx->last_error, pktx.ts);
CURL_TRC_CF(data, cf, "start shutdown(err_type=%d, err_code=%"
PRIu64 ") -> %zd", ctx->last_error.type,
- (uint64_t)ctx->last_error.error_code, (ssize_t)nwritten);
+ ctx->last_error.error_code, (ssize_t)nwritten);
/* there are cases listed in ngtcp2 documentation where this call
* may fail. Since we are doing a connection shutdown as graceful
* as we can, such an error is ignored here. */
}
static void cf_ngtcp2_proxy_conn_close(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ struct Curl_easy *data)
{
bool done;
cf_ngtcp2_proxy_shutdown(cf, data, &done);
}
static void cf_ngtcp2_proxy_stream_close(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct h3_proxy_stream_ctx *stream)
+ struct Curl_easy *data,
+ struct h3_proxy_stream_ctx *stream)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
}
static ssize_t proxy_recv_closed_stream(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct h3_proxy_stream_ctx *stream,
- CURLcode *err)
+ struct Curl_easy *data,
+ struct h3_proxy_stream_ctx *stream,
+ CURLcode *err)
{
ssize_t nread = -1;
*err = CURLE_OK;
return nread;
}
-static struct h3_proxy_stream_ctx *
-h3_proxy_resolve_send_stream(struct cf_h3_proxy_ctx *proxy_ctx,
- struct cf_ngtcp2_proxy_ctx *ctx,
- struct Curl_easy *data)
+static struct h3_proxy_stream_ctx *h3_proxy_resolve_send_stream(
+ struct cf_h3_proxy_ctx *proxy_ctx,
+ struct cf_ngtcp2_proxy_ctx *ctx,
+ struct Curl_easy *data)
{
struct h3_proxy_stream_ctx *stream = H3_PROXY_STREAM_CTX(ctx, data);
}
if(!Curl_bufq_is_empty(&proxy_ctx->inbufq)) {
- result = Curl_bufq_cread(&proxy_ctx->inbufq,
- buf, len, pnread);
+ result = Curl_bufq_cread(&proxy_ctx->inbufq, buf, len, pnread);
if(result)
goto out;
}
/* inbufq had nothing before, maybe after progressing ingress? */
if(!*pnread && !Curl_bufq_is_empty(&proxy_ctx->inbufq)) {
- result = Curl_bufq_cread(&proxy_ctx->inbufq,
- buf, len, pnread);
+ result = Curl_bufq_cread(&proxy_ctx->inbufq, buf, len, pnread);
if(result) {
CURL_TRC_CF(data, cf, "[%" PRId64 "] read inbufq(len=%zu) "
"-> %zd, %d",
}
else {
if(stream->xfer_result) {
- CURL_TRC_CF(data, cf, "[%" PRId64 "] xfer write failed",
- stream->id);
+ CURL_TRC_CF(data, cf, "[%" PRId64 "] xfer write failed", stream->id);
cf_ngtcp2_proxy_stream_close(cf, data, stream);
result = stream->xfer_result;
goto out;
*err = CURLE_SEND_ERROR;
goto out;
}
- stream->id = (int64_t)sid;
+ stream->id = sid;
++ctx->used_bidi_streams;
/* Set stream user data in ngtcp2 connection for callbacks */
bool c_exhaust, s_exhaust;
CF_DATA_SAVE(save, cf, data);
- c_exhaust = want_send && (!ngtcp2_conn_get_cwnd_left(ctx->qconn) ||
- !ngtcp2_conn_get_max_data_left(ctx->qconn));
+ c_exhaust = want_send &&
+ (!ngtcp2_conn_get_cwnd_left(ctx->qconn) ||
+ !ngtcp2_conn_get_max_data_left(ctx->qconn));
s_exhaust = want_send && stream && H3_STREAM_ID(stream) >= 0 &&
stream->quic_flow_blocked;
want_recv = (want_recv || c_exhaust || s_exhaust);
{
ngtcp2_crypto_conn_ref *cref;
struct Curl_cfilter *cf;
- struct cf_h3_proxy_ctx *proxy_ctx;
struct cf_ngtcp2_proxy_ctx *ctx;
+ struct cf_h3_proxy_ctx *proxy_ctx;
struct Curl_easy *data;
cref = (ngtcp2_crypto_conn_ref *)SSL_get_app_data(ssl);
quic_tp = (unsigned char *)tpbuf;
quic_tp_len = (size_t)tplen;
}
-#endif /* HAVE_OPENSSL_EARLYDATA */
+#endif
Curl_ossl_add_session(cf, data, ctx->peer.scache_key, ssl_sessionid,
SSL_version(ssl), "h3", quic_tp, quic_tp_len);
}
struct curl_tls_ctx *ctx = user_data;
#ifdef USE_OPENSSL
-#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+#if defined(OPENSSL_IS_AWSLC) || defined(OPENSSL_IS_BORINGSSL)
if(ngtcp2_crypto_boringssl_configure_client_context(ctx->ossl.ssl_ctx)
!= 0) {
failf(data, "ngtcp2_crypto_boringssl_configure_client_context failed");
failf(data, "ngtcp2_crypto_quictls_configure_client_context failed");
return CURLE_FAILED_INIT;
}
-#endif
+#endif /* !OPENSSL_IS_AWSLC && !OPENSSL_IS_BORINGSSL */
if(Curl_ssl_scache_use(cf, data)) {
SSL_CTX_set_session_cache_mode(ctx->ossl.ssl_ctx,
SSL_SESS_CACHE_CLIENT |
}
static CURLcode cf_ngtcp2_proxy_on_session_reuse(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct alpn_spec *alpns,
- struct Curl_ssl_session *scs,
- bool *do_early_data)
+ struct Curl_easy *data,
+ struct alpn_spec *alpns,
+ struct Curl_ssl_session *scs,
+ bool *do_early_data)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
struct cf_ngtcp2_proxy_ctx *ctx = proxy_ctx->ngtcp2_ctx;
#ifdef USE_GNUTLS
ctx->earlydata_max =
gnutls_record_get_max_early_data_size(ctx->tls.gtls.session);
-#endif /* USE_GNUTLS */
+#endif
#ifdef USE_WOLFSSL
#ifdef WOLFSSL_EARLY_DATA
ctx->earlydata_max = scs->earlydata_max;
#else
ctx->earlydata_max = 0;
#endif /* WOLFSSL_EARLY_DATA */
-#endif /* USE_WOLFSSL */
+#endif
#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
- (defined(USE_OPENSSL) && defined(HAVE_OPENSSL_EARLYDATA))
- if((!ctx->earlydata_max)) {
+ (defined(USE_OPENSSL) && defined(HAVE_OPENSSL_EARLYDATA))
+ if(!ctx->earlydata_max) {
CURL_TRC_CF(data, cf, "SSL session does not allow earlydata");
}
else if(!Curl_alpn_contains_proto(alpns, scs->alpn)) {
CURL_TRC_CF(data, cf, "SSL session from different ALPN, no early data");
}
else if(!scs->quic_tp || !scs->quic_tp_len) {
- CURL_TRC_CF(data, cf, "no 0RTT transport parameters, no early data, ");
+ CURL_TRC_CF(data, cf, "no 0RTT transport parameters, no early data");
}
else {
int rv;
CURLcode result = CURLE_OK;
const struct Curl_sockaddr_ex *sockaddr = NULL;
int qfd;
- static const struct alpn_spec ALPN_SPEC_H3 = {{ "h3", "h3-29" }, 2};
+ static const struct alpn_spec ALPN_SPEC_H3 = { { "h3", "h3-29" }, 2 };
struct proxy_pkt_io_ctx pktx;
ctx = curlx_calloc(1, sizeof(struct cf_ngtcp2_proxy_ctx));
goto out;
/* Get remote address from the socket filter below */
if(cf->next->cft->query(cf->next, data, CF_QUERY_REMOTE_ADDR, NULL,
- CURL_UNCONST(&sockaddr)))
+ CURL_UNCONST(&sockaddr)))
goto out;
if(!sockaddr)
goto out;
}
static CURLcode h3_submit_CONNECT(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct h3_tunnel_stream *ts)
+ struct Curl_easy *data,
+ struct h3_tunnel_stream *ts)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
CURLcode result;
return result;
}
-static CURLcode
-h3_proxy_inspect_response(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct h3_tunnel_stream *ts)
+static CURLcode h3_proxy_inspect_response(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h3_tunnel_stream *ts)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
proxy_inspect_result res;
result = CURLE_COULDNT_CONNECT;
if(cerr) {
- CURL_TRC_CF(data, cf, "connect error, type=%d, code=%"
- PRIu64,
- cerr->type, (uint64_t)cerr->error_code);
+ CURL_TRC_CF(data, cf, "connect error, type=%d, code=%" PRIu64,
+ cerr->type, cerr->error_code);
switch(cerr->type) {
case NGTCP2_CCERR_TYPE_VERSION_NEGOTIATION:
CURL_TRC_CF(data, cf, "error in version negotiation");
return result;
}
-static CURLcode
-cf_h3_proxy_connect(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- bool *done)
+static CURLcode cf_h3_proxy_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data, bool *done)
{
struct cf_h3_proxy_ctx *proxy_ctx = cf->ctx;
- struct cf_call_data save = {0};
+ struct cf_call_data save = { 0 };
CURLcode result = CURLE_OK;
timediff_t check;
struct h3_tunnel_stream *ts = &proxy_ctx->tunnel;
stream = H3_PROXY_STREAM_CTX(ctx, data);
if(stream) {
- CURL_TRC_CF(data, cf, "[%" PRId64 "] easy handle is done",
- stream->id);
+ CURL_TRC_CF(data, cf, "[%" PRId64 "] easy handle is done", stream->id);
cf_ngtcp2_proxy_stream_close(cf, data, stream);
Curl_uint32_hash_remove(&ctx->streams, data->mid);
if(!Curl_uint32_hash_count(&ctx->streams))
}
struct Curl_cftype Curl_cft_h3_proxy = {
- "H3-PROXY",
- CF_TYPE_IP_CONNECT | CF_TYPE_PROXY | CF_TYPE_SSL,
- CURL_LOG_LVL_NONE,
- cf_h3_proxy_destroy,
- cf_h3_proxy_connect,
- cf_h3_proxy_close,
- cf_h3_proxy_shutdown,
- cf_h3_proxy_adjust_pollset,
- cf_h3_proxy_data_pending,
- cf_h3_proxy_send,
- cf_h3_proxy_recv,
- cf_h3_proxy_cntrl,
- cf_h3_proxy_is_alive,
- Curl_cf_def_conn_keep_alive,
- cf_h3_proxy_query,
+ "H3-PROXY",
+ CF_TYPE_IP_CONNECT | CF_TYPE_PROXY | CF_TYPE_SSL,
+ CURL_LOG_LVL_NONE,
+ cf_h3_proxy_destroy,
+ cf_h3_proxy_connect,
+ cf_h3_proxy_close,
+ cf_h3_proxy_shutdown,
+ cf_h3_proxy_adjust_pollset,
+ cf_h3_proxy_data_pending,
+ cf_h3_proxy_send,
+ cf_h3_proxy_recv,
+ cf_h3_proxy_cntrl,
+ cf_h3_proxy_is_alive,
+ Curl_cf_def_conn_keep_alive,
+ cf_h3_proxy_query,
};
CURLcode Curl_cf_h3_proxy_insert_after(struct Curl_cfilter *cf_at,
}
#endif
-
-/* Do not leak this filter's call_data accessor in unity builds. */
-#undef CF_CTX_CALL_DATA
#include "curl_setup.h"
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGTCP2) && defined(USE_NGHTTP3)
+
#include <ngtcp2/ngtcp2.h>
-#include <nghttp3/nghttp3.h>
#ifdef USE_OPENSSL
#include <openssl/err.h>
#include "vtls/wolfssl.h"
#endif
+#include <nghttp3/nghttp3.h>
+
#include "urldata.h"
#include "url.h"
#include "uint-hash.h"
#error H3_STREAM_CHUNK_SIZE smaller than NGTCP2_MAX_UDP_PAYLOAD_SIZE
#endif
-/* The pool keeps spares around and half of a full stream windows
+/* The pool keeps spares around and half of a full stream window
* seems good. More does not seem to improve performance.
- * The benefit of the pool is that stream buffer to not keep
+ * The benefit of the pool is that stream buffers do not keep
* spares. Memory consumption goes down when streams run empty,
* have a large upload done, etc. */
#define H3_STREAM_POOL_SPARES 2
struct cf_call_data call_data;
nghttp3_conn *h3conn;
nghttp3_settings h3settings;
- struct curltime started_at; /* time the current attempt started */
- struct curltime handshake_at; /* time connect handshake finished */
- struct bufc_pool stream_bufcp; /* chunk pool for streams */
- struct dynbuf scratch; /* temp buffer for header construction */
- struct uint_hash streams; /* hash `data->mid` to `h3_stream_ctx` */
- uint64_t used_bidi_streams; /* bidi streams we have opened */
- uint64_t max_bidi_streams; /* max bidi streams we can open */
- size_t earlydata_max; /* max amount of early data supported by
- server on session reuse */
- size_t earlydata_skip; /* sending bytes to skip when earlydata
- is accepted by peer */
- CURLcode tls_vrfy_result; /* result of TLS peer verification */
+ struct curltime started_at; /* time the current attempt started */
+ struct curltime handshake_at; /* time connect handshake finished */
+ struct bufc_pool stream_bufcp; /* chunk pool for streams */
+ struct dynbuf scratch; /* temp buffer for header construction */
+ struct uint_hash streams; /* hash data->mid to h3_stream_ctx */
+ uint64_t used_bidi_streams; /* bidi streams we have opened */
+ uint64_t max_bidi_streams; /* max bidi streams we can open */
+ size_t earlydata_max; /* max amount of early data supported by
+ server on session reuse */
+ size_t earlydata_skip; /* sending bytes to skip when earlydata
+ is accepted by peer */
+ CURLcode tls_vrfy_result; /* result of TLS peer verification */
int qlogfd;
- unsigned char *tunnel_inbuf; /* ingress buffer for tunneled packets */
+ unsigned char *tunnel_inbuf; /* ingress buffer for tunneled packets */
size_t tunnel_inbuf_len;
BIT(initialized);
- BIT(tls_handshake_complete); /* TLS handshake is done */
- BIT(use_earlydata); /* Using 0RTT data */
- BIT(earlydata_accepted); /* 0RTT was accepted by server */
- BIT(shutdown_started); /* queued shutdown packets */
+ BIT(tls_handshake_complete); /* TLS handshake is done */
+ BIT(use_earlydata); /* Using 0RTT data */
+ BIT(earlydata_accepted); /* 0RTT was accepted by server */
+ BIT(shutdown_started); /* queued shutdown packets */
};
/* How to access `call_data` from a cf_ngtcp2 filter */
#ifdef DEBUG_NGTCP2
static void quic_printf(void *user_data, const char *fmt, ...)
{
- struct Curl_cfilter *cf = user_data;
- struct cf_ngtcp2_ctx *ctx = cf->ctx;
-
- (void)ctx; /* need an easy handle to infof() message */
va_list ap;
+ (void)user_data;
va_start(ap, fmt);
curl_mvfprintf(stderr, fmt, ap);
va_end(ap);
rp = ngtcp2_conn_get_remote_transport_params(ctx->qconn);
CURL_TRC_CF(data, cf, "handshake complete after %" FMT_TIMEDIFF_T
"ms, remote transport[max_udp_payload=%" PRIu64
- ", initial_max_data=%" PRIu64
- "]",
- curlx_ptimediff_ms(&ctx->handshake_at, &ctx->started_at),
- rp->max_udp_payload_size, rp->initial_max_data);
+ ", initial_max_data=%" PRIu64 "]",
+ curlx_ptimediff_ms(&ctx->handshake_at, &ctx->started_at),
+ rp->max_udp_payload_size, rp->initial_max_data);
}
#endif
}
#ifdef NGTCP2_CALLBACKS_V3 /* ngtcp2 v1.22.0+ */
-static int cb_get_new_connection_id2(ngtcp2_conn *tconn, ngtcp2_cid *cid,
+static int cb_get_new_connection_id2(
+ ngtcp2_conn *tconn, ngtcp2_cid *cid,
struct ngtcp2_stateless_reset_token *token, size_t cidlen, void *user_data)
{
CURLcode result;
static void h3_xfer_write_resp_hd(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct h3_stream_ctx *stream,
- const char *buf, size_t blen, bool eos)
+ const char *buf, size_t buflen, bool eos)
{
/* This function returns no error intentionally, but records
* the result at the stream, skipping further writes once the
* send/recv callbacks. Closing the stream here leads to SEND/RECV
* errors in other places that then overwrite the transfer's result. */
if(!stream->xfer_result) {
- stream->xfer_result = Curl_xfer_write_resp_hd(data, buf, blen, eos);
+ stream->xfer_result = Curl_xfer_write_resp_hd(data, buf, buflen, eos);
if(stream->xfer_result)
CURL_TRC_CF(data, cf, "[%" PRId64 "] error %d writing %zu "
- "bytes of headers", stream->id, stream->xfer_result, blen);
+ "bytes of headers", stream->id, stream->xfer_result, buflen);
}
}
static void h3_xfer_write_resp(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct h3_stream_ctx *stream,
- const char *buf, size_t blen, bool eos)
+ const char *buf, size_t buflen, bool eos)
{
/* This function returns no error intentionally, but records
* the result at the stream, skipping further writes once the
* send/recv callbacks. Closing the stream here leads to SEND/RECV
* errors in other places that then overwrite the transfer's result. */
if(!stream->xfer_result) {
- stream->xfer_result = Curl_xfer_write_resp(data, buf, blen, eos);
+ stream->xfer_result = Curl_xfer_write_resp(data, buf, buflen, eos);
/* If the transfer write is errored, we do not want any more data */
if(stream->xfer_result) {
CURL_TRC_CF(data, cf, "[%" PRId64 "] error %d writing %zu bytes of data",
- stream->id, stream->xfer_result, blen);
+ stream->id, stream->xfer_result, buflen);
}
}
}
if(!stream->rx_offset)
return;
- avail = Curl_rlimit_avail(&data->progress.dl.rlimit,
- Curl_pgrs_now(data));
+ avail = Curl_rlimit_avail(&data->progress.dl.rlimit, Curl_pgrs_now(data));
if(avail <= 0) {
/* nothing available, do not extend the rx offset */
CURL_TRC_CF(data, cf, "[%" PRId64 "] dl rate limit exhausted (%" PRId64
}
static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
- const uint8_t *buf, size_t blen,
+ const uint8_t *buf, size_t buflen,
void *user_data, void *stream_user_data)
{
struct Curl_cfilter *cf = user_data;
if(!stream)
return NGHTTP3_ERR_CALLBACK_FAILURE;
- h3_xfer_write_resp(cf, data, stream, (const char *)buf, blen, FALSE);
+ h3_xfer_write_resp(cf, data, stream, (const char *)buf, buflen, FALSE);
- ngtcp2_conn_extend_max_offset(ctx->qconn, blen);
- stream->rx_offset += blen;
+ ngtcp2_conn_extend_max_offset(ctx->qconn, buflen);
+ stream->rx_offset += buflen;
if(stream->rx_offset_max < stream->rx_offset)
stream->rx_offset_max = stream->rx_offset;
CURL_TRC_CF(data, cf, "[%" PRId64 "] DATA len=%zu, rx win=%" PRIu64,
- stream->id, blen, stream->rx_offset_max - stream->rx_offset);
+ stream->id, buflen, stream->rx_offset_max - stream->rx_offset);
cf_ngtcp2_upd_rx_win(cf, data, stream);
return 0;
}
rc = nghttp3_conn_bind_qpack_streams(ctx->h3conn, qpack_enc_stream_id,
qpack_dec_stream_id);
if(rc) {
- failf(data, "error binding HTTP/3 qpack streams: %s",
- ngtcp2_strerror(rc));
+ failf(data, "error binding HTTP/3 qpack streams: %s", ngtcp2_strerror(rc));
return CURLE_QUIC_CONNECT_ERROR;
}
/* incoming data frames on the h3 stream */
static CURLcode cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
- char *buf, size_t blen, size_t *pnread)
+ char *buf, size_t buflen, size_t *pnread)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
(void)ctx;
(void)buf;
- NOVERBOSE((void)blen);
+ NOVERBOSE((void)buflen);
CF_DATA_SAVE(save, cf, data);
DEBUGASSERT(cf->connected);
if(ctx->tls_vrfy_result)
result = ctx->tls_vrfy_result;
denied:
- CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_recv(blen=%zu) -> %d, %zu",
- stream ? stream->id : -1, blen, result, *pnread);
+ CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_recv(buflen=%zu) -> %d, %zu",
+ stream ? stream->id : -1, buflen, result, *pnread);
CF_DATA_RESTORE(cf, save);
return result;
}
rc = ngtcp2_conn_open_bidi_stream(ctx->qconn, &sid, data);
if(rc) {
- failf(data, "can get bidi streams");
+ failf(data, "cannot open bidi streams");
result = CURLE_SEND_ERROR;
goto out;
}
return CURLE_OK;
}
if(result) {
- CURL_TRC_CF(data, cf, "ingress, recv from tunnel failed: %d",
- result);
+ CURL_TRC_CF(data, cf, "ingress, recv from tunnel failed: %d", result);
return result;
}
if(nread == 0) {
CURL_TRC_CF(data, cf, "SSL session from different ALPN, no early data");
}
else if(!scs->quic_tp || !scs->quic_tp_len) {
- CURL_TRC_CF(data, cf, "no 0RTT transport parameters, no early data, ");
+ CURL_TRC_CF(data, cf, "no 0RTT transport parameters, no early data");
}
else {
int rv;
/* Direct UDP socket - get local address for ngtcp2 */
ctx->q.local_addrlen = sizeof(ctx->q.local_addr);
rv = getsockname(ctx->q.sockfd, (struct sockaddr *)&ctx->q.local_addr,
- &ctx->q.local_addrlen);
+ &ctx->q.local_addrlen);
if(rv == -1)
return CURLE_QUIC_CONNECT_ERROR;
ngtcp2_addr_init(&ctx->connected_path.local,
- (struct sockaddr *)&ctx->q.local_addr,
- ctx->q.local_addrlen);
+ (struct sockaddr *)&ctx->q.local_addr,
+ ctx->q.local_addrlen);
ngtcp2_addr_init(&ctx->connected_path.remote,
- &sockaddr->curl_sa_addr, (socklen_t)sockaddr->addrlen);
+ &sockaddr->curl_sa_addr, (socklen_t)sockaddr->addrlen);
rc = ngtcp2_conn_client_new(&ctx->qconn, &ctx->dcid, &ctx->scid,
&ctx->connected_path,
}
#endif
-
-/* Do not leak this filter's call_data accessor in unity builds. */
-#undef CF_CTX_CALL_DATA