Skip to content

Commit

Permalink
Merge pull request #1536 from davidBar-On/issue-1534-packet-count-ove…
Browse files Browse the repository at this point in the history
…rflow

Prevent UDP packet count and operations overflow
  • Loading branch information
bmah888 authored Jul 3, 2023
2 parents 1583601 + dfe0ec5 commit c2fe76c
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 35 deletions.
28 changes: 14 additions & 14 deletions src/iperf.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ struct iperf_interval_results
float interval_duration;

/* for UDP */
int interval_packet_count;
int interval_outoforder_packets;
int interval_cnt_error;
int packet_count;
int64_t interval_packet_count;
int64_t interval_outoforder_packets;
int64_t interval_cnt_error;
int64_t packet_count;
double jitter;
int outoforder_packets;
int cnt_error;
int64_t outoforder_packets;
int64_t cnt_error;

int omitted;
#if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \
Expand Down Expand Up @@ -199,16 +199,16 @@ struct iperf_stream
* for udp measurements - This can be a structure outside stream, and
* stream can have a pointer to this
*/
int packet_count;
int peer_packet_count;
int peer_omitted_packet_count;
int omitted_packet_count;
int64_t packet_count;
int64_t peer_packet_count;
int64_t peer_omitted_packet_count;
int64_t omitted_packet_count;
double jitter;
double prev_transit;
int outoforder_packets;
int omitted_outoforder_packets;
int cnt_error;
int omitted_cnt_error;
int64_t outoforder_packets;
int64_t omitted_outoforder_packets;
int64_t cnt_error;
int64_t omitted_cnt_error;
uint64_t target;

struct sockaddr_storage local_addr;
Expand Down
29 changes: 15 additions & 14 deletions src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2472,7 +2472,8 @@ get_results(struct iperf_test *test)
cJSON *j_omitted_packets;
cJSON *j_server_output;
cJSON *j_start_time, *j_end_time;
int sid, cerror, pcount, omitted_cerror, omitted_pcount;
int sid;
int64_t cerror, pcount, omitted_cerror, omitted_pcount;
double jitter;
iperf_size_t bytes_transferred;
int retransmits;
Expand Down Expand Up @@ -3437,7 +3438,7 @@ iperf_print_intermediate(struct iperf_test *test)
int retransmits = 0;
double start_time, end_time;

int total_packets = 0, lost_packets = 0;
int64_t total_packets = 0, lost_packets = 0;
double avg_jitter = 0.0, lost_percent;
int stream_must_be_sender = current_mode * current_mode;

Expand Down Expand Up @@ -3619,11 +3620,11 @@ iperf_print_results(struct iperf_test *test)

