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
This commit is contained in:
Stefan Eissing 2023-10-05 10:05:12 +02:00 committed by Daniel Stenberg
parent ba1e559bd8
commit b9c78eeac1
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -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);