From fc5e1eb8e8f19bcf25037694415af7442144dd3e Mon Sep 17 00:00:00 2001 From: David Bar-On Date: Mon, 29 Apr 2024 10:26:13 +0300 Subject: [PATCH 1/2] Enhancement for issue 1078 - receive all TCP burst messages in one message --- src/iperf.h | 3 ++- src/iperf_api.c | 65 ++++++++++++++++++++++++++++++++++-------------- src/iperf_api.h | 3 +++ src/iperf_sctp.c | 4 +-- src/iperf_tcp.c | 6 ++--- src/iperf_udp.c | 4 +-- 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/iperf.h b/src/iperf.h index c1d839be1..b9fba0e15 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -146,7 +146,7 @@ struct iperf_settings { int domain; /* AF_INET or AF_INET6 */ int socket_bufsize; /* window size for TCP */ - int blksize; /* size of read/writes (-l) */ + int blksize; /* size of read/writes (-l); specific stream read size may be different */ iperf_size_t rate; /* target data rate for application pacing*/ iperf_size_t bitrate_limit; /* server's maximum allowed total data rate for all streams*/ double bitrate_limit_interval; /* interval for averaging total data rate */ @@ -190,6 +190,7 @@ struct iperf_stream int socket; int id; int sender; + int blksize; /* Same as Test blksize, except for send TCP read size may be extended by burst */ /* XXX: is settings just a pointer to the same struct in iperf_test? if not, should it be? */ struct iperf_settings *settings; /* pointer to structure settings */ diff --git a/src/iperf_api.c b/src/iperf_api.c index 139ab87fb..5c1e416f2 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -1935,12 +1935,7 @@ iperf_send_mt(struct iperf_stream *sp) int no_throttle_check; /* Can we do multisend mode? */ - if (test->settings->burst != 0) - multisend = test->settings->burst; - else if (test->settings->rate == 0) - multisend = test->multisend; - else - multisend = 1; /* nope */ + multisend = iperf_calc_burst_size(test); /* Should bitrate throttle be checked for every send */ no_throttle_check = test->settings->rate != 0 && test->settings->burst == 0; @@ -4355,7 +4350,7 @@ iperf_free_stream(struct iperf_stream *sp) struct iperf_interval_results *irp, *nirp; /* XXX: need to free interval list too! */ - munmap(sp->buffer, sp->test->settings->blksize); + munmap(sp->buffer, sp->blksize); close(sp->buffer_fd); if (sp->diskfile_fd >= 0) close(sp->diskfile_fd); @@ -4375,6 +4370,7 @@ iperf_new_stream(struct iperf_test *test, int s, int sender) { struct iperf_stream *sp; int ret = 0; + int multisend, i; char template[1024]; if (test->tmp_template) { @@ -4416,6 +4412,20 @@ iperf_new_stream(struct iperf_test *test, int s, int sender) return NULL; } + /* Set stream block size;TCP receives messages in multiple of burst size */ + sp->blksize = sp->settings->blksize; + if (test->protocol->id == Ptcp && !sender) { + multisend = iperf_calc_burst_size(test); + i = MAX_BLOCKSIZE / sp->blksize; + if (multisend > i) + multisend = i; + if (multisend > 1) + sp->blksize *= multisend; + if (test->debug) { + iperf_printf(test, "Stream %d TCP receive buffer size set to %d bytes (%d times of message length)\n", s, sp->blksize, multisend); + } + } + memset(sp->result, 0, sizeof(struct iperf_stream_result)); TAILQ_INIT(&sp->result->interval_results); @@ -4433,13 +4443,13 @@ iperf_new_stream(struct iperf_test *test, int s, int sender) free(sp); return NULL; } - if (ftruncate(sp->buffer_fd, test->settings->blksize) < 0) { + if (ftruncate(sp->buffer_fd, sp->blksize) < 0) { i_errno = IECREATESTREAM; free(sp->result); free(sp); return NULL; } - sp->buffer = (char *) mmap(NULL, test->settings->blksize, PROT_READ|PROT_WRITE, MAP_PRIVATE, sp->buffer_fd, 0); + sp->buffer = (char *) mmap(NULL, sp->blksize, PROT_READ|PROT_WRITE, MAP_PRIVATE, sp->buffer_fd, 0); if (sp->buffer == MAP_FAILED) { i_errno = IECREATESTREAM; free(sp->result); @@ -4458,7 +4468,7 @@ iperf_new_stream(struct iperf_test *test, int s, int sender) sp->diskfile_fd = open(test->diskfile_name, sender ? O_RDONLY : (O_WRONLY|O_CREAT|O_TRUNC), S_IRUSR|S_IWUSR); if (sp->diskfile_fd == -1) { i_errno = IEFILE; - munmap(sp->buffer, sp->test->settings->blksize); + munmap(sp->buffer, sp->blksize); free(sp->result); free(sp); return NULL; @@ -4472,13 +4482,13 @@ iperf_new_stream(struct iperf_test *test, int s, int sender) /* Initialize stream */ if (test->repeating_payload) - fill_with_repeating_pattern(sp->buffer, test->settings->blksize); + fill_with_repeating_pattern(sp->buffer, sp->blksize); else - ret = readentropy(sp->buffer, test->settings->blksize); + ret = readentropy(sp->buffer, sp->blksize); if ((ret < 0) || (iperf_init_stream(sp, test) < 0)) { close(sp->buffer_fd); - munmap(sp->buffer, sp->test->settings->blksize); + munmap(sp->buffer, sp->blksize); free(sp->result); free(sp); return NULL; @@ -4630,8 +4640,8 @@ diskfile_send(struct iperf_stream *sp) static int rtot; /* if needed, read enough data from the disk to fill up the buffer */ - if (sp->diskfile_left < sp->test->settings->blksize && !sp->test->done) { - r = read(sp->diskfile_fd, sp->buffer, sp->test->settings->blksize - + if (sp->diskfile_left < sp->blksize && !sp->test->done) { + r = read(sp->diskfile_fd, sp->buffer, sp->blksize - sp->diskfile_left); buffer_left += r; rtot += r; @@ -4641,7 +4651,7 @@ diskfile_send(struct iperf_stream *sp) // If the buffer doesn't contain a full buffer at this point, // adjust the size of the data to send. - if (buffer_left != sp->test->settings->blksize) { + if (buffer_left != sp->blksize) { if (sp->test->debug) printf("possible eof\n"); // setting data size to be sent, @@ -4679,12 +4689,12 @@ diskfile_send(struct iperf_stream *sp) * pass. */ sp->diskfile_left = buffer_left - r; - if (sp->diskfile_left && sp->diskfile_left < sp->test->settings->blksize) { + if (sp->diskfile_left && sp->diskfile_left < sp->blksize) { memcpy(sp->buffer, - sp->buffer + (sp->test->settings->blksize - sp->diskfile_left), + sp->buffer + (sp->blksize - sp->diskfile_left), sp->diskfile_left); if (sp->test->debug) - printf("Shifting %d bytes by %d\n", sp->diskfile_left, (sp->test->settings->blksize - sp->diskfile_left)); + printf("Shifting %d bytes by %d\n", sp->diskfile_left, (sp->blksize - sp->diskfile_left)); } return r; } @@ -5121,3 +5131,20 @@ iflush(struct iperf_test *test) return rc2; } + +// Calculates the sending busrt size for the test +int +iperf_calc_burst_size(struct iperf_test *test) +{ + register int multisend; + + /* Can we do multisend mode? */ + if (test->settings->burst != 0) + multisend = test->settings->burst; + else if (test->settings->rate == 0) + multisend = test->multisend; + else + multisend = 1; /* nope */ + + return multisend; +} \ No newline at end of file diff --git a/src/iperf_api.h b/src/iperf_api.h index d2bbdfe96..b17be428e 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -376,6 +376,9 @@ int iperf_clearaffinity(struct iperf_test *); int iperf_printf(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3))); int iflush(struct iperf_test *test); +/* Calculates the sending busrt size for the test */ +int iperf_calc_burst_size(struct iperf_test *test); + /* Error routines. */ void iperf_err(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3))); void iperf_errexit(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3),noreturn)); diff --git a/src/iperf_sctp.c b/src/iperf_sctp.c index 104083281..5b62e6138 100644 --- a/src/iperf_sctp.c +++ b/src/iperf_sctp.c @@ -60,7 +60,7 @@ iperf_sctp_recv(struct iperf_stream *sp) #if defined(HAVE_SCTP_H) int r; - r = Nread(sp->socket, sp->buffer, sp->settings->blksize, Psctp); + r = Nread(sp->socket, sp->buffer, sp->blksize, Psctp); if (r < 0) return r; @@ -92,7 +92,7 @@ iperf_sctp_send(struct iperf_stream *sp) #if defined(HAVE_SCTP_H) int r; - r = Nwrite(sp->socket, sp->buffer, sp->settings->blksize, Psctp); + r = Nwrite(sp->socket, sp->buffer, sp->blksize, Psctp); if (r < 0) return r; diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c index 71c40a6ea..84c365fdb 100644 --- a/src/iperf_tcp.c +++ b/src/iperf_tcp.c @@ -57,7 +57,7 @@ iperf_tcp_recv(struct iperf_stream *sp) { int r; - r = Nread(sp->socket, sp->buffer, sp->settings->blksize, Ptcp); + r = Nread(sp->socket, sp->buffer, sp->blksize, Ptcp); if (r < 0) return r; @@ -86,7 +86,7 @@ iperf_tcp_send(struct iperf_stream *sp) int r; if (!sp->pending_size) - sp->pending_size = sp->settings->blksize; + sp->pending_size = sp->blksize; if (sp->test->zerocopy) r = Nsendfile(sp->buffer_fd, sp->socket, sp->buffer, sp->pending_size); @@ -102,7 +102,7 @@ iperf_tcp_send(struct iperf_stream *sp) if (sp->test->debug_level >= DEBUG_LEVEL_DEBUG) printf("sent %d bytes of %d, pending %d, total %" PRIu64 "\n", - r, sp->settings->blksize, sp->pending_size, sp->result->bytes_sent); + r, sp->blksize, sp->pending_size, sp->result->bytes_sent); return r; } diff --git a/src/iperf_udp.c b/src/iperf_udp.c index a603236df..ecf1df6e7 100644 --- a/src/iperf_udp.c +++ b/src/iperf_udp.c @@ -57,7 +57,7 @@ iperf_udp_recv(struct iperf_stream *sp) uint32_t sec, usec; uint64_t pcount; int r; - int size = sp->settings->blksize; + int size = sp->blksize; int first_packet = 0; double transit = 0, d = 0; struct iperf_time sent_time, arrival_time, temp_time; @@ -250,7 +250,7 @@ iperf_udp_send(struct iperf_stream *sp) sp->result->bytes_sent_this_interval += r; if (sp->test->debug_level >= DEBUG_LEVEL_DEBUG) - printf("sent %d bytes of %d, total %" PRIu64 "\n", r, sp->settings->blksize, sp->result->bytes_sent); + printf("sent %d bytes of %d, total %" PRIu64 "\n", r, sp->blksize, sp->result->bytes_sent); return r; } From a5b1902dca54af748a9ebe824468e3104b4cf673 Mon Sep 17 00:00:00 2001 From: David Bar-On Date: Tue, 30 Apr 2024 23:11:42 +0300 Subject: [PATCH 2/2] Do NOT receive multiple blocks when -n, -k or --file are set --- src/iperf_api.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/iperf_api.c b/src/iperf_api.c index 5c1e416f2..9efb897c8 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -4412,9 +4412,11 @@ iperf_new_stream(struct iperf_test *test, int s, int sender) return NULL; } - /* Set stream block size;TCP receives messages in multiple of burst size */ + /* Set stream block size; TCP receives messages in multiple of burst size */ sp->blksize = sp->settings->blksize; - if (test->protocol->id == Ptcp && !sender) { + if (test->protocol->id == Ptcp && !sender && + sp->settings->bytes == 0 && sp->settings->blocks == 0 && sp->test->diskfile_name == (char*) 0) + { multisend = iperf_calc_burst_size(test); i = MAX_BLOCKSIZE / sp->blksize; if (multisend > i)