quic: remove conn->data use

Closes #6485
This commit is contained in:
Daniel Stenberg 2021-01-19 09:48:40 +01:00
parent 6fcf22654e
commit 2bdec0b363
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 79 additions and 82 deletions

View File

@ -887,7 +887,7 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
error = 0; error = 0;
#ifdef ENABLE_QUIC #ifdef ENABLE_QUIC
if(conn->transport == TRNSPRT_QUIC) { if(conn->transport == TRNSPRT_QUIC) {
result = Curl_quic_is_connected(conn, i, connected); result = Curl_quic_is_connected(data, conn, i, connected);
if(!result && *connected) { if(!result && *connected) {
/* use this socket from now on */ /* use this socket from now on */
conn->sock[sockindex] = conn->tempsock[i]; conn->sock[sockindex] = conn->tempsock[i];
@ -1024,8 +1024,8 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
hostname, conn->port, hostname, conn->port,
Curl_strerror(error, buffer, sizeof(buffer))); Curl_strerror(error, buffer, sizeof(buffer)));
Curl_quic_disconnect(conn, 0); Curl_quic_disconnect(data, conn, 0);
Curl_quic_disconnect(conn, 1); Curl_quic_disconnect(data, conn, 1);
#ifdef WSAETIMEDOUT #ifdef WSAETIMEDOUT
if(WSAETIMEDOUT == data->state.os_errno) if(WSAETIMEDOUT == data->state.os_errno)
@ -1280,7 +1280,7 @@ static CURLcode singleipconnect(struct Curl_easy *data,
else if(conn->transport == TRNSPRT_QUIC) { else if(conn->transport == TRNSPRT_QUIC) {
/* pass in 'sockfd' separately since it hasn't been put into the /* pass in 'sockfd' separately since it hasn't been put into the
tempsock array at this point */ tempsock array at this point */
result = Curl_quic_connect(conn, sockfd, tempindex, result = Curl_quic_connect(data, conn, sockfd, tempindex,
&addr.sa_addr, addr.addrlen); &addr.sa_addr, addr.addrlen);
if(result) if(result)
error = SOCKERRNO; error = SOCKERRNO;

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -35,25 +35,28 @@
#include "urldata.h" #include "urldata.h"
/* functions provided by the specific backends */ /* functions provided by the specific backends */
CURLcode Curl_quic_connect(struct connectdata *conn, CURLcode Curl_quic_connect(struct Curl_easy *data,
struct connectdata *conn,
curl_socket_t sockfd, curl_socket_t sockfd,
int sockindex, int sockindex,
const struct sockaddr *addr, const struct sockaddr *addr,
socklen_t addrlen); socklen_t addrlen);
CURLcode Curl_quic_is_connected(struct connectdata *conn, CURLcode Curl_quic_is_connected(struct Curl_easy *data,
struct connectdata *conn,
int sockindex, int sockindex,
bool *connected); bool *connected);
int Curl_quic_ver(char *p, size_t len); int Curl_quic_ver(char *p, size_t len);
CURLcode Curl_quic_done_sending(struct connectdata *conn); CURLcode Curl_quic_done_sending(struct Curl_easy *data);
void Curl_quic_done(struct Curl_easy *data, bool premature); void Curl_quic_done(struct Curl_easy *data, bool premature);
bool Curl_quic_data_pending(const struct Curl_easy *data); bool Curl_quic_data_pending(const struct Curl_easy *data);
void Curl_quic_disconnect(struct connectdata *conn, int tempindex); void Curl_quic_disconnect(struct Curl_easy *data,
struct connectdata *conn, int tempindex);
#else /* ENABLE_QUIC */ #else /* ENABLE_QUIC */
#define Curl_quic_done_sending(x) #define Curl_quic_done_sending(x)
#define Curl_quic_done(x,y) #define Curl_quic_done(x,y)
#define Curl_quic_data_pending(x) #define Curl_quic_data_pending(x)
#define Curl_quic_disconnect(x,y) #define Curl_quic_disconnect(x,y,z)
#endif /* !ENABLE_QUIC */ #endif /* !ENABLE_QUIC */
#endif /* HEADER_CURL_QUIC_H */ #endif /* HEADER_CURL_QUIC_H */

View File

@ -911,7 +911,7 @@ CURLcode Curl_done_sending(struct Curl_easy *data,
/* These functions should be moved into the handler struct! */ /* These functions should be moved into the handler struct! */
Curl_http2_done_sending(data, conn); Curl_http2_done_sending(data, conn);
Curl_quic_done_sending(conn); Curl_quic_done_sending(data);
if(conn->bits.rewindaftersend) { if(conn->bits.rewindaftersend) {
CURLcode result = Curl_readrewind(conn); CURLcode result = Curl_readrewind(conn);

View File

@ -87,7 +87,7 @@ struct h3out {
"+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1" "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1"
#endif #endif
static CURLcode ng_process_ingress(struct connectdata *conn, static CURLcode ng_process_ingress(struct Curl_easy *data,
curl_socket_t sockfd, curl_socket_t sockfd,
struct quicsocket *qs); struct quicsocket *qs);
static CURLcode ng_flush_egress(struct Curl_easy *data, int sockfd, static CURLcode ng_flush_egress(struct Curl_easy *data, int sockfd,
@ -556,10 +556,8 @@ cb_recv_crypto_data(ngtcp2_conn *tconn, ngtcp2_crypto_level crypto_level,
static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data) static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data)
{ {
struct quicsocket *qs = (struct quicsocket *)user_data; (void)user_data;
(void)tconn; (void)tconn;
infof(qs->conn->data, "QUIC handshake is completed\n");
return 0; return 0;
} }
@ -587,8 +585,6 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
nconsumed = nconsumed =
nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin); nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin);
if(nconsumed < 0) { if(nconsumed < 0) {
failf(qs->conn->data, "nghttp3_conn_read_stream returned error: %s",
nghttp3_strerror((int)nconsumed));
return NGTCP2_ERR_CALLBACK_FAILURE; return NGTCP2_ERR_CALLBACK_FAILURE;
} }
@ -616,8 +612,6 @@ cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id,
rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen); rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen);
if(rv != 0) { if(rv != 0) {
failf(qs->conn->data, "nghttp3_conn_add_ack_offset returned error: %s",
nghttp3_strerror(rv));
return NGTCP2_ERR_CALLBACK_FAILURE; return NGTCP2_ERR_CALLBACK_FAILURE;
} }
@ -637,8 +631,6 @@ static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id,
rv = nghttp3_conn_close_stream(qs->h3conn, stream_id, rv = nghttp3_conn_close_stream(qs->h3conn, stream_id,
app_error_code); app_error_code);
if(rv != 0) { if(rv != 0) {
failf(qs->conn->data, "nghttp3_conn_close_stream returned error: %s",
nghttp3_strerror(rv));
return NGTCP2_ERR_CALLBACK_FAILURE; return NGTCP2_ERR_CALLBACK_FAILURE;
} }
@ -658,8 +650,6 @@ static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id,
rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id); rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id);
if(rv != 0) { if(rv != 0) {
failf(qs->conn->data, "nghttp3_conn_reset_stream returned error: %s",
nghttp3_strerror(rv));
return NGTCP2_ERR_CALLBACK_FAILURE; return NGTCP2_ERR_CALLBACK_FAILURE;
} }
@ -689,8 +679,6 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id); rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id);
if(rv != 0) { if(rv != 0) {
failf(qs->conn->data, "nghttp3_conn_unblock_stream returned error: %s",
nghttp3_strerror(rv));
return NGTCP2_ERR_CALLBACK_FAILURE; return NGTCP2_ERR_CALLBACK_FAILURE;
} }
@ -701,16 +689,16 @@ static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
uint8_t *token, size_t cidlen, uint8_t *token, size_t cidlen,
void *user_data) void *user_data)
{ {
struct quicsocket *qs = (struct quicsocket *)user_data;
CURLcode result; CURLcode result;
(void)tconn; (void)tconn;
(void)user_data;
result = Curl_rand(qs->conn->data, cid->data, cidlen); result = Curl_rand(NULL, cid->data, cidlen);
if(result) if(result)
return NGTCP2_ERR_CALLBACK_FAILURE; return NGTCP2_ERR_CALLBACK_FAILURE;
cid->datalen = cidlen; cid->datalen = cidlen;
result = Curl_rand(qs->conn->data, token, NGTCP2_STATELESS_RESET_TOKENLEN); result = Curl_rand(NULL, token, NGTCP2_STATELESS_RESET_TOKENLEN);
if(result) if(result)
return NGTCP2_ERR_CALLBACK_FAILURE; return NGTCP2_ERR_CALLBACK_FAILURE;
@ -755,7 +743,8 @@ static ngtcp2_callbacks ng_callbacks = {
/* /*
* Might be called twice for happy eyeballs. * Might be called twice for happy eyeballs.
*/ */
CURLcode Curl_quic_connect(struct connectdata *conn, CURLcode Curl_quic_connect(struct Curl_easy *data,
struct connectdata *conn,
curl_socket_t sockfd, curl_socket_t sockfd,
int sockindex, int sockindex,
const struct sockaddr *addr, const struct sockaddr *addr,
@ -765,14 +754,13 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
int rv; int rv;
CURLcode result; CURLcode result;
ngtcp2_path path; /* TODO: this must be initialized properly */ ngtcp2_path path; /* TODO: this must be initialized properly */
struct Curl_easy *data = conn->data;
struct quicsocket *qs = &conn->hequic[sockindex]; struct quicsocket *qs = &conn->hequic[sockindex];
char ipbuf[40]; char ipbuf[40];
long port; long port;
int qfd; int qfd;
if(qs->conn) if(qs->conn)
Curl_quic_disconnect(conn, sockindex); Curl_quic_disconnect(data, conn, sockindex);
qs->conn = conn; qs->conn = conn;
/* extract the used address as a string */ /* extract the used address as a string */
@ -892,9 +880,11 @@ static void qs_disconnect(struct quicsocket *qs)
#endif #endif
} }
void Curl_quic_disconnect(struct connectdata *conn, void Curl_quic_disconnect(struct Curl_easy *data,
struct connectdata *conn,
int tempindex) int tempindex)
{ {
(void)data;
if(conn->transport == TRNSPRT_QUIC) if(conn->transport == TRNSPRT_QUIC)
qs_disconnect(&conn->hequic[tempindex]); qs_disconnect(&conn->hequic[tempindex]);
} }
@ -904,9 +894,8 @@ static CURLcode ng_disconnect(struct Curl_easy *data,
bool dead_connection) bool dead_connection)
{ {
(void)dead_connection; (void)dead_connection;
(void)data; Curl_quic_disconnect(data, conn, 0);
Curl_quic_disconnect(conn, 0); Curl_quic_disconnect(data, conn, 1);
Curl_quic_disconnect(conn, 1);
return CURLE_OK; return CURLE_OK;
} }
@ -1161,7 +1150,6 @@ static int init_ngh3_conn(struct quicsocket *qs)
int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id; int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id;
if(ngtcp2_conn_get_max_local_streams_uni(qs->qconn) < 3) { if(ngtcp2_conn_get_max_local_streams_uni(qs->qconn) < 3) {
failf(qs->conn->data, "too few available QUIC streams");
return CURLE_QUIC_CONNECT_ERROR; return CURLE_QUIC_CONNECT_ERROR;
} }
@ -1257,7 +1245,7 @@ static ssize_t ngh3_stream_recv(struct Curl_easy *data,
as possible to the receive buffer before receiving more */ as possible to the receive buffer before receiving more */
drain_overflow_buffer(stream); drain_overflow_buffer(stream);
if(ng_process_ingress(conn, sockfd, qs)) { if(ng_process_ingress(data, sockfd, qs)) {
*curlcode = CURLE_RECV_ERROR; *curlcode = CURLE_RECV_ERROR;
return -1; return -1;
} }
@ -1669,13 +1657,13 @@ static void ng_has_connected(struct connectdata *conn, int tempindex)
conn->httpversion = 30; conn->httpversion = 30;
conn->bundle->multiuse = BUNDLE_MULTIPLEX; conn->bundle->multiuse = BUNDLE_MULTIPLEX;
conn->quic = &conn->hequic[tempindex]; conn->quic = &conn->hequic[tempindex];
DEBUGF(infof(conn->data, "ngtcp2 established connection!\n"));
} }
/* /*
* There can be multiple connection attempts going on in parallel. * There can be multiple connection attempts going on in parallel.
*/ */
CURLcode Curl_quic_is_connected(struct connectdata *conn, CURLcode Curl_quic_is_connected(struct Curl_easy *data,
struct connectdata *conn,
int sockindex, int sockindex,
bool *done) bool *done)
{ {
@ -1683,11 +1671,11 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn,
struct quicsocket *qs = &conn->hequic[sockindex]; struct quicsocket *qs = &conn->hequic[sockindex];
curl_socket_t sockfd = conn->tempsock[sockindex]; curl_socket_t sockfd = conn->tempsock[sockindex];
result = ng_process_ingress(conn, sockfd, qs); result = ng_process_ingress(data, sockfd, qs);
if(result) if(result)
goto error; goto error;
result = ng_flush_egress(conn->data, sockfd, qs); result = ng_flush_egress(data, sockfd, qs);
if(result) if(result)
goto error; goto error;
@ -1703,7 +1691,7 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn,
} }
static CURLcode ng_process_ingress(struct connectdata *conn, static CURLcode ng_process_ingress(struct Curl_easy *data,
curl_socket_t sockfd, curl_socket_t sockfd,
struct quicsocket *qs) struct quicsocket *qs)
{ {
@ -1728,7 +1716,7 @@ static CURLcode ng_process_ingress(struct connectdata *conn,
if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK)
break; break;
failf(conn->data, "ngtcp2: recvfrom() unexpectedly returned %zd", recvd); failf(data, "ngtcp2: recvfrom() unexpectedly returned %zd", recvd);
return CURLE_RECV_ERROR; return CURLE_RECV_ERROR;
} }
@ -1894,11 +1882,13 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
/* /*
* Called from transfer.c:done_sending when we stop HTTP/3 uploading. * Called from transfer.c:done_sending when we stop HTTP/3 uploading.
*/ */
CURLcode Curl_quic_done_sending(struct connectdata *conn) CURLcode Curl_quic_done_sending(struct Curl_easy *data)
{ {
struct connectdata *conn = data->conn;
DEBUGASSERT(conn);
if(conn->handler == &Curl_handler_http3) { if(conn->handler == &Curl_handler_http3) {
/* only for HTTP/3 transfers */ /* only for HTTP/3 transfers */
struct HTTP *stream = conn->data->req.p.http; struct HTTP *stream = data->req.p.http;
struct quicsocket *qs = conn->quic; struct quicsocket *qs = conn->quic;
stream->upload_done = TRUE; stream->upload_done = TRUE;
(void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id); (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id);

View File

@ -53,14 +53,14 @@
#define QUIC_MAX_DATA (1*1024*1024) #define QUIC_MAX_DATA (1*1024*1024)
#define QUIC_IDLE_TIMEOUT (60 * 1000) /* milliseconds */ #define QUIC_IDLE_TIMEOUT (60 * 1000) /* milliseconds */
static CURLcode process_ingress(struct connectdata *conn, static CURLcode process_ingress(struct Curl_easy *data,
curl_socket_t sockfd, curl_socket_t sockfd,
struct quicsocket *qs); struct quicsocket *qs);
static CURLcode flush_egress(struct connectdata *conn, curl_socket_t sockfd, static CURLcode flush_egress(struct Curl_easy *data, curl_socket_t sockfd,
struct quicsocket *qs); struct quicsocket *qs);
static CURLcode http_request(struct connectdata *conn, const void *mem, static CURLcode http_request(struct Curl_easy *data, const void *mem,
size_t len); size_t len);
static Curl_recv h3_stream_recv; static Curl_recv h3_stream_recv;
static Curl_send h3_stream_send; static Curl_send h3_stream_send;
@ -84,14 +84,17 @@ static int quiche_getsock(struct Curl_easy *data,
return bitmap; return bitmap;
} }
static CURLcode qs_disconnect(struct connectdata *conn, static CURLcode qs_disconnect(struct Curl_easy *data,
struct connectdata *conn,
struct quicsocket *qs) struct quicsocket *qs)
{ {
DEBUGASSERT(conn);
DEBUGASSERT(qs);
if(qs->conn) { if(qs->conn) {
(void)quiche_conn_close(qs->conn, TRUE, 0, NULL, 0); (void)quiche_conn_close(qs->conn, TRUE, 0, NULL, 0);
/* flushing the egress is not a failsafe way to deliver all the /* flushing the egress is not a failsafe way to deliver all the
outstanding packets, but we also don't want to get stuck here... */ outstanding packets, but we also don't want to get stuck here... */
(void)flush_egress(conn, qs->sockfd, qs); (void)flush_egress(data, qs->sockfd, qs);
quiche_conn_free(qs->conn); quiche_conn_free(qs->conn);
qs->conn = NULL; qs->conn = NULL;
} }
@ -111,16 +114,16 @@ static CURLcode quiche_disconnect(struct Curl_easy *data,
bool dead_connection) bool dead_connection)
{ {
struct quicsocket *qs = conn->quic; struct quicsocket *qs = conn->quic;
(void)data;
(void)dead_connection; (void)dead_connection;
return qs_disconnect(conn, qs); return qs_disconnect(data, conn, qs);
} }
void Curl_quic_disconnect(struct connectdata *conn, void Curl_quic_disconnect(struct Curl_easy *data,
struct connectdata *conn,
int tempindex) int tempindex)
{ {
if(conn->transport == TRNSPRT_QUIC) if(conn->transport == TRNSPRT_QUIC)
qs_disconnect(conn, &conn->hequic[tempindex]); qs_disconnect(data, conn, &conn->hequic[tempindex]);
} }
static unsigned int quiche_conncheck(struct Curl_easy *data, static unsigned int quiche_conncheck(struct Curl_easy *data,
@ -170,13 +173,13 @@ static void quiche_debug_log(const char *line, void *argp)
} }
#endif #endif
CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd, CURLcode Curl_quic_connect(struct Curl_easy *data,
struct connectdata *conn, curl_socket_t sockfd,
int sockindex, int sockindex,
const struct sockaddr *addr, socklen_t addrlen) const struct sockaddr *addr, socklen_t addrlen)
{ {
CURLcode result; CURLcode result;
struct quicsocket *qs = &conn->hequic[sockindex]; struct quicsocket *qs = &conn->hequic[sockindex];
struct Curl_easy *data = conn->data;
char *keylog_file = NULL; char *keylog_file = NULL;
#ifdef DEBUG_QUICHE #ifdef DEBUG_QUICHE
@ -242,7 +245,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
} }
#endif #endif
result = flush_egress(conn, sockfd, qs); result = flush_egress(data, sockfd, qs);
if(result) if(result)
return result; return result;
@ -319,38 +322,39 @@ static CURLcode quiche_has_connected(struct connectdata *conn,
/* /*
* This function gets polled to check if this QUIC connection has connected. * This function gets polled to check if this QUIC connection has connected.
*/ */
CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex, CURLcode Curl_quic_is_connected(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
bool *done) bool *done)
{ {
CURLcode result; CURLcode result;
struct quicsocket *qs = &conn->hequic[sockindex]; struct quicsocket *qs = &conn->hequic[sockindex];
curl_socket_t sockfd = conn->tempsock[sockindex]; curl_socket_t sockfd = conn->tempsock[sockindex];
result = process_ingress(conn, sockfd, qs); result = process_ingress(data, sockfd, qs);
if(result) if(result)
goto error; goto error;
result = flush_egress(conn, sockfd, qs); result = flush_egress(data, sockfd, qs);
if(result) if(result)
goto error; goto error;
if(quiche_conn_is_established(qs->conn)) { if(quiche_conn_is_established(qs->conn)) {
*done = TRUE; *done = TRUE;
result = quiche_has_connected(conn, 0, sockindex); result = quiche_has_connected(conn, 0, sockindex);
DEBUGF(infof(conn->data, "quiche established connection!\n")); DEBUGF(infof(data, "quiche established connection!\n"));
} }
return result; return result;
error: error:
qs_disconnect(conn, qs); qs_disconnect(data, conn, qs);
return result; return result;
} }
static CURLcode process_ingress(struct connectdata *conn, int sockfd, static CURLcode process_ingress(struct Curl_easy *data, int sockfd,
struct quicsocket *qs) struct quicsocket *qs)
{ {
ssize_t recvd; ssize_t recvd;
struct Curl_easy *data = conn->data;
uint8_t *buf = (uint8_t *)data->state.buffer; uint8_t *buf = (uint8_t *)data->state.buffer;
size_t bufsize = data->set.buffer_size; size_t bufsize = data->set.buffer_size;
@ -363,7 +367,7 @@ static CURLcode process_ingress(struct connectdata *conn, int sockfd,
break; break;
if(recvd < 0) { if(recvd < 0) {
failf(conn->data, "quiche: recv() unexpectedly returned %zd " failf(data, "quiche: recv() unexpectedly returned %zd "
"(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd); "(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd);
return CURLE_RECV_ERROR; return CURLE_RECV_ERROR;
} }
@ -373,7 +377,7 @@ static CURLcode process_ingress(struct connectdata *conn, int sockfd,
break; break;
if(recvd < 0) { if(recvd < 0) {
failf(conn->data, "quiche_conn_recv() == %zd", recvd); failf(data, "quiche_conn_recv() == %zd", recvd);
return CURLE_RECV_ERROR; return CURLE_RECV_ERROR;
} }
} while(1); } while(1);
@ -385,7 +389,7 @@ static CURLcode process_ingress(struct connectdata *conn, int sockfd,
* flush_egress drains the buffers and sends off data. * flush_egress drains the buffers and sends off data.
* Calls failf() on errors. * Calls failf() on errors.
*/ */
static CURLcode flush_egress(struct connectdata *conn, int sockfd, static CURLcode flush_egress(struct Curl_easy *data, int sockfd,
struct quicsocket *qs) struct quicsocket *qs)
{ {
ssize_t sent; ssize_t sent;
@ -398,14 +402,13 @@ static CURLcode flush_egress(struct connectdata *conn, int sockfd,
break; break;
if(sent < 0) { if(sent < 0) {
failf(conn->data, "quiche_conn_send returned %zd", failf(data, "quiche_conn_send returned %zd", sent);
sent);
return CURLE_SEND_ERROR; return CURLE_SEND_ERROR;
} }
sent = send(sockfd, out, sent, 0); sent = send(sockfd, out, sent, 0);
if(sent < 0) { if(sent < 0) {
failf(conn->data, "send() returned %zd", sent); failf(data, "send() returned %zd", sent);
return CURLE_SEND_ERROR; return CURLE_SEND_ERROR;
} }
} while(1); } while(1);
@ -414,7 +417,7 @@ static CURLcode flush_egress(struct connectdata *conn, int sockfd,
timeout_ns = quiche_conn_timeout_as_nanos(qs->conn); timeout_ns = quiche_conn_timeout_as_nanos(qs->conn);
if(timeout_ns) if(timeout_ns)
/* expire uses milliseconds */ /* expire uses milliseconds */
Curl_expire(conn->data, (timeout_ns + 999999) / 1000000, EXPIRE_QUIC); Curl_expire(data, (timeout_ns + 999999) / 1000000, EXPIRE_QUIC);
return CURLE_OK; return CURLE_OK;
} }
@ -471,7 +474,7 @@ static ssize_t h3_stream_recv(struct Curl_easy *data,
headers.destlen = buffersize; headers.destlen = buffersize;
headers.nlen = 0; headers.nlen = 0;
if(process_ingress(conn, sockfd, qs)) { if(process_ingress(data, sockfd, qs)) {
infof(data, "h3_stream_recv returns on ingress\n"); infof(data, "h3_stream_recv returns on ingress\n");
*curlcode = CURLE_RECV_ERROR; *curlcode = CURLE_RECV_ERROR;
return -1; return -1;
@ -531,7 +534,7 @@ static ssize_t h3_stream_recv(struct Curl_easy *data,
quiche_h3_event_free(ev); quiche_h3_event_free(ev);
} }
if(flush_egress(conn, sockfd, qs)) { if(flush_egress(data, sockfd, qs)) {
*curlcode = CURLE_SEND_ERROR; *curlcode = CURLE_SEND_ERROR;
return -1; return -1;
} }
@ -558,7 +561,7 @@ static ssize_t h3_stream_send(struct Curl_easy *data,
struct HTTP *stream = data->req.p.http; struct HTTP *stream = data->req.p.http;
if(!stream->h3req) { if(!stream->h3req) {
CURLcode result = http_request(conn, mem, len); CURLcode result = http_request(data, mem, len);
if(result) { if(result) {
*curlcode = CURLE_SEND_ERROR; *curlcode = CURLE_SEND_ERROR;
return -1; return -1;
@ -566,8 +569,7 @@ static ssize_t h3_stream_send(struct Curl_easy *data,
sent = len; sent = len;
} }
else { else {
H3BUGF(infof(conn->data, "Pass on %zd body bytes to quiche\n", H3BUGF(infof(data, "Pass on %zd body bytes to quiche\n", len));
len));
sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id, sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id,
(uint8_t *)mem, len, FALSE); (uint8_t *)mem, len, FALSE);
if(sent < 0) { if(sent < 0) {
@ -576,7 +578,7 @@ static ssize_t h3_stream_send(struct Curl_easy *data,
} }
} }
if(flush_egress(conn, sockfd, qs)) { if(flush_egress(data, sockfd, qs)) {
*curlcode = CURLE_SEND_ERROR; *curlcode = CURLE_SEND_ERROR;
return -1; return -1;
} }
@ -598,12 +600,13 @@ int Curl_quic_ver(char *p, size_t len)
field list. */ field list. */
#define AUTHORITY_DST_IDX 3 #define AUTHORITY_DST_IDX 3
static CURLcode http_request(struct connectdata *conn, const void *mem, static CURLcode http_request(struct Curl_easy *data, const void *mem,
size_t len) size_t len)
{ {
/* /*
*/ */
struct HTTP *stream = conn->data->req.p.http; struct connectdata *conn = data->conn;
struct HTTP *stream = data->req.p.http;
size_t nheader; size_t nheader;
size_t i; size_t i;
size_t authority_idx; size_t authority_idx;
@ -613,7 +616,6 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
quiche_h3_header *nva = NULL; quiche_h3_header *nva = NULL;
struct quicsocket *qs = conn->quic; struct quicsocket *qs = conn->quic;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
stream->h3req = TRUE; /* senf off! */ stream->h3req = TRUE; /* senf off! */
@ -826,12 +828,14 @@ fail:
/* /*
* Called from transfer.c:done_sending when we stop HTTP/3 uploading. * Called from transfer.c:done_sending when we stop HTTP/3 uploading.
*/ */
CURLcode Curl_quic_done_sending(struct connectdata *conn) CURLcode Curl_quic_done_sending(struct Curl_easy *data)
{ {
struct connectdata *conn = data->conn;
DEBUGASSERT(conn);
if(conn->handler == &Curl_handler_http3) { if(conn->handler == &Curl_handler_http3) {
/* only for HTTP/3 transfers */ /* only for HTTP/3 transfers */
ssize_t sent; ssize_t sent;
struct HTTP *stream = conn->data->req.p.http; struct HTTP *stream = data->req.p.http;
struct quicsocket *qs = conn->quic; struct quicsocket *qs = conn->quic;
stream->upload_done = TRUE; stream->upload_done = TRUE;
sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id, sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id,