diff options
Diffstat (limited to 'lib/vquic/vquic.c')
-rw-r--r-- | lib/vquic/vquic.c | 88 |
1 files changed, 59 insertions, 29 deletions
diff --git a/lib/vquic/vquic.c b/lib/vquic/vquic.c index 399de0b..9a1a1bb 100644 --- a/lib/vquic/vquic.c +++ b/lib/vquic/vquic.c @@ -43,12 +43,14 @@ #include "bufq.h" #include "dynbuf.h" #include "cfilters.h" -#include "curl_log.h" +#include "curl_trc.h" #include "curl_msh3.h" #include "curl_ngtcp2.h" #include "curl_quiche.h" +#include "rand.h" #include "vquic.h" #include "vquic_int.h" +#include "strerror.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -88,6 +90,16 @@ CURLcode vquic_ctx_init(struct cf_quic_ctx *qctx) #else qctx->no_gso = TRUE; #endif +#ifdef DEBUGBUILD + { + char *p = getenv("CURL_DBG_QUIC_WBLOCK"); + if(p) { + long l = strtol(p, NULL, 10); + if(l >= 0 && l <= 100) + qctx->wblock_percent = (int)l; + } + } +#endif return CURLE_OK; } @@ -230,6 +242,17 @@ static CURLcode vquic_send_packets(struct Curl_cfilter *cf, const uint8_t *pkt, size_t pktlen, size_t gsolen, size_t *psent) { +#ifdef DEBUGBUILD + /* simulate network blocking/partial writes */ + if(qctx->wblock_percent > 0) { + unsigned char c; + Curl_rand(data, &c, 1); + if(c >= ((100-qctx->wblock_percent)*256/100)) { + CURL_TRC_CF(data, cf, "vquic_flush() simulate EWOULDBLOCK"); + return CURLE_AGAIN; + } + } +#endif if(qctx->no_gso && pktlen > gsolen) { return send_packet_no_gso(cf, data, qctx, pkt, pktlen, gsolen, psent); } @@ -253,11 +276,9 @@ CURLcode vquic_flush(struct Curl_cfilter *cf, struct Curl_easy *data, blen = qctx->split_len; } - DEBUGF(LOG_CF(data, cf, "vquic_send(len=%zu, gso=%zu)", - blen, gsolen)); result = vquic_send_packets(cf, data, qctx, buf, blen, gsolen, &sent); - DEBUGF(LOG_CF(data, cf, "vquic_send(len=%zu, gso=%zu) -> %d, sent=%zu", - blen, gsolen, result, sent)); + CURL_TRC_CF(data, cf, "vquic_send(len=%zu, gso=%zu) -> %d, sent=%zu", + blen, gsolen, result, sent); if(result) { if(result == CURLE_AGAIN) { Curl_bufq_skip(&qctx->sendbuf, sent); @@ -288,9 +309,9 @@ CURLcode vquic_send_tail_split(struct Curl_cfilter *cf, struct Curl_easy *data, qctx->split_len = Curl_bufq_len(&qctx->sendbuf) - tail_len; qctx->split_gsolen = gsolen; qctx->gsolen = tail_gsolen; - DEBUGF(LOG_CF(data, cf, "vquic_send_tail_split: [%zu gso=%zu][%zu gso=%zu]", - qctx->split_len, qctx->split_gsolen, - tail_len, qctx->gsolen)); + CURL_TRC_CF(data, cf, "vquic_send_tail_split: [%zu gso=%zu][%zu gso=%zu]", + qctx->split_len, qctx->split_gsolen, + tail_len, qctx->gsolen); return vquic_flush(cf, data, qctx); } @@ -308,6 +329,7 @@ static CURLcode recvmmsg_packets(struct Curl_cfilter *cf, struct sockaddr_storage remote_addr[MMSG_NUM]; size_t total_nread, pkts; int mcount, i, n; + char errstr[STRERROR_LEN]; CURLcode result = CURLE_OK; DEBUGASSERT(max_pkts > 0); @@ -330,12 +352,12 @@ static CURLcode recvmmsg_packets(struct Curl_cfilter *cf, ; if(mcount == -1) { if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - DEBUGF(LOG_CF(data, cf, "ingress, recvmmsg -> EAGAIN")); + CURL_TRC_CF(data, cf, "ingress, recvmmsg -> EAGAIN"); goto out; } if(!cf->connected && SOCKERRNO == ECONNREFUSED) { - const char *r_ip; - int r_port; + const char *r_ip = NULL; + int r_port = 0; Curl_cf_socket_peek(cf->next, data, NULL, NULL, &r_ip, &r_port, NULL, NULL); failf(data, "QUIC: connection to %s port %u refused", @@ -343,13 +365,14 @@ static CURLcode recvmmsg_packets(struct Curl_cfilter *cf, result = CURLE_COULDNT_CONNECT; goto out; } - failf(data, "QUIC: recvmsg() unexpectedly returned %d (errno=%d)", - mcount, SOCKERRNO); + Curl_strerror(SOCKERRNO, errstr, sizeof(errstr)); + failf(data, "QUIC: recvmsg() unexpectedly returned %d (errno=%d; %s)", + mcount, SOCKERRNO, errstr); result = CURLE_RECV_ERROR; goto out; } - DEBUGF(LOG_CF(data, cf, "recvmmsg() -> %d packets", mcount)); + CURL_TRC_CF(data, cf, "recvmmsg() -> %d packets", mcount); pkts += mcount; for(i = 0; i < mcount; ++i) { total_nread += mmsg[i].msg_len; @@ -362,8 +385,9 @@ static CURLcode recvmmsg_packets(struct Curl_cfilter *cf, } out: - DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d", - pkts, total_nread, result)); + if(total_nread || result) + CURL_TRC_CF(data, cf, "recvd %zu packets with %zu bytes -> %d", + pkts, total_nread, result); return result; } @@ -380,6 +404,7 @@ static CURLcode recvmsg_packets(struct Curl_cfilter *cf, struct sockaddr_storage remote_addr; size_t total_nread, pkts; ssize_t nread; + char errstr[STRERROR_LEN]; CURLcode result = CURLE_OK; msg_iov.iov_base = buf; @@ -401,8 +426,8 @@ static CURLcode recvmsg_packets(struct Curl_cfilter *cf, goto out; } if(!cf->connected && SOCKERRNO == ECONNREFUSED) { - const char *r_ip; - int r_port; + const char *r_ip = NULL; + int r_port = 0; Curl_cf_socket_peek(cf->next, data, NULL, NULL, &r_ip, &r_port, NULL, NULL); failf(data, "QUIC: connection to %s port %u refused", @@ -410,8 +435,9 @@ static CURLcode recvmsg_packets(struct Curl_cfilter *cf, result = CURLE_COULDNT_CONNECT; goto out; } - failf(data, "QUIC: recvmsg() unexpectedly returned %zd (errno=%d)", - nread, SOCKERRNO); + Curl_strerror(SOCKERRNO, errstr, sizeof(errstr)); + failf(data, "QUIC: recvmsg() unexpectedly returned %zd (errno=%d; %s)", + nread, SOCKERRNO, errstr); result = CURLE_RECV_ERROR; goto out; } @@ -425,8 +451,9 @@ static CURLcode recvmsg_packets(struct Curl_cfilter *cf, } out: - DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d", - pkts, total_nread, result)); + if(total_nread || result) + CURL_TRC_CF(data, cf, "recvd %zu packets with %zu bytes -> %d", + pkts, total_nread, result); return result; } @@ -443,6 +470,7 @@ static CURLcode recvfrom_packets(struct Curl_cfilter *cf, socklen_t remote_addrlen = sizeof(remote_addr); size_t total_nread, pkts; ssize_t nread; + char errstr[STRERROR_LEN]; CURLcode result = CURLE_OK; DEBUGASSERT(max_pkts > 0); @@ -454,12 +482,12 @@ static CURLcode recvfrom_packets(struct Curl_cfilter *cf, ; if(nread == -1) { if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - DEBUGF(LOG_CF(data, cf, "ingress, recvfrom -> EAGAIN")); + CURL_TRC_CF(data, cf, "ingress, recvfrom -> EAGAIN"); goto out; } if(!cf->connected && SOCKERRNO == ECONNREFUSED) { - const char *r_ip; - int r_port; + const char *r_ip = NULL; + int r_port = 0; Curl_cf_socket_peek(cf->next, data, NULL, NULL, &r_ip, &r_port, NULL, NULL); failf(data, "QUIC: connection to %s port %u refused", @@ -467,8 +495,9 @@ static CURLcode recvfrom_packets(struct Curl_cfilter *cf, result = CURLE_COULDNT_CONNECT; goto out; } - failf(data, "QUIC: recvfrom() unexpectedly returned %zd (errno=%d)", - nread, SOCKERRNO); + Curl_strerror(SOCKERRNO, errstr, sizeof(errstr)); + failf(data, "QUIC: recvfrom() unexpectedly returned %zd (errno=%d; %s)", + nread, SOCKERRNO, errstr); result = CURLE_RECV_ERROR; goto out; } @@ -482,8 +511,9 @@ static CURLcode recvfrom_packets(struct Curl_cfilter *cf, } out: - DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d", - pkts, total_nread, result)); + if(total_nread || result) + CURL_TRC_CF(data, cf, "recvd %zu packets with %zu bytes -> %d", + pkts, total_nread, result); return result; } #endif /* !HAVE_SENDMMSG && !HAVE_SENDMSG */ |