summaryrefslogtreecommitdiffstats
path: root/src/ReportOutputs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ReportOutputs.c')
-rw-r--r--src/ReportOutputs.c2019
1 files changed, 2019 insertions, 0 deletions
diff --git a/src/ReportOutputs.c b/src/ReportOutputs.c
new file mode 100644
index 0000000..e977433
--- /dev/null
+++ b/src/ReportOutputs.c
@@ -0,0 +1,2019 @@
+/*---------------------------------------------------------------
+ * Copyright (c) 2020
+ * Broadcom Corporation
+ * All Rights Reserved.
+ *---------------------------------------------------------------
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ *
+ * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and
+ * the following disclaimers.
+ *
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimers in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ *
+ * Neither the name of Broadcom Coporation,
+ * nor the names of its contributors may be used to endorse
+ * or promote products derived from this Software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * ________________________________________________________________
+ *
+ * reporter output routines
+ *
+ * by Robert J. McMahon (rjmcmahon@rjmcmahon.com, bob.mcmahon@broadcom.com)
+ * -------------------------------------------------------------------
+ */
+#include <math.h>
+#include "headers.h"
+#include "Settings.hpp"
+#include "Reporter.h"
+#include "Locale.h"
+#include "SocketAddr.h"
+#include "iperf_formattime.h"
+
+// These static variables are not thread safe but ok to use becase only
+// the repoter thread usses them
+#define SNBUFFERSIZE 512
+#define SNBUFFEREXTENDSIZE 512
+static char outbuffer[SNBUFFERSIZE]; // Buffer for printing
+static char outbufferext[SNBUFFEREXTENDSIZE]; // Buffer for printing
+
+#define LLAWBUFSIZE 100
+static char netpower_buf[100];
+
+static int HEADING_FLAG(report_bw) = 0;
+static int HEADING_FLAG(report_client_bb_bw) = 0;
+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_write_enhanced_write) = 0;
+static int HEADING_FLAG(report_bw_write_enhanced_netpwr) = 0;
+static int HEADING_FLAG(report_bw_pps_enhanced) = 0;
+static int HEADING_FLAG(report_bw_pps_enhanced_isoch) = 0;
+static int HEADING_FLAG(report_bw_jitter_loss_pps) = 0;
+static int HEADING_FLAG(report_bw_jitter_loss_enhanced) = 0;
+static int HEADING_FLAG(report_bw_jitter_loss_enhanced_isoch) = 0;
+static int HEADING_FLAG(report_write_enhanced_isoch) = 0;
+static int HEADING_FLAG(report_frame_jitter_loss_enhanced) = 0;
+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;
+static int HEADING_FLAG(report_sumcnt_bw_pps_enhanced) = 0;
+static int HEADING_FLAG(report_bw_jitter_loss_enhanced_triptime) = 0;
+static int HEADING_FLAG(report_bw_jitter_loss_enhanced_isoch_triptime) = 0;
+static int HEADING_FLAG(report_sumcnt_bw_jitter_loss) = 0;
+static int HEADING_FLAG(report_burst_read_tcp) = 0;
+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;
+
+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_write_enhanced_write) = flag;
+ HEADING_FLAG(report_write_enhanced_isoch) = flag;
+ HEADING_FLAG(report_bw_write_enhanced_netpwr) = flag;
+ HEADING_FLAG(report_bw_pps_enhanced) = flag;
+ HEADING_FLAG(report_bw_pps_enhanced_isoch) = flag;
+ HEADING_FLAG(report_bw_jitter_loss_pps) = flag;
+ HEADING_FLAG(report_bw_jitter_loss_enhanced) = flag;
+ HEADING_FLAG(report_bw_jitter_loss_enhanced_isoch) = flag;
+ HEADING_FLAG(report_frame_jitter_loss_enhanced) = flag;
+ HEADING_FLAG(report_frame_tcp_enhanced) = flag;
+ HEADING_FLAG(report_frame_read_tcp_enhanced_triptime) = flag;
+ HEADING_FLAG(report_sumcnt_bw_read_enhanced) = flag;
+ HEADING_FLAG(report_sumcnt_bw_read_triptime) = flag;
+ HEADING_FLAG(report_sumcnt_bw_write_enhanced) = flag;
+ HEADING_FLAG(report_udp_fullduplex) = flag;
+ HEADING_FLAG(report_sumcnt_bw_jitter_loss) = flag;
+ HEADING_FLAG(report_sumcnt_bw_pps_enhanced) = flag;
+ HEADING_FLAG(report_burst_read_tcp) = flag;
+ HEADING_FLAG(report_burst_write_tcp) = flag;
+ HEADING_FLAG(report_bw_isoch_enhanced_netpwr) = flag;
+ HEADING_FLAG(report_sumcnt_udp_enhanced) = flag;
+ HEADING_FLAG(report_sumcnt_udp_triptime) = flag;
+}
+static inline void _print_stats_common (struct TransferInfo *stats) {
+ assert(stats!=NULL);
+ outbuffer[0] = '\0';
+ outbufferext[0] = '\0';
+ byte_snprintf(outbuffer, sizeof(outbuffer), (double) stats->cntBytes, toupper((int)stats->common->Format));
+ if (stats->ts.iEnd < SMALLEST_INTERVAL_SEC) {
+ stats->cntBytes = 0;
+ }
+ byte_snprintf(outbufferext, sizeof(outbufferext), (double)stats->cntBytes / (stats->ts.iEnd - stats->ts.iStart), \
+ stats->common->Format);
+ outbuffer[sizeof(outbuffer)-1]='\0';
+ outbufferext[sizeof(outbufferext)-1]='\0';
+}
+
+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);
+ }
+ 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);
+ }
+}
+
+//
+// Little's law is L = lambda * W, where L is queue depth,
+// lambda the arrival rate and W is the processing time
+//
+#define LLAW_LOWERBOUNDS -1e7
+
+static inline void human_format_llawbuf(char *dststr, size_t len, double inP) {
+ if (inP < LLAW_LOWERBOUNDS) {
+ char oobstr[] = "OBL";
+ if (len > sizeof(oobstr))
+ strcpy(dststr, oobstr);
+ } else {
+ //force to adpative bytes for human readable
+ byte_snprintf(dststr, len, inP, 'A');
+ dststr[len-1] = '\0';
+ }
+}
+
+#if 0
+static inline void set_llawbuf_frames (int lambda, double meantransit, double variance, intmax_t framecnt) {
+ int Lvar = 0;
+ int L = round(lambda * meantransit);
+ if (variance > 0.0) {
+ Lvar = round(lambda * variance);
+ } else {
+ Lvar = 0;
+ }
+ snprintf(llaw_buf, sizeof(llaw_buf), "%" PRIdMAX "/%d(%d) frames", framecnt, L, Lvar);
+ llaw_buf[sizeof(llaw_buf) - 1] = '\0';
+}
+#endif
+
+#define NETPWR_LOWERBOUNDS -1e7
+static inline void set_netpowerbuf(double meantransit, struct TransferInfo *stats) {
+ if (meantransit == 0.0) {
+ strcpy(netpower_buf, "NAN");
+ } else {
+ double netpwr = NETPOWERCONSTANT * (((double) stats->cntBytes) / (stats->ts.iEnd - stats->ts.iStart) / meantransit);
+ if (netpwr < NETPWR_LOWERBOUNDS) {
+ strcpy(netpower_buf, "OBL");
+ } else if (netpwr > 100) {
+ snprintf(netpower_buf, sizeof(netpower_buf), "%.0f", netpwr);
+ } else if (netpwr > 10) {
+ snprintf(netpower_buf, sizeof(netpower_buf), "%.2f", netpwr);
+ } else {
+ snprintf(netpower_buf, sizeof(netpower_buf), "%.6f", netpwr);
+ }
+ }
+}
+
+//TCP Output
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+//TCP read or server output
+void tcp_output_read_enhanced (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_read_enhanced);
+ _print_stats_common(stats);
+ printf(report_bw_read_enhanced_format,
+ stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ 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);
+}
+void tcp_output_read_triptime (struct TransferInfo *stats) {
+ double meantransit;
+ HEADING_PRINT_COND(report_bw_read_enhanced_netpwr);
+ char llaw_bufstr[LLAWBUFSIZE];
+ human_format_llawbuf(llaw_bufstr, sizeof(llaw_bufstr), ((stats->final) ? stats->fInP : stats->iInP));
+ _print_stats_common(stats);
+ if (!stats->final) {
+ meantransit = (stats->transit.current.cnt > 0) ? (stats->transit.current.sum / stats->transit.current.cnt) : 0;
+ set_netpowerbuf(meantransit, stats);
+ printf(report_bw_read_enhanced_netpwr_format,
+ stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ (meantransit * 1e3),
+ (stats->transit.current.cnt < 2) ? 0 : stats->transit.current.min * 1e3,
+ (stats->transit.current.cnt < 2) ? 0 : stats->transit.current.max * 1e3,
+ (stats->transit.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->transit.current.m2 / (stats->transit.current.cnt - 1))),
+ stats->transit.current.cnt,
+ stats->transit.current.cnt ? (long) ((double)stats->cntBytes / (double) stats->transit.current.cnt) : 0,
+ llaw_bufstr,
+ netpower_buf,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ stats->sock_callstats.read.bins[4],
+ stats->sock_callstats.read.bins[5],
+ stats->sock_callstats.read.bins[6],
+ stats->sock_callstats.read.bins[7]);
+ } else {
+ meantransit = (stats->transit.total.cnt > 0) ? (stats->transit.total.sum / stats->transit.total.cnt) : 0;
+ set_netpowerbuf(meantransit, stats);
+ printf(report_bw_read_enhanced_netpwr_format,
+ stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ (meantransit * 1e3),
+ stats->transit.total.min * 1e3,
+ stats->transit.total.max * 1e3,
+ (stats->transit.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->transit.total.m2 / (stats->transit.total.cnt - 1))),
+ stats->transit.total.cnt,
+ stats->transit.total.cnt ? (long) ((double)stats->cntBytes / (double) stats->transit.total.cnt) : 0,
+ llaw_bufstr,
+ netpower_buf,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ stats->sock_callstats.read.bins[4],
+ stats->sock_callstats.read.bins[5],
+ stats->sock_callstats.read.bins[6],
+ stats->sock_callstats.read.bins[7]);
+ }
+ if (stats->framelatency_histogram) {
+ histogram_print(stats->framelatency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ fflush(stdout);
+}
+void tcp_output_read_enhanced_isoch (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_isoch_enhanced_netpwr);
+ _print_stats_common(stats);
+ double meantransit;
+ if (!stats->final) {
+ meantransit = (stats->isochstats.transit.current.cnt > 0) ? (stats->isochstats.transit.current.sum / stats->isochstats.transit.current.cnt) : 0;
+ set_netpowerbuf(meantransit, stats);
+ printf(report_bw_isoch_enhanced_netpwr_format,
+ stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ (meantransit * 1e3),
+ (stats->isochstats.transit.current.cnt < 2) ? 0 : stats->isochstats.transit.current.min * 1e3,
+ (stats->isochstats.transit.current.cnt < 2) ? 0 : 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))),
+ stats->isochstats.transit.current.cnt,
+ stats->isochstats.transit.current.cnt ? (long) ((double)stats->cntBytes / (double) stats->isochstats.transit.current.cnt) : 0,
+ netpower_buf,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ stats->sock_callstats.read.bins[4],
+ stats->sock_callstats.read.bins[5],
+ stats->sock_callstats.read.bins[6],
+ stats->sock_callstats.read.bins[7]);
+ } else {
+ meantransit = (stats->isochstats.transit.total.cnt > 0) ? (stats->isochstats.transit.total.sum / stats->isochstats.transit.total.cnt) : 0;
+ set_netpowerbuf(meantransit, stats);
+ printf(report_bw_isoch_enhanced_netpwr_format,
+ stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ (meantransit * 1e3),
+ stats->isochstats.transit.total.min * 1e3,
+ stats->isochstats.transit.total.max * 1e3,
+ (stats->isochstats.transit.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->isochstats.transit.total.m2 / (stats->isochstats.transit.total.cnt - 1))),
+ stats->isochstats.transit.total.cnt,
+ stats->isochstats.transit.total.cnt ? (long) ((double)stats->cntBytes / (double) stats->isochstats.transit.total.cnt) : 0,
+ netpower_buf,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ stats->sock_callstats.read.bins[4],
+ stats->sock_callstats.read.bins[5],
+ stats->sock_callstats.read.bins[6],
+ stats->sock_callstats.read.bins[7]);
+ }
+ if (stats->framelatency_histogram) {
+ histogram_print(stats->framelatency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ fflush(stdout);
+}
+
+void tcp_output_frame_read (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_frame_tcp_enhanced);
+ _print_stats_common(stats);
+ printf(report_bw_read_enhanced_format,
+ stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ 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);
+}
+void tcp_output_frame_read_triptime (struct TransferInfo *stats) {
+ fprintf(stderr, "FIXME\n");
+}
+void tcp_output_burst_read (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_burst_read_tcp);
+ _print_stats_common(stats);
+ if (!stats->final) {
+ set_netpowerbuf(stats->transit.current.mean, stats);
+ printf(report_burst_read_tcp_format,
+ stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->transit.current.mean * 1e3,
+ (1e2 * stats->transit.current.mean * stats->common->FPS), // (1e3 / 100%)
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ stats->sock_callstats.read.bins[4],
+ stats->sock_callstats.read.bins[5],
+ stats->sock_callstats.read.bins[6],
+ stats->sock_callstats.read.bins[7],
+ netpower_buf);
+ } else {
+ printf(report_burst_read_tcp_final_format,
+ stats->common->transferIDStr, stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->transit.total.mean * 1e3,
+ (stats->transit.total.cnt < 2) ? 0 : stats->transit.total.min * 1e3,
+ (stats->transit.total.cnt < 2) ? 0 : stats->transit.total.max * 1e3,
+ (stats->transit.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->transit.total.m2 / (stats->transit.total.cnt - 1))),
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ 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);
+}
+
+//TCP write or client output
+void tcp_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);
+}
+
+void tcp_output_write_bb (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_client_bb_bw);
+ _print_stats_common(stats);
+ char rps_string[80];
+ if (stats->final) {
+ double rps = ((stats->fBBrunning > 0) && (stats->bbrtt.total.cnt > 0)) ? ((double) stats->bbrtt.total.cnt / stats->fBBrunning) : 0;
+ if (rps < 10)
+ snprintf(rps_string, sizeof(rps_string), "%0.1f", rps);
+ else
+ snprintf(rps_string, sizeof(rps_string), "%0.0f", rps);
+ 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);
+#else
+ 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))),
+ rps_string);
+#endif
+ if (isTripTime(stats->common)) {
+ printf(report_client_bb_bw_triptime_format, stats->common->transferIDStr,
+ stats->ts.iStart, stats->ts.iEnd,
+ stats->bbowdto.total.cnt,
+ (stats->bbowdto.total.mean * 1e3),
+ (stats->bbowdto.total.cnt < 2) ? 0 : (stats->bbowdto.total.min * 1e3),
+ (stats->bbowdto.total.cnt < 2) ? 0 : (stats->bbowdto.total.max * 1e3),
+ (stats->bbowdto.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbowdto.total.m2 / (stats->bbowdto.total.cnt - 1))),
+ (stats->bbowdfro.total.mean * 1e3),
+ (stats->bbowdfro.total.cnt < 2) ? 0 : (stats->bbowdfro.total.min * 1e3),
+ (stats->bbowdfro.total.cnt < 2) ? 0 : (stats->bbowdfro.total.max * 1e3),
+ (stats->bbowdfro.total.cnt < 2) ? 0 : 1e3 * (sqrt(stats->bbowdfro.total.m2 / (stats->bbowdfro.total.cnt - 1))),
+ (stats->bbasym.total.mean * 1e3),
+ (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);
+ }
+ if (stats->bbrtt_histogram) {
+ histogram_print(stats->bbrtt_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ } else {
+ double rps = ((stats->bbrtt.current.cnt > 0) && (stats->iBBrunning > 0)) ? ((double) stats->bbrtt.current.cnt / stats->iBBrunning) : 0;
+ if (rps < 10)
+ snprintf(rps_string, sizeof(rps_string), "%0.1f", rps);
+ else
+ snprintf(rps_string, sizeof(rps_string), "%0.0f", rps);
+ 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.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_string);
+#else
+ printf(report_client_bb_bw_format, stats->common->transferIDStr,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ 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))),
+ rps_string);
+#endif
+ }
+ fflush(stdout);
+}
+
+void tcp_output_burst_write (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_burst_write_tcp);
+ _print_stats_common(stats);
+#if HAVE_TCP_STATS
+ set_netpowerbuf((stats->transit.current.mean + stats->sock_callstats.write.tcpstats.rtt), stats);
+ 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.tcpstats.retry,
+ stats->sock_callstats.write.tcpstats.cwnd,
+ stats->sock_callstats.write.tcpstats.rtt,
+ netpower_buf);
+ #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);
+#endif
+ fflush(stdout);
+}
+
+void tcp_output_write_enhanced (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_write_enhanced);
+ _print_stats_common(stats);
+#if !(HAVE_TCP_STATS)
+ 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);
+#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,
+ 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->sock_callstats.write.tcpstats.rttvar,
+ netpower_buf);
+ } 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,
+ netpower_buf);
+ }
+#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);
+}
+
+void tcp_output_write_enhanced_write (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_write_enhanced_write);
+ _print_stats_common(stats);
+#if !(HAVE_TCP_STATS)
+ 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->write_mmm.current.mean * 1e3,
+ 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);
+#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);
+ }
+#endif
+ if (stats->latency_histogram) {
+ histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ if (stats->write_histogram) {
+ histogram_print(stats->write_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ fflush(stdout);
+}
+
+void tcp_output_write_enhanced_isoch (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_write_enhanced_isoch);
+ _print_stats_common(stats);
+#if !(HAVE_TCP_STATS)
+ 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->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips);
+#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);
+ }
+#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);
+}
+
+
+//UDP output
+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);
+}
+
+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);
+}
+
+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);
+}
+
+
+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);
+ _output_outoforder(stats);
+ fflush(stdout);
+}
+
+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);
+ } else {
+ if ((stats->transit.current.min > UNREALISTIC_LATENCYMINMAX) ||
+ (stats->transit.current.min < UNREALISTIC_LATENCYMINMIN)) {
+ printf(report_bw_jitter_loss_suppress_enhanced_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->cntIPG / stats->IPGsum));
+ } else {
+ double meantransit;
+ double variance;
+ char llaw_bufstr[LLAWBUFSIZE];
+ int lambda = ((stats->IPGsum > 0.0) ? (round (stats->cntIPG / stats->IPGsum)) : 0.0);
+ if (!stats->final) {
+ meantransit = (stats->transit.current.cnt > 0) ? (stats->transit.current.sum / stats->transit.current.cnt) : 0;
+ variance = (stats->transit.current.cnt < 2) ? 0 : \
+ (sqrt(stats->transit.current.m2 / (stats->transit.current.cnt - 1)));
+ snprintf(llaw_bufstr, sizeof(llaw_bufstr), "%.0f(%.0f) pkts", stats->iInP, ((double) lambda * variance));
+ } else {
+ meantransit = (stats->transit.total.cnt > 0) ? (stats->transit.total.sum / stats->transit.total.cnt) : 0;
+ variance = (stats->transit.total.cnt < 2) ? 0 : \
+ (sqrt(stats->transit.total.m2 / (stats->transit.total.cnt - 1)));
+ snprintf(llaw_bufstr, sizeof(llaw_bufstr), "%.0f(%.0f) pkts", stats->fInP, ((double) lambda * variance));
+ }
+ llaw_bufstr[sizeof(llaw_bufstr)-1] = '\0';
+ set_netpowerbuf(meantransit, stats);
+ printf(report_bw_jitter_loss_enhanced_triptime_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,
+ (meantransit * 1e3),
+ ((stats->final ? stats->transit.total.min : stats->transit.current.min) * 1e3),
+ ((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),
+ stats->cntIPG,
+ llaw_bufstr,
+ netpower_buf);
+ }
+ }
+ if (stats->latency_histogram) {
+ histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ if (stats->jitter_histogram) {
+ histogram_print(stats->jitter_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ _output_outoforder(stats);
+ fflush(stdout);
+}
+void udp_output_read_enhanced (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_jitter_loss_enhanced);
+ _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);
+ } else {
+ if ((stats->transit.current.min > UNREALISTIC_LATENCYMINMAX) ||
+ (stats->transit.current.min < UNREALISTIC_LATENCYMINMIN)) {
+ printf(report_bw_jitter_loss_suppress_enhanced_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->cntIPG / stats->IPGsum));
+ } else {
+ double meantransit;
+ double variance;
+ if (!stats->final) {
+ meantransit = (stats->transit.current.cnt > 0) ? (stats->transit.current.sum / stats->transit.current.cnt) : 0;
+ variance = (stats->transit.current.cnt < 2) ? 0 : \
+ (sqrt(stats->transit.current.m2 / (stats->transit.current.cnt - 1)));
+ } else {
+ meantransit = (stats->transit.total.cnt > 0) ? (stats->transit.total.sum / stats->transit.total.cnt) : 0;
+ variance = (stats->transit.total.cnt < 2) ? 0 : \
+ (sqrt(stats->transit.total.m2 / (stats->transit.total.cnt - 1)));
+ }
+ set_netpowerbuf(meantransit, stats);
+ printf(report_bw_jitter_loss_enhanced_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,
+ (meantransit * 1e3),
+ ((stats->final ? stats->transit.total.min : stats->transit.current.min) * 1e3),
+ ((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);
+ }
+ }
+ if (stats->latency_histogram) {
+ histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ if (stats->jitter_histogram) {
+ histogram_print(stats->jitter_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ _output_outoforder(stats);
+ fflush(stdout);
+}
+void udp_output_read_triptime_isoch (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_jitter_loss_enhanced_isoch_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);
+
+ } else {
+ // If the min latency is out of bounds of a realistic value
+ // assume the clocks are not synched and suppress the
+ // latency output
+ if ((stats->transit.current.min > UNREALISTIC_LATENCYMINMAX) ||
+ (stats->transit.current.min < UNREALISTIC_LATENCYMINMIN)) {
+ printf(report_bw_jitter_loss_suppress_enhanced_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->cntIPG / stats->IPGsum));
+ } 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;
+ set_netpowerbuf(meantransit, stats);
+ printf(report_bw_jitter_loss_enhanced_isoch_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,
+ (meantransit * 1e3),
+ stats->transit.current.min * 1e3,
+ stats->transit.current.max * 1e3,
+ (stats->transit.current.cnt < 2) ? 0 : 1e3 * (sqrt(stats->transit.current.m2 / (stats->transit.current.cnt - 1))),
+ (stats->cntIPG / stats->IPGsum),
+ stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed,
+ (frame_meantransit * 1e3),
+ 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);
+#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);
+ }
+#endif
+ }
+ }
+ if (stats->latency_histogram) {
+ histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ if (stats->jitter_histogram) {
+ histogram_print(stats->jitter_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ if (stats->framelatency_histogram) {
+ histogram_print(stats->framelatency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ _output_outoforder(stats);
+ fflush(stdout);
+}
+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);
+}
+
+void udp_output_write_enhanced (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_pps_enhanced);
+ _print_stats_common(stats);
+ printf(report_bw_pps_enhanced_format, stats->common->transferIDStr,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->sock_callstats.write.WriteCnt,
+ stats->sock_callstats.write.WriteErr,
+ (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0));
+ fflush(stdout);
+}
+void udp_output_write_enhanced_isoch (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_pps_enhanced_isoch);
+ _print_stats_common(stats);
+ printf(report_bw_pps_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->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0),
+ stats->isochstats.cntFrames, stats->isochstats.cntFramesMissed, stats->isochstats.cntSlips);
+ fflush(stdout);
+}
+
+// Sum reports
+void udp_output_sum_read (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw);
+ _print_stats_common(stats);
+ printf(report_sum_bw_jitter_loss_format,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->cntError, stats->cntDatagrams,
+ (100.0 * stats->cntError) / stats->cntDatagrams);
+ if ((stats->cntOutofOrder > 0) && stats->final) {
+ printf(report_sum_outoforder,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ }
+ fflush(stdout);
+}
+void udp_output_sumcnt (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_sumcnt_bw);
+ _print_stats_common(stats);
+ printf(report_sumcnt_bw_format, stats->threadcnt,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext);
+ if ((stats->cntOutofOrder > 0) && stats->final) {
+ if (isSumOnly(stats->common)) {
+ printf(report_sumcnt_outoforder,
+ stats->threadcnt,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ } else {
+ printf(report_outoforder,
+ stats->common->transferIDStr, stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ }
+ }
+ fflush(stdout);
+}
+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));
+ if ((stats->cntOutofOrder > 0) && stats->final) {
+ if (isSumOnly(stats->common)) {
+ printf(report_sumcnt_outoforder,
+ stats->threadcnt,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ } else {
+ printf(report_sum_outoforder,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ }
+ }
+ fflush(stdout);
+}
+
+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,
+ 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->cntOutofOrder > 0) && stats->final) {
+ if (isSumOnly(stats->common)) {
+ printf(report_sumcnt_outoforder,
+ stats->threadcnt,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ } else {
+ printf(report_sum_outoforder,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ }
+ }
+ fflush(stdout);
+}
+
+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) {
+ if (isSumOnly(stats->common)) {
+ printf(report_sumcnt_outoforder,
+ stats->threadcnt,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ } else {
+ printf(report_sum_outoforder,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ }
+ }
+ fflush(stdout);
+}
+
+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);
+}
+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,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext);
+ fflush(stdout);
+}
+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,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->cntError, stats->cntDatagrams,
+ (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0));
+ if (stats->latency_histogram && stats->final) {
+ histogram_print(stats->latency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ if (stats->jitter_histogram && stats->final) {
+ histogram_print(stats->jitter_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ if ((stats->cntOutofOrder > 0) && stats->final) {
+ if (isSumOnly(stats->common)) {
+ printf(report_sumcnt_outoforder,
+ stats->threadcnt,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ } else {
+ printf(report_sum_outoforder,
+ stats->ts.iStart,
+ stats->ts.iEnd, stats->cntOutofOrder);
+ }
+ }
+ fflush(stdout);
+}
+void udp_output_sum_write_enhanced (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_pps_enhanced);
+ _print_stats_common(stats);
+ printf(report_sum_bw_pps_enhanced_format,
+ 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);
+}
+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,
+ 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);
+}
+
+void tcp_output_sum_read (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);
+}
+void tcp_output_sum_read_enhanced (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_read_enhanced);
+ _print_stats_common(stats);
+ printf(report_sum_bw_read_enhanced_format,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ stats->sock_callstats.read.bins[4],
+ stats->sock_callstats.read.bins[5],
+ stats->sock_callstats.read.bins[6],
+ stats->sock_callstats.read.bins[7]);
+ if (stats->framelatency_histogram && stats->final) {
+ histogram_print(stats->framelatency_histogram, stats->ts.iStart, stats->ts.iEnd);
+ }
+ fflush(stdout);
+}
+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,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext);
+ fflush(stdout);
+}
+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,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ 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);
+}
+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,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ llaw_bufstr,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ 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);
+}
+
+void tcp_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);
+}
+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,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext);
+ fflush(stdout);
+}
+void tcp_output_sum_write_enhanced (struct TransferInfo *stats) {
+ HEADING_PRINT_COND(report_bw_write_enhanced);
+ _print_stats_common(stats);
+ printf(report_sum_bw_write_enhanced_format,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->sock_callstats.write.WriteCnt,
+ stats->sock_callstats.write.WriteErr
+#if HAVE_TCP_STATS
+ ,stats->sock_callstats.write.tcpstats.retry
+#endif
+ );
+ fflush(stdout);
+}
+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,
+ stats->ts.iStart, stats->ts.iEnd,
+ outbuffer, outbufferext,
+ stats->sock_callstats.write.WriteCnt,
+ stats->sock_callstats.write.WriteErr
+#if HAVE_TCP_STATS
+ ,stats->sock_callstats.write.tcpstats.retry
+#endif
+ );
+ fflush(stdout);
+}
+
+// CSV outputs
+void format_ips_port_string (struct TransferInfo *stats, bool sum) {
+ char local_addr[REPORT_ADDRLEN];
+ char remote_addr[REPORT_ADDRLEN];
+ uint16_t local_port;
+ uint16_t remote_port;
+ int swap = (stats->common->ThreadMode == kMode_Server);
+ int reverse = (isServerReverse(stats->common) || isReverse(stats->common));
+ struct sockaddr *local = (swap ? (struct sockaddr*)&stats->common->peer : (struct sockaddr*)&stats->common->local);
+ struct sockaddr *peer = (swap ? (struct sockaddr*)&stats->common->local : (struct sockaddr*)&stats->common->peer);
+
+ if (local->sa_family == AF_INET) {
+ if (isHideIPs(stats->common)) {
+ inet_ntop_hide(AF_INET, &((struct sockaddr_in*)local)->sin_addr,
+ local_addr, REPORT_ADDRLEN);
+ } else {
+ inet_ntop(AF_INET, &((struct sockaddr_in*)local)->sin_addr,
+ local_addr, REPORT_ADDRLEN);
+ }
+ if (!reverse && sum)
+ local_port = 0;
+ else
+ local_port = ntohs(((struct sockaddr_in*)local)->sin_port);
+ } else {
+#if HAVE_IPV6
+ if (local->sa_family == AF_INET6) {
+ inet_ntop(AF_INET6, &((struct sockaddr_in6*)local)->sin6_addr,
+ local_addr, REPORT_ADDRLEN);
+ if (swap && sum)
+ local_port = 0;
+ else
+ local_port = ntohs(((struct sockaddr_in6*)local)->sin6_port);
+ } else
+#endif
+ {
+ local_addr[0] = '\0';
+ local_port = 0;
+ }
+ }
+
+ if (peer->sa_family == AF_INET) {
+ if (isHideIPs(stats->common)) {
+ inet_ntop_hide(AF_INET, &((struct sockaddr_in*)peer)->sin_addr,
+ remote_addr, REPORT_ADDRLEN);
+ } else {
+ inet_ntop(AF_INET, &((struct sockaddr_in*)peer)->sin_addr,
+ remote_addr, REPORT_ADDRLEN);
+ }
+ if (reverse && sum)
+ remote_port = 0;
+ else
+ remote_port = ntohs(((struct sockaddr_in*)peer)->sin_port);
+ } else {
+#if HAVE_IPV6
+ if (local->sa_family == AF_INET6) {
+ inet_ntop(AF_INET6, &((struct sockaddr_in6*)peer)->sin6_addr,
+ remote_addr, REPORT_ADDRLEN);
+ if (!swap && sum)
+ remote_port = 0;
+ else
+ remote_port = ntohs(((struct sockaddr_in6*)peer)->sin6_port);
+ } else
+#endif
+ {
+ remote_addr[0] = '\0';
+ remote_port = 0;
+ }
+ }
+
+ snprintf((char *)&stats->csv_peer, CSVPEERLIMIT, reportCSV_peer,
+ local_addr, local_port,
+ remote_addr, remote_port);
+ stats->csv_peer[(CSVPEERLIMIT-1)] = '\0';
+#if 0 // use to debug CSV ouput
+ printf("*** output = %s swap=%d reverse=%d sum=%d\n", stats->csv_peer, swap, reverse, sum);
+#endif
+}
+
+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);
+ printf(reportCSV_bw_jitter_loss_format,
+ timestr,
+ stats->csv_peer,
+ stats->common->transferID,
+ stats->ts.iStart,
+ stats->ts.iEnd,
+ stats->cntBytes,
+ speed,
+ (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->cntOutofOrder );
+}
+
+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);
+ printf(reportCSV_bw_jitter_loss_pps_format,
+ timestr,
+ stats->csv_peer,
+ stats->common->transferID,
+ stats->ts.iStart,
+ stats->ts.iEnd,
+ stats->cntBytes,
+ speed,
+ (stats->jitter * 1e3),
+ stats->cntError,
+ stats->cntDatagrams,
+ (100.0 * stats->cntError) / stats->cntDatagrams,
+ stats->cntOutofOrder,
+ stats->sock_callstats.write.WriteCnt,
+ stats->sock_callstats.write.WriteErr,
+ (stats->cntIPG ? (stats->cntIPG / stats->IPGsum) : 0.0));
+}
+
+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);
+ printf(reportCSV_bw_format,
+ timestr,
+ stats->csv_peer,
+ stats->common->transferID,
+ stats->ts.iStart,
+ stats->ts.iEnd,
+ stats->cntBytes,
+ speed);
+}
+
+void tcp_output_read_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);
+ printf(reportCSV_bw_read_enhanced_format,
+ timestr,
+ stats->csv_peer,
+ stats->common->transferID,
+ stats->ts.iStart,
+ stats->ts.iEnd,
+ stats->cntBytes,
+ speed,
+ stats->sock_callstats.read.cntRead,
+ stats->sock_callstats.read.bins[0],
+ stats->sock_callstats.read.bins[1],
+ stats->sock_callstats.read.bins[2],
+ stats->sock_callstats.read.bins[3],
+ stats->sock_callstats.read.bins[4],
+ stats->sock_callstats.read.bins[5],
+ stats->sock_callstats.read.bins[6],
+ stats->sock_callstats.read.bins[7]);
+}
+
+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);
+#if !(HAVE_TCP_STATS)
+ printf(reportCSV_bw_write_enhanced_format,
+ timestr,
+ stats->csv_peer,
+ stats->common->transferID,
+ stats->ts.iStart,
+ stats->ts.iEnd,
+ stats->cntBytes,
+ speed,
+ -1,
+ -1,
+ -1,
+ -1,
+ 0,
+ 0);
+#else
+ if (stats->common->transferID == -1) {
+ /* Sums */
+ printf(reportCSV_bw_write_enhanced_format,
+ timestr,
+ stats->csv_peer,
+ stats->common->transferID,
+ stats->ts.iStart,
+ stats->ts.iEnd,
+ stats->cntBytes,
+ speed,
+ stats->sock_callstats.write.WriteCnt,
+ stats->sock_callstats.write.WriteErr,
+ stats->sock_callstats.write.tcpstats.retry,
+ -1,
+ 0,
+ 0);
+ } else if (stats->sock_callstats.write.tcpstats.cwnd > 0) {
+ printf(reportCSV_bw_write_enhanced_format,
+ timestr,
+ stats->csv_peer,
+ stats->common->transferID,
+ stats->ts.iStart,
+ stats->ts.iEnd,
+ stats->cntBytes,
+ speed,
+ 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->sock_callstats.write.tcpstats.rttvar);
+ } else {
+ printf(reportCSV_bw_write_enhanced_format,
+ timestr,
+ stats->csv_peer,
+ stats->common->transferID,
+ stats->ts.iStart,
+ stats->ts.iEnd,
+ stats->cntBytes,
+ speed,
+ stats->sock_callstats.write.WriteCnt,
+ stats->sock_callstats.write.WriteErr,
+ stats->sock_callstats.write.tcpstats.retry,
+ -1,
+ stats->sock_callstats.write.tcpstats.rtt,
+ 0);
+ }
+#endif
+}
+
+/*
+ * Report the client or listener Settings in default style
+ */
+static void output_window_size (struct ReportSettings *report) {
+ int winsize = getsock_tcp_windowsize(report->common->socket, (report->common->ThreadMode != kMode_Client ? 0 : 1));
+ byte_snprintf(outbuffer, sizeof(outbuffer), winsize, \
+ ((toupper(report->common->Format) == 'B') ? 'B' : 'A'));
+ outbuffer[(sizeof(outbuffer)-1)] = '\0';
+ printf("%s: %s", (isUDP(report->common) ? udp_buffer_size : tcp_window_size), outbuffer);
+ if (report->common->winsize_requested == 0) {
+ printf(" %s", window_default);
+ } else if (winsize != report->common->winsize_requested) {
+ byte_snprintf(outbuffer, sizeof(outbuffer), report->common->winsize_requested,
+ toupper((int)report->common->Format));
+ outbuffer[(sizeof(outbuffer)-1)] = '\0';
+ printf(warn_window_requested, outbuffer);
+ }
+ fflush(stdout);
+}
+static void reporter_output_listener_settings (struct ReportSettings *report) {
+ if (report->common->PortLast > report->common->Port) {
+ printf(server_pid_portrange, (isUDP(report->common) ? "UDP" : "TCP"), \
+ 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);
+ }
+ if (report->common->Localhost != NULL) {
+ if (isEnhanced(report->common) && !SockAddr_isMulticast(&report->local)) {
+ if (report->common->Ifrname) {
+ printf(bind_address_iface, report->common->Localhost, report->common->Ifrname);
+ } else {
+ char *host_ip = (char *) malloc(REPORT_ADDRLEN);
+ if (host_ip != NULL) {
+ if (((struct sockaddr*)(&report->common->local))->sa_family == AF_INET) {
+ if (isHideIPs(report->common)) {
+ inet_ntop_hide(AF_INET, &((struct sockaddr_in*)(&report->common->local))->sin_addr,
+ host_ip, REPORT_ADDRLEN);
+ } else {
+ inet_ntop(AF_INET, &((struct sockaddr_in*)(&report->common->local))->sin_addr,
+ host_ip, REPORT_ADDRLEN);
+ }
+ }
+#if HAVE_IPV6
+ else {
+ inet_ntop(AF_INET6, &((struct sockaddr_in6*)(&report->common->local))->sin6_addr,
+ host_ip, REPORT_ADDRLEN);
+ }
+#endif
+ printf(bind_address, host_ip);
+ free(host_ip);
+ }
+ }
+ }
+ if (SockAddr_isMulticast(&report->local)) {
+ if(!report->common->SSMMulticastStr)
+ if (!report->common->Ifrname)
+ printf(join_multicast, report->common->Localhost);
+ else
+ printf(join_multicast_starg_dev, report->common->Localhost,report->common->Ifrname);
+ else if(!report->common->Ifrname)
+ printf(join_multicast_sg, report->common->SSMMulticastStr, report->common->Localhost);
+ else
+ printf(join_multicast_sg_dev, report->common->SSMMulticastStr, report->common->Localhost, report->common->Ifrname);
+ }
+ }
+ if (isTunDev(report->common) || isTapDev(report->common)) {
+ 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 (isCongestionControl(report->common) && report->common->Congestion) {
+ fprintf(stdout, "TCP congestion control set to %s\n", report->common->Congestion);
+ }
+ if (isOverrideTOS(report->common)) {
+ fprintf(stdout, "Reflected TOS will be set to 0x%x\n", report->common->RTOS);
+ }
+ if (isPrintMSS(report->common)) {
+ if (isTCPMSS(report->common)) {
+ printf(report_mss, report->sockmaxseg);
+ } else {
+ printf(report_default_mss, report->sockmaxseg);
+ }
+ }
+ if (report->common->TOS) {
+ fprintf(stdout, "TOS will be set to 0x%x\n", report->common->TOS);
+ }
+ if (isUDP(report->common)) {
+ if (isSingleClient(report->common)) {
+ fprintf(stdout, "WARN: Suggested to use lower case -u instead of -U (to avoid serialize & bypass of reporter thread)\n");
+ } else if (isSingleClient(report->common)) {
+ fprintf(stdout, "Server set to single client traffic mode per -U (serialize traffic tests)\n");
+ }
+ } else if (isSingleClient(report->common)) {
+ fprintf(stdout, "Server set to single client traffic mode (serialize traffic tests)\n");
+ }
+ if (isMulticast(report->common)) {
+ fprintf(stdout, "Server set to single client traffic mode (per multicast receive)\n");
+ }
+ if (isHistogram(report->common)) {
+ fprintf(stdout, "Enabled receive histograms bin-width=%0.3f ms, bins=%d (clients should use --trip-times)\n", \
+ ((1e3 * report->common->HistBinsize) / pow(10,report->common->HistUnits)), report->common->HistBins);
+ }
+ if (isJitterHistogram(report->common)) {
+ fprintf(stdout, "Enabled jitter histograms (bin-width=%d us)\n", report->common->jitter_binwidth);
+ }
+ if (isFrameInterval(report->common)) {
+#if HAVE_FASTSAMPLING
+ fprintf(stdout, "Frame or burst interval reporting (feature is experimental)\n");
+#else
+ fprintf(stdout, "Frame or burst interval reporting (feature is experimental, ./configure --enable-fastsampling suggested)\n");
+#endif
+ }
+ output_window_size(report);
+ printf("\n");
+ if (isPermitKey(report->common) && report->common->PermitKey) {
+ if (report->common->ListenerTimeout > 0) {
+ fprintf(stdout, "Permit key is '%s' (timeout in %0.1f seconds)\n", report->common->PermitKey, report->common->ListenerTimeout);
+ } else {
+ fprintf(stdout, "Permit key is '%s' (WARN: no timeout)\n", report->common->PermitKey);
+ }
+ }
+ fflush(stdout);
+}
+static void reporter_output_client_settings (struct ReportSettings *report) {
+ char *hoststr = (isHideIPs(report->common) ? report->common->HideHost \
+ : report->common->Host);
+ 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));
+ } 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));
+ }
+ if ((isEnhanced(report->common) || isNearCongest(report->common)) && !isUDP(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);
+ } else {
+ printf("%s: %s\n", client_write_size, outbuffer);
+ }
+ }
+ if (isIsochronous(report->common)) {
+ char meanbuf[40];
+ char variancebuf[40];
+ byte_snprintf(meanbuf, sizeof(meanbuf), report->isochstats.mMean, 'a');
+ byte_snprintf(variancebuf, sizeof(variancebuf), report->isochstats.mVariance, 'a');
+ 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';
+ if (isTcpQuickAck(report->common)) {
+ printf(client_bounceback, tmpbuf, report->common->bbhold);
+ } else {
+ printf(client_bounceback_noqack, tmpbuf, report->common->bbhold);
+ }
+ }
+ if (isFQPacing(report->common)) {
+ 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)) {
+ printf(report_mss, report->sockmaxseg);
+ } else {
+ 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 (isEnhanced(report->common)) {
+ if (isNoDelay(report->common)) {
+ fprintf(stdout, "TOS set to 0x%x and nodelay (Nagle off)\n", report->common->TOS);
+ } else {
+ fprintf(stdout, "TOS set to 0x%x (Nagle on)\n", report->common->TOS);
+ }
+ }
+ if (isNearCongest(report->common)) {
+ if (report->common->rtt_weight == NEARCONGEST_DEFAULT) {
+ fprintf(stdout, "TCP near-congestion delay weight set to %2.4f (use --near-congestion=<value> to change)\n", report->common->rtt_weight);
+ } else {
+ fprintf(stdout, "TCP near-congestion delay weight set to %2.4f\n", report->common->rtt_weight);
+ }
+ }
+ if (isSingleClient(report->common)) {
+ fprintf(stdout, "WARN: Client set to bypass reporter thread per -U (suggest use lower case -u instead)\n");
+ }
+ if ((isIPG(report->common) || isUDP(report->common)) && !isIsochronous(report->common)) {
+ byte_snprintf(outbuffer, sizeof(outbuffer), report->common->pktIPG, 'a');
+ outbuffer[(sizeof(outbuffer)-1)] = '\0';
+#ifdef HAVE_KALMAN
+ printf(client_datagram_size_kalman, report->common->BufLen, report->common->pktIPG);
+#else
+ printf(client_datagram_size, report->common->BufLen, report->common->pktIPG);
+#endif
+ }
+ if (isConnectOnly(report->common)) {
+ fprintf(stdout, "TCP three-way-handshake (3WHS) only\n");
+ } else {
+ output_window_size(report);
+ printf("\n");
+#if HAVE_DECL_TCP_NOTSENT_LOWAT
+ if (isWritePrefetch(report->common)) {
+ fprintf(stdout, "Event based writes (pending queue watermark at %d bytes)\n", report->common->WritePrefetch);
+ }
+#endif
+ if (isHistogram(report->common)) {
+ if (!isBounceBack(report->common)) {
+ fprintf(stdout, "Enabled write histograms bin-width=%0.3f ms, bins=%d\n", \
+ ((1e3 * report->common->HistBinsize) / pow(10,report->common->HistUnits)), report->common->HistBins);
+ } else {
+ fprintf(stdout, "Set bounceback histograms to bin-width=%0.3f ms, bins=%d\n", \
+ ((1e3 * report->common->HistBinsize) / pow(10,report->common->HistUnits)), report->common->HistBins);
+ }
+ }
+ }
+ fflush(stdout);
+}
+
+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)));
+ 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);
+ }
+ fflush(stdout);
+}
+
+void reporter_print_connection_report (struct ConnectionInfo *report) {
+ assert(report->common);
+ // copy the inet_ntop into temp buffers, to avoid overwriting
+ char local_addr[REPORT_ADDRLEN];
+ char remote_addr[REPORT_ADDRLEN];
+ struct sockaddr *local = ((struct sockaddr*)&report->common->local);
+ struct sockaddr *peer = ((struct sockaddr*)&report->common->peer);
+ 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);
+ b += strlen(b);
+ }
+#endif
+#if HAVE_DECL_TCP_NOTSENT_LOWAT
+ if (!isUDP(report->common) && (report->common->socket > 0) && isWritePrefetch(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (%s%d)", "prefetch=", report->common->WritePrefetch);
+ b += strlen(b);
+ }
+#endif
+ if (isIsochronous(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (isoch)");
+ b += strlen(b);
+ }
+ if (isPeriodicBurst(report->common) && (report->common->ThreadMode != kMode_Client) && !isServerReverse(report->common)) {
+#if HAVE_FASTSAMPLING
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (burst-period=%0.4fs)", (1.0 / report->common->FPS));
+#else
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (burst-period=%0.2fs)", (1.0 / report->common->FPS));
+#endif
+ b += strlen(b);
+ }
+ if (isFullDuplex(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (full-duplex)");
+ b += strlen(b);
+ } else if (isServerReverse(report->common) || isReverse(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (reverse)");
+ b += strlen(b);
+ if (isFQPacing(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (fq)");
+ b += strlen(b);
+ }
+ }
+ if (isTxStartTime(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (epoch-start)");
+ b += strlen(b);
+ }
+ 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);
+ } else {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (bb len/hold=%d/%d)", report->common->bbsize, report->common->bbhold);
+ }
+ b += strlen(b);
+ }
+ if (isL2LengthCheck(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (l2mode)");
+ b += strlen(b);
+ }
+ if (isUDP(report->common) && isNoUDPfin(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (no-udp-fin)");
+ b += strlen(b);
+ }
+ if (isTripTime(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (trip-times)");
+ b += strlen(b);
+ }
+ if (isEnhanced(report->common)) {
+ 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);
+ } else if (isReverse(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (tos tx=0x%x)", 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);
+ } else if (isReverse(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (tos tx=0x%x)", report->common->TOS);
+ } else {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (tos rx=0x%x)", report->common->TOS);
+ }
+ b += strlen(b);
+ }
+ if (isEnhanced(report->common) || isPeerVerDetect(report->common)) {
+ if (report->peerversion[0] != '\0') {
+ snprintf(b, SNBUFFERSIZE-strlen(b), "%s", report->peerversion);
+ b += strlen(b);
+ }
+ }
+#if HAVE_DECL_TCP_QUICKACK
+ if (isTcpQuickAck(report->common) && !isBounceBack(report->common)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (qack)");
+ b += strlen(b);
+ }
+#endif
+#if HAVE_TCP_STATS
+ if (!isUDP(report->common) && (report->tcpinitstats.isValid)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (icwnd/mss/irtt=%u/%u/%u)", \
+ 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) {
+ char timestr[80];
+ iperf_formattime(timestr, sizeof(timestr), report->connect_timestamp, \
+ isEnhanced(report->common), isUTC(report->common), YearThruSecTZ);
+ if (!isUDP(report->common) && (report->common->ThreadMode == kMode_Client) && (report->tcpinitstats.connecttime > 0)) {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " (ct=%4.2f ms) on %s", report->tcpinitstats.connecttime, timestr);
+ } else {
+ snprintf(b, SNBUFFERSIZE-strlen(b), " on %s", timestr);
+ }
+ b += strlen(b);
+ }
+ }
+ if (local->sa_family == AF_INET) {
+ if (isHideIPs(report->common)) {
+ inet_ntop_hide(AF_INET, &((struct sockaddr_in*)local)->sin_addr, local_addr, REPORT_ADDRLEN);
+ } else {
+ inet_ntop(AF_INET, &((struct sockaddr_in*)local)->sin_addr, local_addr, REPORT_ADDRLEN);
+ }
+ }
+#if HAVE_IPV6
+ else {
+ inet_ntop(AF_INET6, &((struct sockaddr_in6*)local)->sin6_addr, local_addr, REPORT_ADDRLEN);
+ }
+#endif
+ if (peer->sa_family == AF_INET) {
+ if (isHideIPs(report->common)) {
+ inet_ntop_hide(AF_INET, &((struct sockaddr_in*)peer)->sin_addr, remote_addr, REPORT_ADDRLEN);
+ } else {
+ inet_ntop(AF_INET, &((struct sockaddr_in*)peer)->sin_addr, remote_addr, REPORT_ADDRLEN);
+ }
+ }
+#if HAVE_IPV6
+ else {
+ inet_ntop(AF_INET6, &((struct sockaddr_in6*)peer)->sin6_addr, remote_addr, REPORT_ADDRLEN);
+ }
+#endif
+#if HAVE_IPV6
+ if (report->common->KeyCheck) {
+ if (isEnhanced(report->common) && report->common->Ifrname && (strlen(report->common->Ifrname) < SNBUFFERSIZE-strlen(b))) {
+ printf(report_peer_dev, report->common->transferIDStr, local_addr, report->common->Ifrname, \
+ (local->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)local)->sin_port) : \
+ ntohs(((struct sockaddr_in6*)local)->sin6_port)), \
+ remote_addr, (peer->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)peer)->sin_port) : \
+ ntohs(((struct sockaddr_in6*)peer)->sin6_port)), outbuffer);
+ } else {
+ printf(report_peer, report->common->transferIDStr, local_addr, \
+ (local->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)local)->sin_port) : \
+ ntohs(((struct sockaddr_in6*)local)->sin6_port)), \
+ remote_addr, (peer->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)peer)->sin_port) : \
+ ntohs(((struct sockaddr_in6*)peer)->sin6_port)), outbuffer);
+ }
+ } else {
+ printf(report_peer_fail, local_addr, \
+ (local->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)local)->sin_port) : \
+ ntohs(((struct sockaddr_in6*)local)->sin6_port)), \
+ remote_addr, (peer->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)peer)->sin_port) : \
+ ntohs(((struct sockaddr_in6*)peer)->sin6_port)), outbuffer);
+ }
+
+#else
+ if (report->common->KeyCheck) {
+ if (isEnhanced(report->common) && report->common->Ifrname && (strlen(report->common->Ifrname) < SNBUFFERSIZE-strlen(b))) {
+ printf(report_peer_dev, report->common->transferIDStr, local_addr, report->common->Ifrname, \
+ local_addr, (local->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)local)->sin_port) : 0), \
+ remote_addr, (peer->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)peer)->sin_port) : 0), \
+ outbuffer);
+ } else {
+ printf(report_peer, report->common->transferIDStr, \
+ local_addr, (local->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)local)->sin_port) : 0), \
+ remote_addr, (peer->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)peer)->sin_port) : 0), \
+ outbuffer);
+ }
+ } else {
+ printf(report_peer_fail, local_addr, (local->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)local)->sin_port) : 0), \
+ remote_addr, (peer->sa_family == AF_INET ? ntohs(((struct sockaddr_in*)peer)->sin_port) : 0), \
+ outbuffer);
+ }
+#endif
+ 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
+ int seconds_from_now;
+ if (isTxHoldback(report->common)) {
+ seconds_from_now = report->txholdbacktime.tv_sec;
+ if (report->txholdbacktime.tv_usec > 0)
+ seconds_from_now++;
+ } else {
+ seconds_from_now = ceil(TimeDifference(report->epochStartTime, now));
+ }
+ struct timeval start;
+ start = now;
+ char start_timebuf[80];
+ start.tv_sec = now.tv_sec + seconds_from_now;
+ char now_timebuf[80];
+ iperf_formattime(now_timebuf, sizeof(now_timebuf), now, \
+ isEnhanced(report->common), isUTC(report->common), YearThruSecTZ);
+ iperf_formattime(start_timebuf, sizeof(start_timebuf), start, \
+ isEnhanced(report->common), isUTC(report->common), YearThruSec);
+ if (seconds_from_now > 0) {
+ printf(client_report_epoch_start_current, report->common->transferID, seconds_from_now, \
+ start_timebuf, now_timebuf);
+ } else if (!isBounceBack(report->common)) {
+ printf(warn_start_before_now, report->common->transferID, report->epochStartTime.tv_sec, \
+ report->epochStartTime.tv_usec, start_timebuf, now_timebuf);
+ }
+ }
+ }
+ fflush(stdout);
+}
+
+void reporter_print_settings_report (struct ReportSettings *report) {
+ assert(report != NULL);
+ report->pid = (int) getpid();
+ printf("%s", separator_line);
+ if (report->common->ThreadMode == kMode_Listener) {
+ reporter_output_listener_settings(report);
+ } else {
+ reporter_output_client_settings(report);
+ }
+ printf("%s", separator_line);
+ fflush(stdout);
+}
+
+void reporter_peerversion (struct ConnectionInfo *report, uint32_t upper, uint32_t lower) {
+ if (!upper || !lower) {
+ report->peerversion[0]='\0';
+ } else {
+ int rel, major, minor, alpha;
+ rel = (upper & 0xFFFF0000) >> 16;
+ major = (upper & 0x0000FFFF);
+ minor = (lower & 0xFFFF0000) >> 16;
+ alpha = (lower & 0x0000000F);
+ snprintf(report->peerversion, (PEERVERBUFSIZE-10), " (peer %d.%d.%d)", rel, major, minor);
+ switch(alpha) {
+ case 0:
+ sprintf(report->peerversion + strlen(report->peerversion) - 1,"-dev)");
+ break;
+ case 1:
+ sprintf(report->peerversion + strlen(report->peerversion) - 1,"-rc)");
+ break;
+ case 2:
+ sprintf(report->peerversion + strlen(report->peerversion) - 1,"-rc2)");
+ break;
+ case 3:
+ break;
+ case 4:
+ sprintf(report->peerversion + strlen(report->peerversion) - 1,"-private)");
+ break;
+ case 5:
+ sprintf(report->peerversion + strlen(report->peerversion) - 1,"-master)");
+ break;
+ default:
+ sprintf(report->peerversion + strlen(report->peerversion) - 1, "-unk)");
+ }
+ report->peerversion[PEERVERBUFSIZE-1]='\0';
+ }
+}
+
+void reporter_print_server_relay_report (struct ServerRelay *report) {
+ printf(server_reporting, report->info.common->transferID);
+ if (isTripTime(report->info.common) || isEnhanced(report->info.common)) {
+ udp_output_read_triptime(&report->info);
+ } else {
+ udp_output_read(&report->info);
+ }
+ fflush(stdout);
+}