From: Stefan Eissing Date: Thu, 5 Oct 2023 08:05:12 +0000 (+0200) Subject: cf-socket: simulate slow/blocked receives in debug X-Git-Tag: curl-8_4_0~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b9c78eeac122f4d6df3886806935858292e1128d;p=thirdparty%2Fcurl.git cf-socket: simulate slow/blocked receives in debug add 2 env variables for non-UDP sockets: 1. CURL_DBG_SOCK_RBLOCK: percentage of receive calls that randomly should return EAGAIN 2. CURL_DBG_SOCK_RMAX: max amount of bytes read from socket Closes #12035 --- diff --git a/lib/cf-socket.c b/lib/cf-socket.c index effe6e649d..ce3f9e9437 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -781,6 +781,8 @@ struct cf_socket_ctx { #ifdef DEBUGBUILD int wblock_percent; /* percent of writes doing EAGAIN */ int wpartial_percent; /* percent of bytes written in send */ + int rblock_percent; /* percent of reads doing EAGAIN */ + size_t recv_max; /* max enforced read size */ #endif BIT(got_first_byte); /* if first byte was received */ BIT(accepted); /* socket was accepted, not connected */ @@ -811,6 +813,18 @@ static void cf_socket_ctx_init(struct cf_socket_ctx *ctx, if(l >= 0 && l <= 100) ctx->wpartial_percent = (int)l; } + p = getenv("CURL_DBG_SOCK_RBLOCK"); + if(p) { + long l = strtol(p, NULL, 10); + if(l >= 0 && l <= 100) + ctx->rblock_percent = (int)l; + } + p = getenv("CURL_DBG_SOCK_RMAX"); + if(p) { + long l = strtol(p, NULL, 10); + if(l >= 0) + ctx->recv_max = (size_t)l; + } } #endif } @@ -1358,6 +1372,27 @@ static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, fdsave = cf->conn->sock[cf->sockindex]; cf->conn->sock[cf->sockindex] = ctx->sock; +#ifdef DEBUGBUILD + /* simulate network blocking/partial reads */ + if(cf->cft != &Curl_cft_udp && ctx->rblock_percent > 0) { + unsigned char c; + Curl_rand(data, &c, 1); + if(c >= ((100-ctx->rblock_percent)*256/100)) { + CURL_TRC_CF(data, cf, "recv(len=%zu) SIMULATE EWOULDBLOCK", len); + *err = CURLE_AGAIN; + nread = -1; + cf->conn->sock[cf->sockindex] = fdsave; + return nread; + } + } + if(cf->cft != &Curl_cft_udp && ctx->recv_max && ctx->recv_max < len) { + size_t orig_len = len; + len = ctx->recv_max; + CURL_TRC_CF(data, cf, "recv(len=%zu) SIMULATE max read of %zu bytes", + orig_len, len); + } +#endif + if(ctx->buffer_recv && !Curl_bufq_is_empty(&ctx->recvbuf)) { CURL_TRC_CF(data, cf, "recv from buffer"); nread = Curl_bufq_read(&ctx->recvbuf, (unsigned char *)buf, len, err);