diff options
Diffstat (limited to '')
-rw-r--r-- | src/ReportOutputs.c | 1057 |
1 files changed, 758 insertions, 299 deletions
diff --git a/src/ReportOutputs.c b/src/ReportOutputs.c index e977433..2e34cb5 100644 --- a/src/ReportOutputs.c +++ b/src/ReportOutputs.c @@ -51,6 +51,7 @@ #include "Locale.h" #include "SocketAddr.h" #include "iperf_formattime.h" +#include "dscp.h" // These static variables are not thread safe but ok to use becase only // the repoter thread usses them @@ -68,6 +69,8 @@ static int HEADING_FLAG(report_bw_jitter_loss) = 0; static int HEADING_FLAG(report_bw_read_enhanced) = 0; static int HEADING_FLAG(report_bw_read_enhanced_netpwr) = 0; static int HEADING_FLAG(report_bw_write_enhanced) = 0; +static int HEADING_FLAG(report_bw_write_enhanced_fq) = 0; +static int HEADING_FLAG(report_bw_write_fq) = 0; static int HEADING_FLAG(report_write_enhanced_write) = 0; static int HEADING_FLAG(report_bw_write_enhanced_netpwr) = 0; static int HEADING_FLAG(report_bw_pps_enhanced) = 0; @@ -81,7 +84,6 @@ static int HEADING_FLAG(report_frame_tcp_enhanced) = 0; static int HEADING_FLAG(report_frame_read_tcp_enhanced_triptime) = 0; static int HEADING_FLAG(report_udp_fullduplex) = 0; static int HEADING_FLAG(report_sumcnt_bw) = 0; -static int HEADING_FLAG(report_sumcnt_udp_fullduplex) = 0; static int HEADING_FLAG(report_sumcnt_bw_read_enhanced) = 0; static int HEADING_FLAG(report_sumcnt_bw_read_triptime) = 0; static int HEADING_FLAG(report_sumcnt_bw_write_enhanced) = 0; @@ -94,16 +96,21 @@ static int HEADING_FLAG(report_burst_write_tcp) = 0; static int HEADING_FLAG(report_bw_isoch_enhanced_netpwr) = 0; static int HEADING_FLAG(report_sumcnt_udp_enhanced) = 0; static int HEADING_FLAG(report_sumcnt_udp_triptime) = 0; +static int HEADING_FLAG(reportCSV_bw_read_enhanced) = 0; +static int HEADING_FLAG(reportCSV_bw_write_enhanced) = 0; +static int HEADING_FLAG(reportCSV_bw_jitter_loss_pps) = 0; +static int HEADING_FLAG(reportCSV_client_bb_bw_tcp) = 0; void reporter_default_heading_flags (int flag) { HEADING_FLAG(report_bw) = flag; HEADING_FLAG(report_client_bb_bw) = flag; HEADING_FLAG(report_sumcnt_bw) = flag; - HEADING_FLAG(report_sumcnt_udp_fullduplex) = flag; HEADING_FLAG(report_bw_jitter_loss) = flag; HEADING_FLAG(report_bw_read_enhanced) = flag; HEADING_FLAG(report_bw_read_enhanced_netpwr) = flag; HEADING_FLAG(report_bw_write_enhanced) = flag; + HEADING_FLAG(report_bw_write_enhanced_fq) = flag; + HEADING_FLAG(report_bw_write_fq) = flag; HEADING_FLAG(report_write_enhanced_write) = flag; HEADING_FLAG(report_write_enhanced_isoch) = flag; HEADING_FLAG(report_bw_write_enhanced_netpwr) = flag; @@ -126,7 +133,30 @@ void reporter_default_heading_flags (int flag) { HEADING_FLAG(report_bw_isoch_enhanced_netpwr) = flag; HEADING_FLAG(report_sumcnt_udp_enhanced) = flag; HEADING_FLAG(report_sumcnt_udp_triptime) = flag; + HEADING_FLAG(reportCSV_bw_read_enhanced) = 0; + HEADING_FLAG(reportCSV_bw_write_enhanced) = 0; + HEADING_FLAG(reportCSV_bw_jitter_loss_pps) = 0; + HEADING_FLAG(reportCSV_client_bb_bw_tcp) = 0; } + +// +// flush when +// +// o) it's a final report +// o) this is the sum report (all preceding interval reports need flush) +// o) below the flush rate limiter +// +#define FLUSH_RATE_LIMITER 1000 //units is microseconds +static inline void cond_flush (struct TransferInfo *stats) { + static struct timeval prev={0,0}; + struct timeval now; + TimeGetNow(now); + if (stats->final || (stats->type == SUM_REPORT) || !(TimeDifferenceUsec(now, prev) < FLUSH_RATE_LIMITER)) { + fflush(stdout); + prev = now; + } +} + static inline void _print_stats_common (struct TransferInfo *stats) { assert(stats!=NULL); outbuffer[0] = '\0'; @@ -145,13 +175,13 @@ static inline void _output_outoforder(struct TransferInfo *stats) { if (stats->cntOutofOrder > 0) { printf(report_outoforder, stats->common->transferIDStr, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } if (stats->l2counts.cnt) { printf(report_l2statistics, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, stats->l2counts.cnt, stats->l2counts.lengtherr, - stats->l2counts.udpcsumerr, stats->l2counts.unknown); + stats->l2counts.udpcsumerr, stats->l2counts.unknown, (stats->common->Omit ? report_omitted : "")); } } @@ -209,29 +239,29 @@ static inline void set_netpowerbuf(double meantransit, struct TransferInfo *stat void tcp_output_fullduplex (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw); _print_stats_common(stats); - printf(report_bw_sum_fullduplex_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext); - fflush(stdout); + printf(report_bw_sum_fullduplex_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_fullduplex_sum (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw); _print_stats_common(stats); - printf(report_sum_bw_format, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext); - fflush(stdout); + printf(report_sum_bw_format, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_fullduplex_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw); _print_stats_common(stats); - printf(report_bw_sum_fullduplex_enhanced_format, stats->common->transferID, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext); - fflush(stdout); + printf(report_bw_sum_fullduplex_enhanced_format, stats->common->transferID, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_read (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw); _print_stats_common(stats); - printf(report_bw_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext); - fflush(stdout); + printf(report_bw_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } //TCP read or server output void tcp_output_read_enhanced (struct TransferInfo *stats) { @@ -248,8 +278,9 @@ void tcp_output_read_enhanced (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); - fflush(stdout); + stats->sock_callstats.read.bins[7], + (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_read_triptime (struct TransferInfo *stats) { double meantransit; @@ -279,7 +310,8 @@ void tcp_output_read_triptime (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); + stats->sock_callstats.read.bins[7], + (stats->common->Omit ? report_omitted : "")); } else { meantransit = (stats->transit.total.cnt > 0) ? (stats->transit.total.sum / stats->transit.total.cnt) : 0; set_netpowerbuf(meantransit, stats); @@ -302,12 +334,13 @@ void tcp_output_read_triptime (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); + stats->sock_callstats.read.bins[7], + (stats->common->Omit ? report_omitted : "")); } if (stats->framelatency_histogram) { histogram_print(stats->framelatency_histogram, stats->ts.iStart, stats->ts.iEnd); } - fflush(stdout); + cond_flush(stats); } void tcp_output_read_enhanced_isoch (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_isoch_enhanced_netpwr); @@ -334,7 +367,8 @@ void tcp_output_read_enhanced_isoch (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); + stats->sock_callstats.read.bins[7], + (stats->common->Omit ? report_omitted : "")); } else { meantransit = (stats->isochstats.transit.total.cnt > 0) ? (stats->isochstats.transit.total.sum / stats->isochstats.transit.total.cnt) : 0; set_netpowerbuf(meantransit, stats); @@ -356,12 +390,13 @@ void tcp_output_read_enhanced_isoch (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); + stats->sock_callstats.read.bins[7], + (stats->common->Omit ? report_omitted : "")); } if (stats->framelatency_histogram) { histogram_print(stats->framelatency_histogram, stats->ts.iStart, stats->ts.iEnd); } - fflush(stdout); + cond_flush(stats); } void tcp_output_frame_read (struct TransferInfo *stats) { @@ -378,8 +413,9 @@ void tcp_output_frame_read (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); - fflush(stdout); + stats->sock_callstats.read.bins[7], + (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_frame_read_triptime (struct TransferInfo *stats) { fprintf(stderr, "FIXME\n"); @@ -403,7 +439,8 @@ void tcp_output_burst_read (struct TransferInfo *stats) { stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], stats->sock_callstats.read.bins[7], - netpower_buf); + netpower_buf, + (stats->common->Omit ? report_omitted : "")); } else { printf(report_burst_read_tcp_final_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, @@ -420,9 +457,10 @@ void tcp_output_burst_read (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); + stats->sock_callstats.read.bins[7], + (stats->common->Omit ? report_omitted : "")); } - fflush(stdout); + cond_flush(stats); } //TCP write or client output @@ -431,8 +469,8 @@ void tcp_output_write (struct TransferInfo *stats) { _print_stats_common(stats); printf(report_bw_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - fflush(stdout); + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_write_bb (struct TransferInfo *stats) { @@ -448,18 +486,35 @@ void tcp_output_write_bb (struct TransferInfo *stats) { rps_string[sizeof(rps_string) - 1] = '\0'; #if HAVE_TCP_STATS - printf(report_client_bb_bw_format, stats->common->transferIDStr, - stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext, - stats->bbrtt.total.cnt, - (stats->bbrtt.total.mean * 1e3), - (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.min * 1e3), - (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.max * 1e3), - (stats->bbrtt.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.total.m2 / (stats->bbrtt.total.cnt - 1))), - stats->sock_callstats.write.tcpstats.retry, - stats->sock_callstats.write.tcpstats.cwnd, - stats->sock_callstats.write.tcpstats.rtt, - rps_string); + if (!stats->final) { + printf(report_client_bb_bw_format, stats->common->transferIDStr, + stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->bbrtt.total.cnt, + (stats->bbrtt.total.mean * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.min * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.max * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.total.m2 / (stats->bbrtt.total.cnt - 1))), + stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.cwnd_packets, + stats->sock_callstats.write.tcpstats.rtt, + stats->sock_callstats.write.tcpstats.rttvar, + rps_string, + (stats->common->Omit ? report_omitted : "")); + } else { + printf(report_client_bb_bw_final_format, stats->common->transferIDStr, + stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->bbrtt.total.cnt, + (stats->bbrtt.total.mean * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.min * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.max * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.total.m2 / (stats->bbrtt.total.cnt - 1))), + stats->sock_callstats.write.tcpstats.retry, + rps_string, + (stats->common->Omit ? report_omitted : "")); + } #else printf(report_client_bb_bw_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, @@ -469,7 +524,8 @@ void tcp_output_write_bb (struct TransferInfo *stats) { (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.min * 1e3), (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.max * 1e3), (stats->bbrtt.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.total.m2 / (stats->bbrtt.total.cnt - 1))), - rps_string); + rps_string, + (stats->common->Omit ? report_omitted : "")); #endif if (isTripTime(stats->common)) { printf(report_client_bb_bw_triptime_format, stats->common->transferIDStr, @@ -487,11 +543,23 @@ void tcp_output_write_bb (struct TransferInfo *stats) { (stats->bbasym.total.cnt < 2) ? 0 : (stats->bbasym.total.min * 1e3), (stats->bbasym.total.cnt < 2) ? 0 : (stats->bbasym.total.max * 1e3), (stats->bbasym.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbasym.total.m2 / (stats->bbasym.total.cnt - 1))), - rps_string); + (stats->common->Omit ? report_omitted : "")); + } + if (stats->bbowdto_histogram) { + stats->bbowdto_histogram->final = 1; + histogram_print(stats->bbowdto_histogram, stats->ts.iStart, stats->ts.iEnd); + } + if (stats->bbowdfro_histogram) { + stats->bbowdfro_histogram->final = 1; + histogram_print(stats->bbowdfro_histogram, stats->ts.iStart, stats->ts.iEnd); } if (stats->bbrtt_histogram) { + stats->bbrtt_histogram->final = 1; histogram_print(stats->bbrtt_histogram, stats->ts.iStart, stats->ts.iEnd); } + if (isTripTime(stats->common) && (stats->bb_clocksync_error > 0)) { + printf(report_client_bb_triptime_clocksync_error, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, stats->bb_clocksync_error); + } } else { double rps = ((stats->bbrtt.current.cnt > 0) && (stats->iBBrunning > 0)) ? ((double) stats->bbrtt.current.cnt / stats->iBBrunning) : 0; if (rps < 10) @@ -511,8 +579,11 @@ void tcp_output_write_bb (struct TransferInfo *stats) { (stats->bbrtt.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.current.m2 / (stats->bbrtt.current.cnt - 1))), stats->sock_callstats.write.tcpstats.retry, stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.cwnd_packets, stats->sock_callstats.write.tcpstats.rtt, - rps_string); + stats->sock_callstats.write.tcpstats.rttvar, + rps_string, + (stats->common->Omit ? report_omitted : "")); #else printf(report_client_bb_bw_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, @@ -522,10 +593,43 @@ void tcp_output_write_bb (struct TransferInfo *stats) { (stats->bbrtt.current.cnt < 2) ? 0 : (stats->bbrtt.current.min * 1e3), (stats->bbrtt.current.cnt < 2) ? 0 : (stats->bbrtt.current.max * 1e3), (stats->bbrtt.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.current.m2 / (stats->bbrtt.current.cnt - 1))), - rps_string); + rps_string, + (stats->common->Omit ? report_omitted : "")); #endif + if (isTripTime(stats->common)) { + printf(report_client_bb_bw_triptime_format, stats->common->transferIDStr, + stats->ts.iStart, stats->ts.iEnd, + stats->bbowdto.current.cnt, + (stats->bbowdto.current.mean * 1e3), + (stats->bbowdto.current.cnt < 2) ? 0 : (stats->bbowdto.current.min * 1e3), + (stats->bbowdto.current.cnt < 2) ? 0 : (stats->bbowdto.current.max * 1e3), + (stats->bbowdto.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbowdto.current.m2 / (stats->bbowdto.current.cnt - 1))), + (stats->bbowdfro.current.mean * 1e3), + (stats->bbowdfro.current.cnt < 2) ? 0 : (stats->bbowdfro.current.min * 1e3), + (stats->bbowdfro.current.cnt < 2) ? 0 : (stats->bbowdfro.current.max * 1e3), + (stats->bbowdfro.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbowdfro.current.m2 / (stats->bbowdfro.current.cnt - 1))), + (stats->bbasym.current.mean * 1e3), + (stats->bbasym.current.cnt < 2) ? 0 : (stats->bbasym.current.min * 1e3), + (stats->bbasym.current.cnt < 2) ? 0 : (stats->bbasym.current.max * 1e3), + (stats->bbasym.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbasym.current.m2 / (stats->bbasym.current.cnt - 1))), + (stats->common->Omit ? report_omitted : "")); + } + if (isHistogram(stats->common)) { + if (stats->bbowdto_histogram) { + stats->bbowdto_histogram->final = 0; + histogram_print(stats->bbowdto_histogram, stats->ts.iStart, stats->ts.iEnd); + } + if (stats->bbowdfro_histogram) { + stats->bbowdfro_histogram->final = 0; + histogram_print(stats->bbowdfro_histogram, stats->ts.iStart, stats->ts.iEnd); + } + if (stats->bbrtt_histogram) { + stats->bbrtt_histogram->final = 0; + histogram_print(stats->bbrtt_histogram, stats->ts.iStart, stats->ts.iEnd); + } + } } - fflush(stdout); + cond_flush(stats); } void tcp_output_burst_write (struct TransferInfo *stats) { @@ -542,16 +646,18 @@ void tcp_output_burst_write (struct TransferInfo *stats) { stats->sock_callstats.write.tcpstats.retry, stats->sock_callstats.write.tcpstats.cwnd, stats->sock_callstats.write.tcpstats.rtt, - netpower_buf); + netpower_buf, + (stats->common->Omit ? report_omitted : "")); #else printf(report_burst_write_tcp_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->transit.current.mean, stats->sock_callstats.write.WriteCnt, - stats->sock_callstats.write.WriteErr); + stats->sock_callstats.write.WriteErr, + (stats->common->Omit ? report_omitted : "")); #endif - fflush(stdout); + cond_flush(stats); } void tcp_output_write_enhanced (struct TransferInfo *stats) { @@ -562,37 +668,121 @@ void tcp_output_write_enhanced (struct TransferInfo *stats) { stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->sock_callstats.write.WriteCnt, - stats->sock_callstats.write.WriteErr); + stats->sock_callstats.write.WriteErr, + (stats->common->Omit ? report_omitted : "")); #else set_netpowerbuf(stats->sock_callstats.write.tcpstats.rtt * 1e-6, stats); - if (stats->sock_callstats.write.tcpstats.cwnd > 0) { - printf(report_bw_write_enhanced_format, +#if HAVE_STRUCT_TCP_INFO_TCPI_SND_CWND + printf(report_bw_write_enhanced_format, + stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->sock_callstats.write.WriteCnt, + stats->sock_callstats.write.WriteErr, + stats->sock_callstats.write.tcpstats.retry, +#if HAVE_TCP_INFLIGHT + stats->sock_callstats.write.tcpstats.bytes_in_flight, + stats->sock_callstats.write.tcpstats.packets_in_flight, +#endif + stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.cwnd_packets, + stats->sock_callstats.write.tcpstats.rtt, + stats->sock_callstats.write.tcpstats.rttvar, + netpower_buf, + (stats->common->Omit ? report_omitted : "")); +#else + printf(report_bw_write_enhanced_nocwnd_format, + stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->sock_callstats.write.WriteCnt, + stats->sock_callstats.write.WriteErr, + stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.rtt, + stats->sock_callstats.write.tcpstats.rttvar, + netpower_buf, + (stats->common->Omit ? report_omitted : "")); +#endif +#endif +#if HAVE_DECL_TCP_NOTSENT_LOWAT + if (stats->latency_histogram) { + histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd); + } +#endif + cond_flush(stats); +} + +void tcp_output_write_enhanced_fq (struct TransferInfo *stats) { +#if (HAVE_DECL_SO_MAX_PACING_RATE) + _print_stats_common(stats); + char pacingrate[40]; + if (!stats->final) { + byte_snprintf(pacingrate, sizeof(pacingrate), stats->FQPacingRateCurrent, 'a'); + pacingrate[39] = '\0'; + } else { + pacingrate[0] = '\0'; + } +#if !(HAVE_TCP_STATS) + HEADING_PRINT_COND(report_bw_write_fq); + printf(report_bw_write_fq_format, + stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->sock_callstats.write.WriteCnt, + stats->sock_callstats.write.WriteErr, + pacingrate, + (stats->common->Omit ? report_omitted : "")); +#else + HEADING_PRINT_COND(report_bw_write_enhanced_fq); + set_netpowerbuf(stats->sock_callstats.write.tcpstats.rtt * 1e-6, stats); +#if HAVE_STRUCT_TCP_INFO_TCPI_SND_CWND + if (!stats->final) { + printf(report_bw_write_enhanced_fq_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->sock_callstats.write.WriteCnt, stats->sock_callstats.write.WriteErr, stats->sock_callstats.write.tcpstats.retry, +#if HAVE_TCP_INFLIGHT + stats->sock_callstats.write.tcpstats.bytes_in_flight, + stats->sock_callstats.write.tcpstats.packets_in_flight, +#endif stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.cwnd_packets, stats->sock_callstats.write.tcpstats.rtt, stats->sock_callstats.write.tcpstats.rttvar, - netpower_buf); + pacingrate, netpower_buf, + (stats->common->Omit ? report_omitted : "")); } else { - printf(report_bw_write_enhanced_nocwnd_format, + printf(report_bw_write_enhanced_fq_final_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->sock_callstats.write.WriteCnt, stats->sock_callstats.write.WriteErr, stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.cwnd, stats->sock_callstats.write.tcpstats.rtt, - netpower_buf); + stats->sock_callstats.write.tcpstats.rttvar, + netpower_buf, + (stats->common->Omit ? report_omitted : "")); } +#else + printf(report_bw_write_enhanced_nocwnd_format, + stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->sock_callstats.write.WriteCnt, + stats->sock_callstats.write.WriteErr, + stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.rtt, + stats->sock_callstats.write.tcpstats.rttvar, + netpower_buf, + (stats->common->Omit ? report_omitted : "")); +#endif #endif #if HAVE_DECL_TCP_NOTSENT_LOWAT if (stats->latency_histogram) { histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd); } #endif - fflush(stdout); + cond_flush(stats); +#endif } void tcp_output_write_enhanced_write (struct TransferInfo *stats) { @@ -608,39 +798,48 @@ void tcp_output_write_enhanced_write (struct TransferInfo *stats) { stats->write_mmm.current.min * 1e3, stats->write_mmm.current.max * 1e3, (stats->write_mmm.current.cnt < 2) ? 0 : (1e-3 * sqrt(stats->write_mmm.current.m2 / (stats->write_mmm.current.cnt - 1))), - stats->write_mmm.current.cnt); + stats->write_mmm.current.cnt, + (stats->common->Omit ? report_omitted : "")); #else set_netpowerbuf(stats->sock_callstats.write.tcpstats.rtt * 1e-6, stats); - if (stats->sock_callstats.write.tcpstats.cwnd > 0) { - printf(report_write_enhanced_write_format, - stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext, - stats->sock_callstats.write.WriteCnt, - stats->sock_callstats.write.WriteErr, - stats->sock_callstats.write.tcpstats.retry, - stats->sock_callstats.write.tcpstats.cwnd, - stats->sock_callstats.write.tcpstats.rtt, - netpower_buf, - stats->write_mmm.current.mean * 1e-3, - stats->write_mmm.current.min * 1e-3, - stats->write_mmm.current.max * 1e-3, - (stats->write_mmm.current.cnt < 2) ? 0 : (1e-3 * sqrt(stats->write_mmm.current.m2 / (stats->write_mmm.current.cnt - 1))), - stats->write_mmm.current.cnt); - } else { - printf(report_write_enhanced_nocwnd_write_format, - stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext, - stats->sock_callstats.write.WriteCnt, - stats->sock_callstats.write.WriteErr, - stats->sock_callstats.write.tcpstats.retry, - stats->sock_callstats.write.tcpstats.rtt, - netpower_buf, - stats->write_mmm.current.mean * 1e3, - stats->write_mmm.current.min * 1e3, - stats->write_mmm.current.max * 1e3, - (stats->write_mmm.current.cnt < 2) ? 0 : (1e3 * sqrt(stats->write_mmm.current.m2 / (stats->write_mmm.current.cnt - 1))), - stats->write_mmm.current.cnt); - } +#if HAVE_STRUCT_TCP_INFO_TCPI_SND_CWND + printf(report_write_enhanced_write_format, + stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->sock_callstats.write.WriteCnt, + stats->sock_callstats.write.WriteErr, + stats->sock_callstats.write.tcpstats.retry, +#if HAVE_TCP_INFLIGHT + stats->sock_callstats.write.tcpstats.bytes_in_flight, + stats->sock_callstats.write.tcpstats.packets_in_flight, +#endif + stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.cwnd_packets, + stats->sock_callstats.write.tcpstats.rtt, + stats->sock_callstats.write.tcpstats.rttvar, + netpower_buf, + stats->write_mmm.current.mean * 1e-3, + stats->write_mmm.current.min * 1e-3, + stats->write_mmm.current.max * 1e-3, + (stats->write_mmm.current.cnt < 2) ? 0 : (1e-3 * sqrt(stats->write_mmm.current.m2 / (stats->write_mmm.current.cnt - 1))), + stats->write_mmm.current.cnt, + (stats->common->Omit ? report_omitted : "")); +#else + printf(report_write_enhanced_nocwnd_write_format, + stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->sock_callstats.write.WriteCnt, + stats->sock_callstats.write.WriteErr, + stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.rtt, + stats->sock_callstats.write.tcpstats.rttvar, + netpower_buf, + stats->write_mmm.current.mean * 1e3, + stats->write_mmm.current.min * 1e3, + stats->write_mmm.current.max * 1e3, + (stats->write_mmm.current.cnt < 2) ? 0 : (1e3 * sqrt(stats->write_mmm.current.m2 / (stats->write_mmm.current.cnt - 1))), + stats->write_mmm.current.cnt, (stats->common->Omit ? report_omitted : "")); +#endif #endif if (stats->latency_histogram) { histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd); @@ -648,7 +847,7 @@ void tcp_output_write_enhanced_write (struct TransferInfo *stats) { if (stats->write_histogram) { histogram_print(stats->write_histogram, stats->ts.iStart, stats->ts.iEnd); } - fflush(stdout); + cond_flush(stats); } void tcp_output_write_enhanced_isoch (struct TransferInfo *stats) { @@ -660,38 +859,41 @@ void tcp_output_write_enhanced_isoch (struct TransferInfo *stats) { outbuffer, outbufferext, stats->sock_callstats.write.WriteCnt, stats->sock_callstats.write.WriteErr, - stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips); + stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips, (stats->common->Omit ? report_omitted : "")); #else set_netpowerbuf(stats->sock_callstats.write.tcpstats.rtt * 1e-6, stats); - if (stats->sock_callstats.write.tcpstats.cwnd > 0) { - printf(report_write_enhanced_isoch_format, - stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext, - stats->sock_callstats.write.WriteCnt, - stats->sock_callstats.write.WriteErr, - stats->sock_callstats.write.tcpstats.retry, - stats->sock_callstats.write.tcpstats.cwnd, - stats->sock_callstats.write.tcpstats.rtt, - stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips, - netpower_buf); - } else { - printf(report_write_enhanced_isoch_nocwnd_format, - stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext, - stats->sock_callstats.write.WriteCnt, - stats->sock_callstats.write.WriteErr, - stats->sock_callstats.write.tcpstats.retry, - stats->sock_callstats.write.tcpstats.rtt, - stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips, - netpower_buf); - } +#if HAVE_STRUCT_TCP_INFO_TCPI_SND_CWND + printf(report_write_enhanced_isoch_format, + stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->sock_callstats.write.WriteCnt, + stats->sock_callstats.write.WriteErr, + stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.cwnd_packets, + stats->sock_callstats.write.tcpstats.rtt, + stats->sock_callstats.write.tcpstats.rttvar, + stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips, + netpower_buf,(stats->common->Omit ? report_omitted : "")); +#else + printf(report_write_enhanced_isoch_nocwnd_format, + stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + stats->sock_callstats.write.WriteCnt, + stats->sock_callstats.write.WriteErr, + stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.rtt, + stats->sock_callstats.write.tcpstats.rttvar, + stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips, + netpower_buf,(stats->common->Omit ? report_omitted : "")); +#endif #endif #if HAVE_DECL_TCP_NOTSENT_LOWAT if (stats->latency_histogram) { histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd); } #endif - fflush(stdout); + cond_flush(stats); } @@ -700,50 +902,65 @@ void udp_output_fullduplex (struct TransferInfo *stats) { HEADING_PRINT_COND(report_udp_fullduplex); _print_stats_common(stats); printf(report_udp_fullduplex_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, \ - stats->cntDatagrams, (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0)); - fflush(stdout); + stats->cntDatagrams, (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0),(stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void udp_output_fullduplex_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_udp_fullduplex); _print_stats_common(stats); printf(report_udp_fullduplex_enhanced_format, stats->common->transferID, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, \ - stats->cntDatagrams, (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0)); - fflush(stdout); + stats->cntDatagrams, (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0),(stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void udp_output_fullduplex_sum (struct TransferInfo *stats) { HEADING_PRINT_COND(report_udp_fullduplex); _print_stats_common(stats); printf(report_udp_fullduplex_sum_format, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, \ - stats->cntDatagrams, (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0)); - fflush(stdout); + stats->cntDatagrams, (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0),(stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void udp_output_read (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_jitter_loss); _print_stats_common(stats); - printf(report_bw_jitter_loss_format, stats->common->transferIDStr, - stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext, - (stats->final) ? ((stats->inline_jitter.total.sum / (double) stats->inline_jitter.total.cnt) * 1e3) : (stats->jitter * 1e3), \ - stats->cntError, stats->cntDatagrams, - (100.0 * stats->cntError) / stats->cntDatagrams); + if (!stats->cntIPG) { + printf(report_bw_jitter_loss_format, stats->common->transferIDStr, + stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + 0.0, stats->cntError, + stats->cntDatagrams, + 0.0,(stats->common->Omit ? report_omitted : "")); + } else { + printf(report_bw_jitter_loss_format, stats->common->transferIDStr, + stats->ts.iStart, stats->ts.iEnd, + outbuffer, outbufferext, + (stats->final) ? ((stats->inline_jitter.total.sum / (double) stats->inline_jitter.total.cnt) * 1e3) : (stats->jitter * 1e3), \ + stats->cntError, stats->cntDatagrams, + (100.0 * stats->cntError) / stats->cntDatagrams, (stats->common->Omit ? report_omitted : "")); + } _output_outoforder(stats); - fflush(stdout); + cond_flush(stats); } void udp_output_read_triptime (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_jitter_loss_enhanced_triptime); _print_stats_common(stats); + if (!stats->cntIPG) { printf(report_bw_jitter_loss_suppress_enhanced_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, 0.0, stats->cntError, stats->cntDatagrams, - 0.0,0.0,0.0,0.0,0.0,0.0); + stats->sock_callstats.read.cntRead, + stats->sock_callstats.read.cntReadTimeo, +#if HAVE_DECL_MSG_TRUNC + stats->sock_callstats.read.cntReadErrLen, +#endif + 0.0,0.0,0.0,0.0,0.0,0.0,(stats->common->Omit ? report_omitted : "")); } else { if ((stats->transit.current.min > UNREALISTIC_LATENCYMINMAX) || (stats->transit.current.min < UNREALISTIC_LATENCYMINMIN)) { @@ -753,7 +970,14 @@ void udp_output_read_triptime (struct TransferInfo *stats) { (stats->final) ? ((stats->inline_jitter.total.sum / (double) stats->inline_jitter.total.cnt) * 1e3) : (stats->jitter * 1e3), stats->cntError, stats->cntDatagrams, (100.0 * stats->cntError) / stats->cntDatagrams, - (stats->cntIPG / stats->IPGsum)); + (stats->cntIPG / stats->IPGsum), + stats->sock_callstats.read.cntRead, +#if HAVE_DECL_MSG_TRUNC + stats->sock_callstats.read.cntReadTimeo, + stats->sock_callstats.read.cntReadErrLen,(stats->common->Omit ? report_omitted : "")); +#else + stats->sock_callstats.read.cntReadTimeo, (stats->common->Omit ? report_omitted : "")); +#endif } else { double meantransit; double variance; @@ -785,7 +1009,12 @@ void udp_output_read_triptime (struct TransferInfo *stats) { (stats->cntIPG / stats->IPGsum), stats->cntIPG, llaw_bufstr, - netpower_buf); + stats->sock_callstats.read.cntRead, + stats->sock_callstats.read.cntReadTimeo, +#if HAVE_DECL_MSG_TRUNC + stats->sock_callstats.read.cntReadErrLen, +#endif + netpower_buf, (stats->common->Omit ? report_omitted : "")); } } if (stats->latency_histogram) { @@ -795,7 +1024,7 @@ void udp_output_read_triptime (struct TransferInfo *stats) { histogram_print(stats->jitter_histogram, stats->ts.iStart, stats->ts.iEnd); } _output_outoforder(stats); - fflush(stdout); + cond_flush(stats); } void udp_output_read_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_jitter_loss_enhanced); @@ -806,7 +1035,12 @@ void udp_output_read_enhanced (struct TransferInfo *stats) { outbuffer, outbufferext, 0.0, stats->cntError, stats->cntDatagrams, - 0.0,0.0,0.0,0.0,0.0,0.0); + stats->sock_callstats.read.cntRead, + stats->sock_callstats.read.cntReadTimeo, +#if HAVE_DECL_MSG_TRUNC + stats->sock_callstats.read.cntReadErrLen, +#endif + 0.0,0.0,0.0,0.0,0.0,0.0, (stats->common->Omit ? report_omitted : "")); } else { if ((stats->transit.current.min > UNREALISTIC_LATENCYMINMAX) || (stats->transit.current.min < UNREALISTIC_LATENCYMINMIN)) { @@ -816,7 +1050,14 @@ void udp_output_read_enhanced (struct TransferInfo *stats) { (stats->final) ? ((stats->inline_jitter.total.sum / (double) stats->inline_jitter.total.cnt) * 1e3) : (stats->jitter * 1e3), stats->cntError, stats->cntDatagrams, (100.0 * stats->cntError) / stats->cntDatagrams, - (stats->cntIPG / stats->IPGsum)); + (stats->cntIPG / stats->IPGsum), + stats->sock_callstats.read.cntRead, +#if HAVE_DECL_MSG_TRUNC + stats->sock_callstats.read.cntReadTimeo, + stats->sock_callstats.read.cntReadErrLen, (stats->common->Omit ? report_omitted : "")); +#else + stats->sock_callstats.read.cntReadTimeo, (stats->common->Omit ? report_omitted : "")); +#endif } else { double meantransit; double variance; @@ -841,7 +1082,12 @@ void udp_output_read_enhanced (struct TransferInfo *stats) { ((stats->final ? stats->transit.total.max : stats->transit.current.max) * 1e3), (stats->final ? (stats->transit.total.cnt < 2) : (stats->transit.current.cnt < 2)) ? 0 : (1e3 * variance), // convert from sec to ms (stats->cntIPG / stats->IPGsum), - netpower_buf); + stats->sock_callstats.read.cntRead, + stats->sock_callstats.read.cntReadTimeo, +#if HAVE_DECL_MSG_TRUNC + stats->sock_callstats.read.cntReadErrLen, +#endif + netpower_buf, (stats->common->Omit ? report_omitted : "")); } } if (stats->latency_histogram) { @@ -851,7 +1097,7 @@ void udp_output_read_enhanced (struct TransferInfo *stats) { histogram_print(stats->jitter_histogram, stats->ts.iStart, stats->ts.iEnd); } _output_outoforder(stats); - fflush(stdout); + cond_flush(stats); } void udp_output_read_triptime_isoch (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_jitter_loss_enhanced_isoch_triptime); @@ -876,7 +1122,7 @@ void udp_output_read_triptime_isoch (struct TransferInfo *stats) { (stats->final) ? ((stats->inline_jitter.total.sum / (double) stats->inline_jitter.total.cnt) * 1e3) : (stats->jitter * 1e3), stats->cntError, stats->cntDatagrams, (100.0 * stats->cntError) / stats->cntDatagrams, - (stats->cntIPG / stats->IPGsum)); + (stats->cntIPG / stats->IPGsum), (stats->common->Omit ? report_omitted : "")); } else { double frame_meantransit = (stats->isochstats.transit.current.cnt > 0) ? (stats->isochstats.transit.current.sum / stats->isochstats.transit.current.cnt) : 0; double meantransit = (stats->transit.current.cnt > 0) ? (stats->transit.current.sum / stats->transit.current.cnt) : 0; @@ -897,7 +1143,7 @@ void udp_output_read_triptime_isoch (struct TransferInfo *stats) { stats->isochstats.transit.current.min * 1e3, stats->isochstats.transit.current.max * 1e3, (stats->isochstats.transit.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->isochstats.transit.current.m2 / (stats->isochstats.transit.current.cnt - 1))), - netpower_buf); + netpower_buf, (stats->common->Omit ? report_omitted : "")); #if 0 if (stats->final) { printf("***** Jitter MMM = %f/%f/%f\n",stats->inline_jitter.total.mean, stats->inline_jitter.total.min, stats->inline_jitter.total.max); @@ -915,15 +1161,15 @@ void udp_output_read_triptime_isoch (struct TransferInfo *stats) { histogram_print(stats->framelatency_histogram, stats->ts.iStart, stats->ts.iEnd); } _output_outoforder(stats); - fflush(stdout); + cond_flush(stats); } void udp_output_write (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw); _print_stats_common(stats); printf(report_bw_format, stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - fflush(stdout); + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void udp_output_write_enhanced (struct TransferInfo *stats) { @@ -934,8 +1180,9 @@ void udp_output_write_enhanced (struct TransferInfo *stats) { outbuffer, outbufferext, stats->sock_callstats.write.WriteCnt, stats->sock_callstats.write.WriteErr, - (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0)); - fflush(stdout); + stats->sock_callstats.write.WriteTimeo, + (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0), (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void udp_output_write_enhanced_isoch (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_pps_enhanced_isoch); @@ -946,8 +1193,8 @@ void udp_output_write_enhanced_isoch (struct TransferInfo *stats) { stats->sock_callstats.write.WriteCnt, stats->sock_callstats.write.WriteErr, (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0), - stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips); - fflush(stdout); + stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } // Sum reports @@ -958,121 +1205,123 @@ void udp_output_sum_read (struct TransferInfo *stats) { stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->cntError, stats->cntDatagrams, - (100.0 * stats->cntError) / stats->cntDatagrams); + ((100.0 * stats->cntError) / stats->cntDatagrams), + (stats->common->Omit ? report_omitted : "")); if ((stats->cntOutofOrder > 0) && stats->final) { printf(report_sum_outoforder, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } - fflush(stdout); + cond_flush(stats); } void udp_output_sumcnt (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw); _print_stats_common(stats); - printf(report_sumcnt_bw_format, stats->threadcnt, + printf(report_sumcnt_bw_format, stats->slot_thread_downcount, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - if ((stats->cntOutofOrder > 0) && stats->final) { + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + if ((stats->cntOutofOrder > 0) && stats->final) { if (isSumOnly(stats->common)) { printf(report_sumcnt_outoforder, - stats->threadcnt, + stats->threadcnt_final, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } else { printf(report_outoforder, stats->common->transferIDStr, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } } - fflush(stdout); + cond_flush(stats); } void udp_output_sumcnt_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw_jitter_loss); _print_stats_common(stats); - printf(report_sumcnt_bw_jitter_loss_format, stats->threadcnt, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, \ - stats->cntError, stats->cntDatagrams, (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0)); + printf(report_sumcnt_bw_jitter_loss_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, \ + stats->cntError, stats->cntDatagrams, (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0), (stats->common->Omit ? report_omitted : "")); if ((stats->cntOutofOrder > 0) && stats->final) { if (isSumOnly(stats->common)) { printf(report_sumcnt_outoforder, - stats->threadcnt, + (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } else { printf(report_sum_outoforder, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder,(stats->common->Omit ? report_omitted : "")); } } - fflush(stdout); + cond_flush(stats); } void udp_output_sumcnt_read_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw_read_enhanced); _print_stats_common(stats); - printf(report_sumcnt_bw_read_enhanced_format, stats->threadcnt, + printf(report_sumcnt_bw_read_enhanced_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, (stats->final) ? ((stats->inline_jitter.total.sum / (double) stats->inline_jitter.total.cnt) * 1e3) : (stats->jitter * 1e3), \ stats->cntError, stats->cntDatagrams, - (100.0 * stats->cntError) / stats->cntDatagrams); + (100.0 * stats->cntError) / stats->cntDatagrams, (stats->common->Omit ? report_omitted : "")); if ((stats->cntOutofOrder > 0) && stats->final) { if (isSumOnly(stats->common)) { printf(report_sumcnt_outoforder, - stats->threadcnt, + (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } else { printf(report_sum_outoforder, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } } - fflush(stdout); + cond_flush(stats); } void udp_output_sumcnt_read_triptime (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_udp_triptime); _print_stats_common(stats); - printf(report_sumcnt_udp_triptime_format, stats->threadcnt, stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, \ - stats->cntError, stats->cntDatagrams, stats->cntIPG, (stats->final ? stats->fInP : stats->iInP), (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0)); - if ((stats->cntOutofOrder > 0) && stats->final) { + printf(report_sumcnt_udp_triptime_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, \ + stats->cntError, stats->cntDatagrams, stats->cntIPG, (stats->final ? stats->fInP : stats->iInP), \ + (stats->cntIPG && (stats->IPGsum > 0.0) ? (stats->cntIPG / stats->IPGsum) : 0.0), (stats->common->Omit ? report_omitted : "")); + if ((stats->cntOutofOrder > 0) && stats->final) { if (isSumOnly(stats->common)) { printf(report_sumcnt_outoforder, - stats->threadcnt, + stats->threadcnt_final, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } else { printf(report_sum_outoforder, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } } - fflush(stdout); + cond_flush(stats); } void udp_output_sum_write (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw); _print_stats_common(stats); printf(report_sum_bw_format, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - fflush(stdout); + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void udp_output_sumcnt_write (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw); _print_stats_common(stats); - printf(report_sumcnt_bw_format, stats->threadcnt, + printf(report_sumcnt_bw_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - fflush(stdout); + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void udp_output_sum_read_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_udp_enhanced); _print_stats_common(stats); - printf(report_sumcnt_udp_enhanced_format, stats->threadcnt, + printf(report_sumcnt_udp_enhanced_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->cntError, stats->cntDatagrams, - (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0)); + (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0), (stats->common->Omit ? report_omitted : "")); if (stats->latency_histogram && stats->final) { histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd); } @@ -1082,16 +1331,16 @@ void udp_output_sum_read_enhanced (struct TransferInfo *stats) { if ((stats->cntOutofOrder > 0) && stats->final) { if (isSumOnly(stats->common)) { printf(report_sumcnt_outoforder, - stats->threadcnt, + stats->threadcnt_final, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } else { printf(report_sum_outoforder, stats->ts.iStart, - stats->ts.iEnd, stats->cntOutofOrder); + stats->ts.iEnd, stats->cntOutofOrder, (stats->common->Omit ? report_omitted : "")); } } - fflush(stdout); + cond_flush(stats); } void udp_output_sum_write_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_pps_enhanced); @@ -1101,19 +1350,19 @@ void udp_output_sum_write_enhanced (struct TransferInfo *stats) { outbuffer, outbufferext, stats->sock_callstats.write.WriteCnt, stats->sock_callstats.write.WriteErr, - ((stats->cntIPG && (stats->IPGsum > 0.0)) ? (stats->cntIPG / stats->IPGsum) : 0.0)); - fflush(stdout); + ((stats->cntIPG && (stats->IPGsum > 0.0)) ? (stats->cntIPG / stats->IPGsum) : 0.0), (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void udp_output_sumcnt_write_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw_pps_enhanced); _print_stats_common(stats); - printf(report_sumcnt_bw_pps_enhanced_format, stats->threadcnt, + printf(report_sumcnt_bw_pps_enhanced_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->sock_callstats.write.WriteCnt, stats->sock_callstats.write.WriteErr, - ((stats->cntIPG && (stats->IPGsum > 0.0)) ? (stats->cntIPG / stats->IPGsum) : 0.0)); - fflush(stdout); + ((stats->cntIPG && (stats->IPGsum > 0.0)) ? (stats->cntIPG / stats->IPGsum) : 0.0), (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_sum_read (struct TransferInfo *stats) { @@ -1121,8 +1370,8 @@ void tcp_output_sum_read (struct TransferInfo *stats) { _print_stats_common(stats); printf(report_sum_bw_format, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - fflush(stdout); + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_sum_read_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_read_enhanced); @@ -1138,24 +1387,24 @@ void tcp_output_sum_read_enhanced (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); + stats->sock_callstats.read.bins[7], (stats->common->Omit ? report_omitted : "")); if (stats->framelatency_histogram && stats->final) { histogram_print(stats->framelatency_histogram, stats->ts.iStart, stats->ts.iEnd); } - fflush(stdout); + cond_flush(stats); } void tcp_output_sumcnt_read (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw); _print_stats_common(stats); - printf(report_sumcnt_bw_format, stats->threadcnt, + printf(report_sumcnt_bw_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - fflush(stdout); + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_sumcnt_read_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw_read_enhanced); _print_stats_common(stats); - printf(report_sumcnt_bw_read_enhanced_format, stats->threadcnt, + printf(report_sumcnt_bw_read_enhanced_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->sock_callstats.read.cntRead, @@ -1166,15 +1415,15 @@ void tcp_output_sumcnt_read_enhanced (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); - fflush(stdout); + stats->sock_callstats.read.bins[7], (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_sumcnt_read_triptime (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw_read_triptime); _print_stats_common(stats); char llaw_bufstr[LLAWBUFSIZE]; human_format_llawbuf(llaw_bufstr, sizeof(llaw_bufstr), ((stats->final) ? stats->fInP : stats->iInP)); - printf(report_sumcnt_bw_read_triptime_format, stats->threadcnt, + printf(report_sumcnt_bw_read_triptime_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, llaw_bufstr, @@ -1186,8 +1435,8 @@ void tcp_output_sumcnt_read_triptime (struct TransferInfo *stats) { stats->sock_callstats.read.bins[4], stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], - stats->sock_callstats.read.bins[7]); - fflush(stdout); + stats->sock_callstats.read.bins[7], (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_sum_write (struct TransferInfo *stats) { @@ -1195,16 +1444,16 @@ void tcp_output_sum_write (struct TransferInfo *stats) { _print_stats_common(stats); printf(report_sum_bw_format, stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - fflush(stdout); + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_sumcnt_write (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw); _print_stats_common(stats); - printf(report_sumcnt_bw_format, stats->threadcnt, + printf(report_sumcnt_bw_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, - outbuffer, outbufferext); - fflush(stdout); + outbuffer, outbufferext, (stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_sum_write_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_bw_write_enhanced); @@ -1217,13 +1466,13 @@ void tcp_output_sum_write_enhanced (struct TransferInfo *stats) { #if HAVE_TCP_STATS ,stats->sock_callstats.write.tcpstats.retry #endif - ); - fflush(stdout); + ,(stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } void tcp_output_sumcnt_write_enhanced (struct TransferInfo *stats) { HEADING_PRINT_COND(report_sumcnt_bw_write_enhanced); _print_stats_common(stats); - printf(report_sumcnt_bw_write_enhanced_format, stats->threadcnt, + printf(report_sumcnt_bw_write_enhanced_format, (stats->final ? stats->threadcnt_final: stats->slot_thread_downcount), stats->ts.iStart, stats->ts.iEnd, outbuffer, outbufferext, stats->sock_callstats.write.WriteCnt, @@ -1231,8 +1480,8 @@ void tcp_output_sumcnt_write_enhanced (struct TransferInfo *stats) { #if HAVE_TCP_STATS ,stats->sock_callstats.write.tcpstats.retry #endif - ); - fflush(stdout); + ,(stats->common->Omit ? report_omitted : "")); + cond_flush(stats); } // CSV outputs @@ -1313,12 +1562,28 @@ void format_ips_port_string (struct TransferInfo *stats, bool sum) { #endif } +static inline void _print_stats_csv_timestr(struct TransferInfo *stats, + char *timestr, int buflen) +{ + iperf_formattime(timestr, + buflen, + (!stats->final ? stats->ts.nextTime : stats->ts.packetTime), + isEnhanced(stats->common), + isUTC(stats->common), + (isEnhanced(stats->common) ? CSVTZ : CSV)); +} + +static inline intmax_t _print_stats_csv_speed(struct TransferInfo *stats) +{ + return (intmax_t) (((stats->cntBytes > 0) && (stats->ts.iEnd - stats->ts.iStart) > 0.0) + ? (((double)stats->cntBytes * 8.0) / (stats->ts.iEnd - stats->ts.iStart)) + : 0); +} + void udp_output_basic_csv (struct TransferInfo *stats) { char timestr[120]; - iperf_formattime(timestr, sizeof(timestr), (!stats->final ? stats->ts.nextTime : stats->ts.packetTime), \ - isEnhanced(stats->common), isUTC(stats->common), (isEnhanced(stats->common) ? CSVTZ : CSV)); - intmax_t speed = (intmax_t) (((stats->cntBytes > 0) && (stats->ts.iEnd - stats->ts.iStart) > 0.0) ? \ - (((double)stats->cntBytes * 8.0) / (stats->ts.iEnd - stats->ts.iStart)) : 0); + _print_stats_csv_timestr(stats, timestr, sizeof(timestr)); + intmax_t speed = _print_stats_csv_speed(stats); printf(reportCSV_bw_jitter_loss_format, timestr, stats->csv_peer, @@ -1331,15 +1596,14 @@ void udp_output_basic_csv (struct TransferInfo *stats) { stats->cntError, stats->cntDatagrams, (100.0 * stats->cntError) / stats->cntDatagrams, stats->cntOutofOrder ); + cond_flush(stats); } void udp_output_enhanced_csv (struct TransferInfo *stats) { - char timestr[80]; - iperf_formattime(timestr, sizeof(timestr), (!stats->final ? stats->ts.nextTime : stats->ts.packetTime), \ - isEnhanced(stats->common), isUTC(stats->common), - isEnhanced(stats->common) ? CSVTZ : CSV); - intmax_t speed = (intmax_t) (((stats->cntBytes > 0) && (stats->ts.iEnd - stats->ts.iStart) > 0.0) ? \ - (((double)stats->cntBytes * 8.0) / (stats->ts.iEnd - stats->ts.iStart)) : 0); + HEADING_PRINT_COND(reportCSV_bw_jitter_loss_pps); + char timestr[120]; + _print_stats_csv_timestr(stats, timestr, sizeof(timestr)); + intmax_t speed = _print_stats_csv_speed(stats); printf(reportCSV_bw_jitter_loss_pps_format, timestr, stats->csv_peer, @@ -1356,14 +1620,13 @@ void udp_output_enhanced_csv (struct TransferInfo *stats) { stats->sock_callstats.write.WriteCnt, stats->sock_callstats.write.WriteErr, (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0)); + cond_flush(stats); } void tcp_output_basic_csv (struct TransferInfo *stats) { - char timestr[80]; - iperf_formattime(timestr, sizeof(timestr), (!stats->final ? stats->ts.nextTime : stats->ts.packetTime), \ - isEnhanced(stats->common), isUTC(stats->common), (isEnhanced(stats->common) ? CSVTZ : CSV)); - intmax_t speed = (intmax_t) (((stats->cntBytes > 0) && (stats->ts.iEnd - stats->ts.iStart) > 0.0) ? \ - (((double)stats->cntBytes * 8.0) / (stats->ts.iEnd - stats->ts.iStart)) : 0); + char timestr[120]; + _print_stats_csv_timestr(stats, timestr, sizeof(timestr)); + intmax_t speed = _print_stats_csv_speed(stats); printf(reportCSV_bw_format, timestr, stats->csv_peer, @@ -1372,15 +1635,14 @@ void tcp_output_basic_csv (struct TransferInfo *stats) { stats->ts.iEnd, stats->cntBytes, speed); + cond_flush(stats); } void tcp_output_read_enhanced_csv (struct TransferInfo *stats) { + HEADING_PRINT_COND(reportCSV_bw_read_enhanced); char timestr[80]; - iperf_formattime(timestr, sizeof(timestr), (!stats->final ? stats->ts.nextTime : stats->ts.packetTime), \ - isEnhanced(stats->common), isUTC(stats->common), - isEnhanced(stats->common) ? CSVTZ : CSV); - intmax_t speed = (intmax_t) (((stats->cntBytes > 0) && (stats->ts.iEnd - stats->ts.iStart) > 0.0) ? \ - (((double)stats->cntBytes * 8.0) / (stats->ts.iEnd - stats->ts.iStart)) : 0); + _print_stats_csv_timestr(stats, timestr, sizeof(timestr)); + intmax_t speed = _print_stats_csv_speed(stats); printf(reportCSV_bw_read_enhanced_format, timestr, stats->csv_peer, @@ -1398,15 +1660,14 @@ void tcp_output_read_enhanced_csv (struct TransferInfo *stats) { stats->sock_callstats.read.bins[5], stats->sock_callstats.read.bins[6], stats->sock_callstats.read.bins[7]); + cond_flush(stats); } void tcp_output_write_enhanced_csv (struct TransferInfo *stats) { - char timestr[80]; - iperf_formattime(timestr, sizeof(timestr), (!stats->final ? stats->ts.nextTime : stats->ts.packetTime), \ - isEnhanced(stats->common), isUTC(stats->common), - isEnhanced(stats->common) ? CSVTZ : CSV); - intmax_t speed = (intmax_t) (((stats->cntBytes > 0) && (stats->ts.iEnd - stats->ts.iStart) > 0.0) ? \ - (((double)stats->cntBytes * 8.0) / (stats->ts.iEnd - stats->ts.iStart)) : 0); + HEADING_PRINT_COND(reportCSV_bw_write_enhanced); + char timestr[120]; + _print_stats_csv_timestr(stats, timestr, sizeof(timestr)); + intmax_t speed = _print_stats_csv_speed(stats); #if !(HAVE_TCP_STATS) printf(reportCSV_bw_write_enhanced_format, timestr, @@ -1420,6 +1681,7 @@ void tcp_output_write_enhanced_csv (struct TransferInfo *stats) { -1, -1, -1, + -1, 0, 0); #else @@ -1437,9 +1699,11 @@ void tcp_output_write_enhanced_csv (struct TransferInfo *stats) { stats->sock_callstats.write.WriteErr, stats->sock_callstats.write.tcpstats.retry, -1, + -1, 0, 0); - } else if (stats->sock_callstats.write.tcpstats.cwnd > 0) { + } else { +#if HAVE_STRUCT_TCP_INFO_TCPI_SND_CWND printf(reportCSV_bw_write_enhanced_format, timestr, stats->csv_peer, @@ -1452,9 +1716,10 @@ void tcp_output_write_enhanced_csv (struct TransferInfo *stats) { stats->sock_callstats.write.WriteErr, stats->sock_callstats.write.tcpstats.retry, stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.cwnd_packets, stats->sock_callstats.write.tcpstats.rtt, stats->sock_callstats.write.tcpstats.rttvar); - } else { +#else printf(reportCSV_bw_write_enhanced_format, timestr, stats->csv_peer, @@ -1467,10 +1732,101 @@ void tcp_output_write_enhanced_csv (struct TransferInfo *stats) { stats->sock_callstats.write.WriteErr, stats->sock_callstats.write.tcpstats.retry, -1, + -1, stats->sock_callstats.write.tcpstats.rtt, 0); +#endif } #endif + cond_flush(stats); +} + +void tcp_output_write_bb_csv (struct TransferInfo *stats) { + HEADING_PRINT_COND(reportCSV_client_bb_bw_tcp); + char timestr[120]; + _print_stats_csv_timestr(stats, timestr, sizeof(timestr)); + intmax_t speed = _print_stats_csv_speed(stats); + if (stats->final) { + double rps = ((stats->fBBrunning > 0) && (stats->bbrtt.total.cnt > 0)) ? ((double) stats->bbrtt.total.cnt / stats->fBBrunning) : 0; + +#if HAVE_TCP_STATS + printf(reportCSV_client_bb_bw_tcp_format, + timestr, + stats->csv_peer, + stats->common->transferID, + stats->ts.iStart, + stats->ts.iEnd, + stats->cntBytes, + speed, + stats->bbrtt.total.cnt, + (stats->bbrtt.total.mean * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.min * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.max * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.total.m2 / (stats->bbrtt.total.cnt - 1))), + stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.rtt, + rps); +#else + printf(reportCSV_client_bb_bw_tcp_format, + timestr, + stats->csv_peer, + stats->common->transferID, + stats->ts.iStart, + stats->ts.iEnd, + stats->cntBytes, + speed, + stats->bbrtt.total.cnt, + (stats->bbrtt.total.mean * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.min * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : (stats->bbrtt.total.max * 1e3), + (stats->bbrtt.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.total.m2 / (stats->bbrtt.total.cnt - 1))), + -1, + -1, + -1, + rps); +#endif + } else { + double rps = ((stats->bbrtt.current.cnt > 0) && (stats->iBBrunning > 0)) ? ((double) stats->bbrtt.current.cnt / stats->iBBrunning) : 0; +#if HAVE_TCP_STATS + printf(reportCSV_client_bb_bw_tcp_format, + timestr, + stats->csv_peer, + stats->common->transferID, + stats->ts.iStart, + stats->ts.iEnd, + stats->cntBytes, + speed, + stats->bbrtt.current.cnt, + (stats->bbrtt.current.mean * 1e3), + (stats->bbrtt.current.cnt < 2) ? 0 : (stats->bbrtt.current.min * 1e3), + (stats->bbrtt.current.cnt < 2) ? 0 : (stats->bbrtt.current.max * 1e3), + (stats->bbrtt.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.current.m2 / (stats->bbrtt.current.cnt - 1))), + stats->sock_callstats.write.tcpstats.retry, + stats->sock_callstats.write.tcpstats.cwnd, + stats->sock_callstats.write.tcpstats.rtt, + rps); +#else + printf(reportCSV_client_bb_bw_tcp_format, + timestr, + stats->csv_peer, + stats->common->transferID, + stats->ts.iStart, + stats->ts.iEnd, + stats->cntBytes, + speed, + stats->bbrtt.current.cnt, + (stats->bbrtt.current.mean * 1e3), + (stats->bbrtt.current.cnt < 2) ? 0 : (stats->bbrtt.current.min * 1e3), + (stats->bbrtt.current.cnt < 2) ? 0 : (stats->bbrtt.current.max * 1e3), + (stats->bbrtt.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbrtt.current.m2 / (stats->bbrtt.current.cnt - 1))), + -1, + -1, + -1, + rps); +#endif + } + cond_flush(stats); } /* @@ -1498,7 +1854,11 @@ static void reporter_output_listener_settings (struct ReportSettings *report) { report->common->Port, report->common->PortLast, report->pid); } else { printf(isEnhanced(report->common) ? server_pid_port : server_port, - (isUDP(report->common) ? "UDP" : "TCP"), report->common->Port, report->pid); + (isUDP(report->common) ? ((isIPV6(report->common) && isEnhanced(report->common)) ? "UDP (v6)" : "UDP") : \ + ((isIPV6(report->common) && isEnhanced(report->common)) ? "TCP (v6)" : "TCP")), report->common->Port, report->pid); + } + if (isUDP(report->common) && isWorkingLoadUp(report->common) && isWorkingLoadDown(report->common)) { + printf(server_working_load_port, "TCP", report->common->Port); } if (report->common->Localhost != NULL) { if (isEnhanced(report->common) && !SockAddr_isMulticast(&report->local)) { @@ -1543,17 +1903,36 @@ static void reporter_output_listener_settings (struct ReportSettings *report) { printf(bind_address_iface_taptun, report->common->Ifrname); } if (isEnhanced(report->common)) { - byte_snprintf(outbuffer, sizeof(outbuffer), report->common->BufLen, toupper((int)report->common->Format)); - byte_snprintf(outbufferext, sizeof(outbufferext), report->common->BufLen / 8, 'A'); - outbuffer[(sizeof(outbuffer)-1)] = '\0'; - outbufferext[(sizeof(outbufferext)-1)] = '\0'; - printf("%s: %s (Dist bin width=%s)\n", server_read_size, outbuffer, outbufferext); + if (!(isUDP(report->common))) { + byte_snprintf(outbuffer, sizeof(outbuffer), report->common->BufLen, toupper((int)report->common->Format)); + byte_snprintf(outbufferext, sizeof(outbufferext), report->common->BufLen / 8, 'A'); + outbuffer[(sizeof(outbuffer)-1)] = '\0'; + outbufferext[(sizeof(outbufferext)-1)] = '\0'; + printf("%s: %s (Dist bin width=%s)\n", server_read_size, outbuffer, outbufferext); + } else { + byte_snprintf(outbuffer, sizeof(outbuffer), report->common->BufLen, 'B'); + outbuffer[(sizeof(outbuffer)-1)] = '\0'; + printf("%s: %s \n", server_read_size, outbuffer); + } + } - if (isCongestionControl(report->common) && report->common->Congestion) { - fprintf(stdout, "TCP congestion control set to %s\n", report->common->Congestion); +#if HAVE_DECL_TCP_CONGESTION + if (isCongestionControl(report->common) || isEnhanced(report->common)) { + char cca[40] = ""; + Socklen_t len = sizeof(cca); + if (getsockopt(report->common->socket, IPPROTO_TCP, TCP_CONGESTION, &cca, &len) == 0) { + cca[len]='\0'; + } + if (report->common->Congestion) { + fprintf(stdout,"TCP congestion control default set to %s using %s\n", report->common->Congestion, cca); + } else if (strlen(cca)) { + fprintf(stdout,"TCP congestion control default %s\n", cca); + } } +#endif if (isOverrideTOS(report->common)) { - fprintf(stdout, "Reflected TOS will be set to 0x%x\n", report->common->RTOS); + fprintf(stdout, "Reflected TOS will be set to 0x%x (dscp=%d,ecn=%d)\n", report->common->RTOS, \ + DSCP_VALUE(report->common->RTOS), ECN_VALUE(report->common->RTOS)); } if (isPrintMSS(report->common)) { if (isTCPMSS(report->common)) { @@ -1563,7 +1942,8 @@ static void reporter_output_listener_settings (struct ReportSettings *report) { } } if (report->common->TOS) { - fprintf(stdout, "TOS will be set to 0x%x\n", report->common->TOS); + fprintf(stdout, "TOS will be set to 0x%x (dscp=%d,ecn=%d)\n", report->common->TOS, \ + DSCP_VALUE(report->common->RTOS), ECN_VALUE(report->common->RTOS)); } if (isUDP(report->common)) { if (isSingleClient(report->common)) { @@ -1574,7 +1954,7 @@ static void reporter_output_listener_settings (struct ReportSettings *report) { } else if (isSingleClient(report->common)) { fprintf(stdout, "Server set to single client traffic mode (serialize traffic tests)\n"); } - if (isMulticast(report->common)) { + if (isMulticast(report->common) && (report->common->Port == report->common->PortLast)) { fprintf(stdout, "Server set to single client traffic mode (per multicast receive)\n"); } if (isHistogram(report->common)) { @@ -1608,19 +1988,31 @@ static void reporter_output_client_settings (struct ReportSettings *report) { if (!report->common->Ifrnametx) { printf(isEnhanced(report->common) ? client_pid_port : client_port, hoststr, (isUDP(report->common) ? "UDP" : "TCP"), report->common->Port, report->pid, \ - (!report->common->threads ? 1 : report->common->threads)); + (!report->common->threads ? 1 : report->common->threads), + (!report->common->threads ? 1 : report->common->working_load_threads)); } else { printf(client_pid_port_dev, hoststr, (isUDP(report->common) ? "UDP" : "TCP"), report->common->Port, report->pid, \ - report->common->Ifrnametx, (!report->common->threads ? 1 : report->common->threads)); + report->common->Ifrnametx, (!report->common->threads ? 1 : report->common->threads), + (!report->common->threads ? 1 : report->common->working_load_threads)); } - if ((isEnhanced(report->common) || isNearCongest(report->common)) && !isUDP(report->common)) { + if ((isEnhanced(report->common) || isNearCongest(report->common)) && !isUDP(report->common) && !isBounceBack(report->common)) { byte_snprintf(outbuffer, sizeof(outbuffer), report->common->BufLen, 'B'); outbuffer[(sizeof(outbuffer)-1)] = '\0'; - if (isTcpWriteTimes(report->common)) { - printf("%s: %s (writetimer-enabled)\n", client_write_size, outbuffer); + if (!isBurstSize(report->common)) { + if (isTcpWriteTimes(report->common)) { + printf("%s: %s (write timer enabled)\n", client_write_size, outbuffer); + } else { + printf("%s: %s\n", client_write_size, outbuffer); + } } else { - printf("%s: %s\n", client_write_size, outbuffer); + byte_snprintf(outbufferext, sizeof(outbufferext), report->common->BurstSize, 'B'); + outbufferext[(sizeof(outbufferext)-1)] = '\0'; + if (isTcpWriteTimes(report->common)) { + printf("%s: %s Burst size: %s (write timer enabled)\n", client_write_size, outbuffer, outbufferext); + } else { + printf("%s: %s Burst size: %s\n", client_write_size, outbuffer, outbufferext); + } } } if (isIsochronous(report->common)) { @@ -1631,30 +2023,47 @@ static void reporter_output_client_settings (struct ReportSettings *report) { meanbuf[39]='\0'; variancebuf[39]='\0'; printf(client_isochronous, report->isochstats.mFPS, meanbuf, variancebuf, (report->isochstats.mBurstInterval/1000.0), (report->isochstats.mBurstIPG/1000.0)); } - if (isPeriodicBurst(report->common)) { - char tmpbuf[40]; - byte_snprintf(tmpbuf, sizeof(tmpbuf), report->common->BurstSize, 'A'); - tmpbuf[39]='\0'; - if (report->common->bbcount) { - printf(client_burstperiodcount, tmpbuf, report->common->bbcount, (1.0 / report->common->FPS)); - } else { - printf(client_burstperiod, tmpbuf, (1.0 / report->common->FPS)); - } - } if (isBounceBack(report->common)) { - char tmpbuf[40]; - byte_snprintf(tmpbuf, sizeof(tmpbuf), report->common->bbsize, 'A'); - tmpbuf[39]='\0'; + char tmplbuf[40]; + byte_snprintf(tmplbuf, sizeof(tmplbuf), report->common->bbsize, 'A'); + tmplbuf[39]='\0'; + char tmprbuf[40]; + byte_snprintf(tmprbuf, sizeof(tmprbuf), report->common->bbreplysize, 'A'); + tmprbuf[39]='\0'; if (isTcpQuickAck(report->common)) { - printf(client_bounceback, tmpbuf, report->common->bbhold); + printf(client_bounceback, tmplbuf, tmprbuf, report->common->bbhold); } else { - printf(client_bounceback_noqack, tmpbuf, report->common->bbhold); + printf(client_bounceback_noqack, tmplbuf, tmprbuf, report->common->bbhold); + } + if (report->common->FPS > 0) { + printf(client_bbburstperiodcount, report->common->bbcount, (1.0 / report->common->FPS)); + } + } else { + if (isPeriodicBurst(report->common) && (report->common->FPS > 0)) { + char tmpbuf[40]; + byte_snprintf(tmpbuf, sizeof(tmpbuf), report->common->BurstSize, 'A'); + tmpbuf[39]='\0'; + if (report->common->bbcount) { + printf(client_burstperiodcount, tmpbuf, report->common->bbcount, (1.0 / report->common->FPS)); + } else { + printf(client_burstperiod, tmpbuf, (1.0 / report->common->FPS)); + } } } if (isFQPacing(report->common)) { - byte_snprintf(outbuffer, sizeof(outbuffer), report->common->FQPacingRate, 'a'); - outbuffer[(sizeof(outbuffer)-1)] = '\0'; - printf(client_fq_pacing,outbuffer); + char prate[40]; + byte_snprintf(prate, sizeof(prate), report->common->FQPacingRate, 'a'); + prate[39] = '\0'; + if (isFQPacingStep(report->common)) { + char pratestep[40]; + byte_snprintf(pratestep, sizeof(pratestep), report->common->FQPacingRateStep, 'a'); + pratestep[39] = '\0'; + printf(client_fq_pacing_step,prate, pratestep); + } else { + byte_snprintf(outbuffer, sizeof(outbuffer), report->common->FQPacingRate, 'a'); + outbuffer[(sizeof(outbuffer)-1)] = '\0'; + printf(client_fq_pacing,outbuffer); + } } if (isPrintMSS(report->common)) { if (isTCPMSS(report->common)) { @@ -1663,16 +2072,41 @@ static void reporter_output_client_settings (struct ReportSettings *report) { printf(report_default_mss, report->sockmaxseg); } } - - if (isCongestionControl(report->common) && report->common->Congestion) { - fprintf(stdout, "TCP congestion control set to %s\n", report->common->Congestion); +#if HAVE_DECL_TCP_CONGESTION + if (isCongestionControl(report->common) || isEnhanced(report->common)) { + char cca[40] = ""; + Socklen_t len = sizeof(cca); + if (getsockopt(report->common->socket, IPPROTO_TCP, TCP_CONGESTION, &cca, &len) == 0) { + cca[len]='\0'; + } + if (report->common->Congestion) { + fprintf(stdout,"TCP congestion control set to %s using %s\n", report->common->Congestion, cca); + } else if (strlen(cca)) { + fprintf(stdout,"TCP congestion control using %s\n", cca); + } + } + if ((isWorkingLoadUp(report->common) || isWorkingLoadDown(report->common)) && isLoadCCA(report->common)) { + fprintf(stdout,"TCP working load congestion control set to %s\n", report->common->LoadCCA); } +#endif if (isEnhanced(report->common)) { + char strtext[10]; + if (isSetTOS(report->common)) { + strcpy(strtext, "set"); + } else { + strcpy(strtext, "defaults"); + } + fprintf(stdout, "TOS %s to 0x%x (dscp=%d,ecn=%d)", strtext, report->common->TOS, \ + DSCP_VALUE(report->common->TOS), ECN_VALUE(report->common->TOS)); + if (ECN_VALUE(report->common->TOS)) { + fprintf(stdout, " (warn ecn bits set)"); + } if (isNoDelay(report->common)) { - fprintf(stdout, "TOS set to 0x%x and nodelay (Nagle off)\n", report->common->TOS); + fprintf(stdout," and nodelay (Nagle off)"); } else { - fprintf(stdout, "TOS set to 0x%x (Nagle on)\n", report->common->TOS); + fprintf(stdout," (Nagle on)"); } + fprintf(stdout, "\n"); } if (isNearCongest(report->common)) { if (report->common->rtt_weight == NEARCONGEST_DEFAULT) { @@ -1716,15 +2150,23 @@ static void reporter_output_client_settings (struct ReportSettings *report) { fflush(stdout); } +#define MINSAMPLES_FORVARIANCE 25 void reporter_connect_printf_tcp_final (struct ConnectionInfo * report) { - if (report->connect_times.cnt > 1) { - double variance = (report->connect_times.cnt < 2) ? 0 : 1e3* (sqrt(report->connect_times.m2 / (report->connect_times.cnt - 1))); + if (report->connect_times.cnt >= MINSAMPLES_FORVARIANCE) { + double variance = (sqrt(report->connect_times.m2 / (report->connect_times.cnt - 1))); fprintf(stdout, "[ CT] final connect times (min/avg/max/stdev) = %0.3f/%0.3f/%0.3f/%0.3f ms (tot/err) = %" PRIdMAX "/%" PRIdMAX "\n", \ report->connect_times.min, \ (report->connect_times.sum / report->connect_times.cnt), \ report->connect_times.max, variance, \ (report->connect_times.cnt + report->connect_times.err), \ report->connect_times.err); + } else if (report->connect_times.cnt > 2) { + fprintf(stdout, "[ CT] final connect times (min/avg/max) = %0.3f/%0.3f/%0.3f ms (tot/err) = %" PRIdMAX "/%" PRIdMAX "\n", \ + report->connect_times.min, \ + (report->connect_times.sum / report->connect_times.cnt), \ + report->connect_times.max, \ + (report->connect_times.cnt + report->connect_times.err), \ + report->connect_times.err); } fflush(stdout); } @@ -1739,7 +2181,6 @@ void reporter_print_connection_report (struct ConnectionInfo *report) { outbuffer[0]='\0'; outbufferext[0]='\0'; char *b = &outbuffer[0]; - #if HAVE_DECL_TCP_WINDOW_CLAMP if (!isUDP(report->common) && isRxClamp(report->common)) { snprintf(b, SNBUFFERSIZE-strlen(b), " (%s%d)", "clamp=", report->common->ClampSize); @@ -1781,9 +2222,11 @@ void reporter_print_connection_report (struct ConnectionInfo *report) { } if (isBounceBack(report->common)) { if (isTcpQuickAck(report->common)) { - snprintf(b, SNBUFFERSIZE-strlen(b), " (bb w/quickack len/hold=%d/%d)", report->common->bbsize, report->common->bbhold); + snprintf(b, SNBUFFERSIZE-strlen(b), " (bb w/quickack req/reply/hold=%d/%d/%d)", report->common->bbsize, \ + report->common->bbreplysize, report->common->bbhold); } else { - snprintf(b, SNBUFFERSIZE-strlen(b), " (bb len/hold=%d/%d)", report->common->bbsize, report->common->bbhold); + snprintf(b, SNBUFFERSIZE-strlen(b), " (bb req/reply/hold=%d/%d/%d)", report->common->bbsize, \ + report->common->bbreplysize, report->common->bbhold); } b += strlen(b); } @@ -1800,23 +2243,47 @@ void reporter_print_connection_report (struct ConnectionInfo *report) { b += strlen(b); } if (isEnhanced(report->common)) { - snprintf(b, SNBUFFERSIZE-strlen(b), " (sock=%d)", report->common->socket);; - b += strlen(b); + if (isCongestionControl(report->common)) { +#if HAVE_DECL_TCP_CONGESTION + char cca[40] = ""; + Socklen_t len = sizeof(cca); + int rc; + if ((rc = getsockopt(report->common->socket, IPPROTO_TCP, TCP_CONGESTION, &cca, &len)) == 0) { + cca[len]='\0'; + } + if (rc != SOCKET_ERROR) { + snprintf(b, SNBUFFERSIZE-strlen(b), " (sock=%d/%s)", report->common->socket, cca); + b += strlen(b); + } +#endif + } else { + snprintf(b, SNBUFFERSIZE-strlen(b), " (sock=%d)", report->common->socket); + b += strlen(b); + } } if (isOverrideTOS(report->common)) { if (isFullDuplex(report->common)) { - snprintf(b, SNBUFFERSIZE-strlen(b), " (tos rx/tx=0x%x/0x%x)", report->common->TOS, report->common->RTOS); + snprintf(b, SNBUFFERSIZE-strlen(b), " (tos rx/tx=0x%x,dscp=%d,ecn=%d, /0x%x,dscp=%d,ecn=%d)", report->common->TOS, \ + DSCP_VALUE(report->common->TOS), ECN_VALUE(report->common->TOS), \ + report->common->RTOS, \ + DSCP_VALUE(report->common->RTOS), ECN_VALUE(report->common->RTOS)); } else if (isReverse(report->common)) { - snprintf(b, SNBUFFERSIZE-strlen(b), " (tos tx=0x%x)", report->common->TOS); + snprintf(b, SNBUFFERSIZE-strlen(b), " (tos rx=0x%x,dscp=%d,ecn=%d)", report->common->TOS, \ + DSCP_VALUE(report->common->TOS), ECN_VALUE(report->common->TOS)); } b += strlen(b); } else if (report->common->TOS) { if (isFullDuplex(report->common) || isBounceBack(report->common)) { - snprintf(b, SNBUFFERSIZE-strlen(b), " (tos rx/tx=0x%x/0x%x)", report->common->TOS, report->common->TOS); + snprintf(b, SNBUFFERSIZE-strlen(b), " (tos rx/tx=0x%x,dscp=%d,ecn=%d/0x%x,dscp=%d,ecn=%d)", report->common->TOS, \ + DSCP_VALUE(report->common->TOS), ECN_VALUE(report->common->TOS), \ + report->common->TOS, \ + DSCP_VALUE(report->common->TOS), ECN_VALUE(report->common->TOS)); } else if (isReverse(report->common)) { - snprintf(b, SNBUFFERSIZE-strlen(b), " (tos tx=0x%x)", report->common->TOS); + snprintf(b, SNBUFFERSIZE-strlen(b), " (tos rx=0x%x,dscp=%d,ecn=%d)", report->common->TOS, \ + DSCP_VALUE(report->common->TOS), ECN_VALUE(report->common->TOS)); } else { - snprintf(b, SNBUFFERSIZE-strlen(b), " (tos rx=0x%x)", report->common->TOS); + snprintf(b, SNBUFFERSIZE-strlen(b), " (tos tx=0x%x,dscp=%d,ecn=%d)", report->common->TOS, \ + DSCP_VALUE(report->common->TOS), ECN_VALUE(report->common->TOS)); } b += strlen(b); } @@ -1833,13 +2300,12 @@ void reporter_print_connection_report (struct ConnectionInfo *report) { } #endif #if HAVE_TCP_STATS - if (!isUDP(report->common) && (report->tcpinitstats.isValid)) { - snprintf(b, SNBUFFERSIZE-strlen(b), " (icwnd/mss/irtt=%u/%u/%u)", \ + if (!isUDP(report->common) && (report->tcpinitstats.isValid) && isEnhanced(report->common)) { + snprintf(b, SNBUFFERSIZE-strlen(b), " (icwnd/mss/irtt=%" PRIdMAX "/%" PRIuLEAST32 "/%" PRIuLEAST32 ")", \ report->tcpinitstats.cwnd, report->tcpinitstats.mss_negotiated, report->tcpinitstats.rtt); b += strlen(b); } #endif - if ((isFullDuplex(report->common) || !isServerReverse(report->common)) \ && (isEnhanced(report->common) || isConnectOnly(report->common))) { if (report->connect_timestamp.tv_sec > 0) { @@ -1923,14 +2389,7 @@ void reporter_print_connection_report (struct ConnectionInfo *report) { if ((report->common->ThreadMode == kMode_Client) && !isServerReverse(report->common)) { if (isTxHoldback(report->common) || isTxStartTime(report->common)) { struct timeval now; -#ifdef HAVE_CLOCK_GETTIME - struct timespec t1; - clock_gettime(CLOCK_REALTIME, &t1); - now.tv_sec = t1.tv_sec; - now.tv_usec = t1.tv_nsec / 1000; -#else - gettimeofday(&now, NULL); -#endif + TimeGetNow(now); int seconds_from_now; if (isTxHoldback(report->common)) { seconds_from_now = report->txholdbacktime.tv_sec; |