for (current_mode = lower_mode; current_mode <= upper_mode; ++current_mode) {
cJSON *json_summary_stream = NULL;
int total_retransmits = 0;
int total_packets = 0, lost_packets = 0;
int sender_packet_count = 0, receiver_packet_count = 0; /* for this stream, this interval */
int sender_omitted_packet_count = 0, receiver_omitted_packet_count = 0; /* for this stream, this interval */
int sender_total_packets = 0, receiver_total_packets = 0; /* running total */
int64_t total_retransmits = 0;
int64_t total_packets = 0, lost_packets = 0;
int64_t sender_packet_count = 0, receiver_packet_count = 0; /* for this stream, this interval */
int64_t sender_omitted_packet_count = 0, receiver_omitted_packet_count = 0; /* for this stream, this interval */
int64_t sender_total_packets = 0, receiver_total_packets = 0; /* running total */
char ubuf[UNIT_LEN];
char nbuf[UNIT_LEN];
struct stat sb;
Expand Down Expand Up @@ -3723,7 +3724,7 @@ iperf_print_results(struct iperf_test *test)
* Running total of the total number of packets. Use the sender packet count if we
* have it, otherwise use the receiver packet count.
*/
int packet_count = sender_packet_count ? sender_packet_count : receiver_packet_count;
int64_t packet_count = sender_packet_count ? sender_packet_count : receiver_packet_count;
total_packets += (packet_count - sp->omitted_packet_count);
sender_total_packets += (sender_packet_count - sender_omitted_packet_count);
receiver_total_packets += (receiver_packet_count - receiver_omitted_packet_count);
Expand All @@ -3745,7 +3746,7 @@ iperf_print_results(struct iperf_test *test)
if (test->sender_has_retransmits) {
/* Sender summary, TCP and SCTP with retransmits. */
if (test->json_output)
cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d max_snd_cwnd: %d max_snd_wnd: %d max_rtt: %d min_rtt: %d mean_rtt: %d sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans, (int64_t) sp->result->stream_max_snd_cwnd, (int64_t) sp->result->stream_max_snd_wnd, (int64_t) sp->result->stream_max_rtt, (int64_t) sp->result->stream_min_rtt, (int64_t) ((sp->result->stream_count_rtt == 0) ? 0 : sp->result->stream_sum_rtt / sp->result->stream_count_rtt), stream_must_be_sender));
cJSON_AddItemToObject(json_summary_stream, report_sender, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d max_snd_cwnd: %d max_snd_wnd: %d max_rtt: %d min_rtt: %d mean_rtt: %d sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans, (int64_t) sp->result->stream_max_snd_cwnd, (int64_t) sp->result->stream_max_snd_wnd, (int64_t) sp->result->stream_max_rtt, (int64_t) sp->result->stream_min_rtt, (int64_t) ((sp->result->stream_count_rtt == 0) ? 0 : sp->result->stream_sum_rtt / sp->result->stream_count_rtt), stream_must_be_sender));
else
if (test->role == 's' && !sp->sender) {
if (test->verbose)
Expand All @@ -3757,7 +3758,7 @@ iperf_print_results(struct iperf_test *test)
} else {
/* Sender summary, TCP and SCTP without retransmits. */
if (test->json_output)
cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, stream_must_be_sender));
cJSON_AddItemToObject(json_summary_stream, report_sender, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, stream_must_be_sender));
else
if (test->role == 's' && !sp->sender) {
if (test->verbose)
Expand Down Expand Up @@ -3792,7 +3793,7 @@ iperf_print_results(struct iperf_test *test)
* is the case, then use the receiver's count of packets
* instead.
*/
int packet_count = sender_packet_count ? sender_packet_count : receiver_packet_count;
int64_t packet_count = sender_packet_count ? sender_packet_count : receiver_packet_count;
cJSON_AddItemToObject(json_summary_stream, "udp", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f jitter_ms: %f lost_packets: %d packets: %d lost_percent: %f out_of_order: %d sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, (double) sp->jitter * 1000.0, (int64_t) (sp->cnt_error - sp->omitted_cnt_error), (int64_t) (packet_count - sp->omitted_packet_count), (double) lost_percent, (int64_t) (sp->outoforder_packets - sp->omitted_outoforder_packets), stream_must_be_sender));
}
else {
Expand Down Expand Up @@ -3848,7 +3849,7 @@ iperf_print_results(struct iperf_test *test)
if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
/* Receiver summary, TCP and SCTP */
if (test->json_output)
cJSON_AddItemToObject(json_summary_stream, "receiver", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f sender: %b", (int64_t) sp->socket, (double) start_time, (double) receiver_time, (double) end_time, (int64_t) bytes_received, bandwidth * 8, stream_must_be_sender));
cJSON_AddItemToObject(json_summary_stream, report_receiver, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f sender: %b", (int64_t) sp->socket, (double) start_time, (double) receiver_time, (double) end_time, (int64_t) bytes_received, bandwidth * 8, stream_must_be_sender));
else
if (test->role == 's' && sp->sender) {
if (test->verbose)
Expand Down Expand Up @@ -3997,7 +3998,7 @@ iperf_print_results(struct iperf_test *test)
*/
if (! (test->role == 's' && !stream_must_be_sender) ) {
unit_snprintf(ubuf, UNIT_LEN, (double) total_sent, 'A');
iperf_printf(test, report_sum_bw_udp_format, mbuf, start_time, sender_time, ubuf, nbuf, 0.0, 0, sender_total_packets, 0.0, "sender");
iperf_printf(test, report_sum_bw_udp_format, mbuf, start_time, sender_time, ubuf, nbuf, 0.0, 0, sender_total_packets, 0.0, report_sender);
}
if (! (test->role == 's' && stream_must_be_sender) ) {

Expand All @@ -4010,7 +4011,7 @@ iperf_print_results(struct iperf_test *test)
bandwidth = 0.0;
}
unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
iperf_printf(test, report_sum_bw_udp_format, mbuf, start_time, receiver_time, ubuf, nbuf, avg_jitter * 1000.0, lost_packets, receiver_total_packets, lost_percent, "receiver");
iperf_printf(test, report_sum_bw_udp_format, mbuf, start_time, receiver_time, ubuf, nbuf, avg_jitter * 1000.0, lost_packets, receiver_total_packets, lost_percent, report_receiver);
}
}
}
Expand Down
22 changes: 17 additions & 5 deletions src/iperf_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@

#include "version.h"

#if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
#else
# ifndef PRIu64
# if sizeof(long) == 8
# define PRIu64 "lu"
# else
# define PRIu64 "llu"
# endif
# endif
#endif

#ifdef __cplusplus
extern "C"
{
Expand Down Expand Up @@ -382,13 +394,13 @@ const char report_bw_retrans_cwnd_format[] =
"[%3d]%s %6.2f-%-6.2f sec %ss %ss/sec %3u %ss %s\n";

const char report_bw_udp_format[] =
"[%3d]%s %6.2f-%-6.2f sec %ss %ss/sec %5.3f ms %d/%d (%.2g%%) %s\n";
"[%3d]%s %6.2f-%-6.2f sec %ss %ss/sec %5.3f ms %" PRIu64 "/%" PRIu64 " (%.2g%%) %s\n";

const char report_bw_udp_format_no_omitted_error[] =
"[%3d]%s %6.2f-%-6.2f sec %ss %ss/sec %5.3f ms Unknown/%d %s\n";
"[%3d]%s %6.2f-%-6.2f sec %ss %ss/sec %5.3f ms Unknown/%" PRIu64 " %s\n";

const char report_bw_udp_sender_format[] =
"[%3d]%s %6.2f-%-6.2f sec %ss %ss/sec %s %d %s\n";
"[%3d]%s %6.2f-%-6.2f sec %ss %ss/sec %s %" PRIu64 " %s\n";

const char report_summary[] =
"Test Complete. Summary Results:\n";
Expand All @@ -400,10 +412,10 @@ const char report_sum_bw_retrans_format[] =
"[SUM]%s %6.2f-%-6.2f sec %ss %ss/sec %3d %s\n";

const char report_sum_bw_udp_format[] =
"[SUM]%s %6.2f-%-6.2f sec %ss %ss/sec %5.3f ms %d/%d (%.2g%%) %s\n";
"[SUM]%s %6.2f-%-6.2f sec %ss %ss/sec %5.3f ms %" PRIu64 "/%" PRIu64 " (%.2g%%) %s\n";

const char report_sum_bw_udp_sender_format[] =
"[SUM]%s %6.2f-%-6.2f sec %ss %ss/sec %s %d %s\n";
"[SUM]%s %6.2f-%-6.2f sec %ss %ss/sec %s %" PRIu64 " %s\n";

const char report_omitted[] = "(omitted)";

Expand Down
4 changes: 2 additions & 2 deletions src/iperf_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ iperf_udp_recv(struct iperf_stream *sp)
}

if (sp->test->debug_level >= DEBUG_LEVEL_DEBUG)
fprintf(stderr, "pcount %" PRIu64 " packet_count %d\n", pcount, sp->packet_count);
fprintf(stderr, "pcount %" PRIu64 " packet_count %" PRIu64 "\n", pcount, sp->packet_count);

/*
* Try to handle out of order packets. The way we do this
Expand Down Expand Up @@ -167,7 +167,7 @@ iperf_udp_recv(struct iperf_stream *sp)

/* Log the out-of-order packet */
if (sp->test->debug)
fprintf(stderr, "OUT OF ORDER - incoming packet sequence %" PRIu64 " but expected sequence %d on stream %d", pcount, sp->packet_count + 1, sp->socket);
fprintf(stderr, "OUT OF ORDER - incoming packet sequence %" PRIu64 " but expected sequence %" PRIu64 " on stream %d", pcount, sp->packet_count + 1, sp->socket);
}

/*
Expand Down

0 comments on commit c2fe76c

Please sign in to comment.