1 /*--------------------------------------------------------------- 2 * Copyright (c) 1999,2000,2001,2002,2003 3 * The Board of Trustees of the University of Illinois 4 * All Rights Reserved. 5 *--------------------------------------------------------------- 6 * Permission is hereby granted, free of charge, to any person 7 * obtaining a copy of this software (Iperf) and associated 8 * documentation files (the "Software"), to deal in the Software 9 * without restriction, including without limitation the 10 * rights to use, copy, modify, merge, publish, distribute, 11 * sublicense, and/or sell copies of the Software, and to permit 12 * persons to whom the Software is furnished to do 13 * so, subject to the following conditions: 14 * 15 * 16 * Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and 18 * the following disclaimers. 19 * 20 * 21 * Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimers in the documentation and/or other materials 24 * provided with the distribution. 25 * 26 * 27 * Neither the names of the University of Illinois, NCSA, 28 * nor the names of its contributors may be used to endorse 29 * or promote products derived from this Software without 30 * specific prior written permission. 31 * 32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 33 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 34 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 35 * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT 36 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 37 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 38 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE 39 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 40 * ________________________________________________________________ 41 * National Laboratory for Applied Network Research 42 * National Center for Supercomputing Applications 43 * University of Illinois at Urbana-Champaign 44 * http://www.ncsa.uiuc.edu 45 * ________________________________________________________________ 46 * 47 * Reporter.h 48 * by Kevin Gibbs <kgibbs@nlanr.net> 49 * 50 * Since version 2.0 this handles all reporting. 51 * ________________________________________________________________ */ 52 53 #ifndef REPORTER_H 54 #define REPORTER_H 55 56 #include "headers.h" 57 #include "Mutex.h" 58 #include "histogram.h" 59 #include "packet_ring.h" 60 61 // forward declarations found in Settings.hpp 62 struct thread_Settings; 63 struct server_hdr; 64 65 #include "Settings.hpp" 66 67 #define NUM_REPORT_STRUCTS 10000 68 #define PEERVERBUFSIZE 256 69 #define NETPOWERCONSTANT 1e-6 70 #define REPORTTXTMAX 80 71 #define MINBARRIERTIMEOUT 3 72 #define PARTIALPERCENT 0.25 // used to decide if a final partial report should be displayed 73 // If the minimum latency exceeds the boundaries below 74 // assume the clocks are not synched and suppress the 75 // latency output. Units are seconds 76 #define UNREALISTIC_LATENCYMINMIN -0.01 77 #define UNREALISTIC_LATENCYMINMAX 60 78 79 #ifdef __cplusplus 80 extern "C" { 81 #endif 82 83 extern struct Condition ReportCond; 84 extern struct Condition ReportsPending; 85 extern int groupID; 86 extern Mutex transferid_mutex; 87 88 /* 89 * 90 * Used for end/end latency measurements 91 * 92 */ 93 struct TransitStats { 94 double maxTransit; 95 double minTransit; 96 double sumTransit; 97 double lastTransit; 98 double meanTransit; 99 double m2Transit; 100 double vdTransit; 101 int cntTransit; 102 double totmaxTransit; 103 double totminTransit; 104 double totsumTransit; 105 int totcntTransit; 106 double totmeanTransit; 107 double totm2Transit; 108 double totvdTransit; 109 }; 110 111 struct MeanMinMaxStats { 112 double max; 113 double min; 114 double sum; 115 double last; 116 double mean; 117 double m2; 118 double vd; 119 int cnt; 120 int err; 121 }; 122 123 #define TCPREADBINCOUNT 8 124 struct ReadStats { 125 int cntRead; 126 int totcntRead; 127 int bins[TCPREADBINCOUNT]; 128 int totbins[TCPREADBINCOUNT]; 129 int binsize; 130 }; 131 132 struct WriteStats { 133 int WriteCnt; 134 int WriteErr; 135 int totWriteCnt; 136 int totWriteErr; 137 #ifdef HAVE_STRUCT_TCP_INFO_TCPI_TOTAL_RETRANS 138 int TCPretry; 139 int totTCPretry; 140 int cwnd; 141 int rtt; 142 #endif 143 }; 144 145 /* 146 * This struct contains all important information from the sending or 147 * recieving thread. 148 */ 149 #define L2UNKNOWN 0x01 150 #define L2LENERR 0x02 151 #define L2CSUMERR 0x04 152 153 enum WriteErrType { 154 WriteNoErr = 0, 155 WriteErrAccount, 156 WriteErrFatal, 157 WriteErrNoAccount, 158 }; 159 160 struct L2Stats { 161 intmax_t cnt; 162 intmax_t unknown; 163 intmax_t udpcsumerr; 164 intmax_t lengtherr; 165 intmax_t tot_cnt; 166 intmax_t tot_unknown; 167 intmax_t tot_udpcsumerr; 168 intmax_t tot_lengtherr; 169 }; 170 171 /* 172 * The type field of ReporterData is a bitmask 173 * with one or more of the following 174 */ 175 enum ReportType { 176 DATA_REPORT = 1, 177 SUM_REPORT, 178 SETTINGS_REPORT, 179 CONNECTION_REPORT, 180 SERVER_RELAY_REPORT 181 }; 182 183 enum ReportSubType { 184 FULLDUPLEXSUM_REPORT = 1, 185 HOSTSUM_REPORT, 186 TOTALSUM_REPORT 187 }; 188 189 union SendReadStats { 190 struct ReadStats read; 191 struct WriteStats write; 192 }; 193 194 // This attributes are shared by all reports 195 // deep copies are made when creating a new report 196 // rather than using references 197 struct ReportCommon { 198 enum ThreadMode ThreadMode; 199 enum ReportMode ReportMode; 200 bool KeyCheck; 201 int flags; 202 int flags_extend; 203 int flags_extend2; 204 int threads; 205 unsigned short Port; 206 unsigned short PortLast; 207 unsigned short BindPort; 208 unsigned short ListenPort; 209 intmax_t AppRate; // -b or -u 210 uint32_t BurstSize; 211 int AppRateUnits; 212 char Format; 213 int TTL; 214 int BufLen; 215 int MSS; 216 int TCPWin; 217 #if HAVE_DECL_TCP_WINDOW_CLAMP 218 int ClampSize; 219 #endif 220 #if HAVE_DECL_TCP_NOTSENT_LOWAT 221 int WritePrefetch; 222 #endif 223 int winsize_requested; 224 unsigned int FQPacingRate; 225 int HistBins; 226 int HistBinsize; 227 int HistUnits; 228 double pktIPG; 229 iperf_sockaddr peer; 230 Socklen_t size_peer; 231 iperf_sockaddr local; 232 Socklen_t size_local; 233 char* Host; // -c 234 char* HideHost; 235 char* Localhost; // -B 236 char* Ifrname; 237 char* Ifrnametx; 238 char* SSMMulticastStr; 239 char* Congestion; 240 char* transferIDStr; 241 char* PermitKey; 242 int transferID; 243 double rtt_weight; 244 double ListenerTimeout; 245 double FPS; 246 #ifdef HAVE_STRUCT_TCP_INFO_TCPI_TOTAL_RETRANS 247 bool enable_sampleTCPstats; 248 bool intervalonly_sampleTCPstats; 249 #endif 250 #if WIN32 251 SOCKET socket; 252 #else 253 int socket; 254 #if defined(HAVE_LINUX_FILTER_H) && defined(HAVE_AF_PACKET) 255 int socketdrop; 256 #endif 257 #endif 258 }; 259 260 struct ConnectionInfo { 261 struct ReportCommon *common; 262 struct timeval connect_timestamp; 263 double connecttime; 264 struct timeval txholdbacktime; 265 struct timeval epochStartTime; 266 int winsize; 267 char peerversion[PEERVERBUFSIZE]; 268 struct MeanMinMaxStats connect_times; 269 int MSS; 270 }; 271 272 struct ShiftIntCounter { 273 intmax_t current; 274 intmax_t prev; 275 }; 276 277 struct ShiftUintCounter { 278 uintmax_t current; 279 uintmax_t prev; 280 }; 281 282 struct ShiftCounters { 283 struct ShiftUintCounter Bytes; 284 struct ShiftIntCounter Lost; 285 struct ShiftIntCounter OutofOrder; 286 struct ShiftIntCounter Datagrams; 287 struct ShiftIntCounter IPG; 288 }; 289 290 struct IsochStats { 291 double mFPS; //frames per second 292 double mMean; //variable bit rate mean 293 double mVariance; //vbr variance 294 int mJitterBufSize; //Server jitter buffer size, units is frames 295 uintmax_t cntFrames; 296 uintmax_t cntFramesMissed; 297 uintmax_t cntSlips; 298 struct ShiftUintCounter slipcnt; 299 struct ShiftUintCounter framecnt; 300 struct ShiftUintCounter framelostcnt; 301 unsigned int mBurstInterval; 302 unsigned int mBurstIPG; //IPG of packets within the burst 303 uint32_t frameID; 304 }; 305 306 struct ReportSettings { 307 struct ReportCommon *common; 308 iperf_sockaddr peer; 309 Socklen_t size_peer; 310 iperf_sockaddr local; 311 Socklen_t size_local; 312 int pid; 313 struct IsochStats isochstats; 314 void (*output_handler) (struct ReportSettings *settings); 315 }; 316 317 // Timestamps 318 enum TimeStampType { 319 INTERVAL = 0, 320 FINALPARTIAL, 321 TOTAL, 322 FRAME 323 }; 324 325 struct ReportTimeStamps { 326 double iStart; 327 double iEnd; 328 double significant_partial; 329 struct timeval startTime; 330 struct timeval matchTime; 331 struct timeval packetTime; 332 struct timeval prevpacketTime; 333 struct timeval prevsendTime; 334 struct timeval nextTime; 335 struct timeval intervalTime; 336 struct timeval IPGstart; 337 #ifdef HAVE_STRUCT_TCP_INFO_TCPI_TOTAL_RETRANS 338 struct timeval nextTCPStampleTime; 339 #endif 340 }; 341 342 struct TransferInfo { 343 struct ReportCommon *common; 344 struct ReportTimeStamps ts; 345 void (*output_handler) (struct TransferInfo *stats); 346 int groupID; 347 int threadcnt; 348 int filter_this_sample_output; 349 uintmax_t cntBytes; 350 intmax_t cntError; 351 intmax_t cntOutofOrder; 352 intmax_t cntDatagrams; 353 intmax_t cntIPG; 354 intmax_t PacketID; 355 double jitter; 356 double tripTime; 357 double IPGsum; 358 struct ShiftCounters total; // Shift counters used to calculate interval reports and hold totals 359 union SendReadStats sock_callstats; 360 struct IsochStats isochstats; 361 struct histogram *latency_histogram; 362 struct TransitStats transit; 363 struct histogram *framelatency_histogram; 364 struct TransitStats frame; 365 struct L2Stats l2counts; 366 // Packet and frame state info 367 uint32_t matchframeID; 368 uint32_t frameID; 369 char csv_peer[CSVPEERLIMIT]; 370 bool final; 371 bool burstid_transition; 372 }; 373 374 struct SumReport { 375 struct ReferenceMutex reference; 376 int threads; 377 struct TransferInfo info; 378 void (*transfer_protocol_sum_handler) (struct TransferInfo *stats, int final); 379 struct BarrierMutex fullduplex_barrier; 380 int sum_fd_set; 381 }; 382 383 struct ReporterData { 384 // function pointer for per packet processing 385 void (*packet_handler_pre_report) (struct ReporterData *data, struct ReportStruct *packet); 386 void (*packet_handler_post_report) (struct ReporterData *data, struct ReportStruct *packet); 387 void (*transfer_protocol_handler) (struct ReporterData *data, int final); 388 int (*transfer_interval_handler) (struct ReporterData *data, struct ReportStruct *packet); 389 390 struct PacketRing *packetring; 391 int reporter_thread_suspends; // used to detect CPU bound systems 392 393 // group sum and full duplext reports 394 struct SumReport *GroupSumReport; 395 struct SumReport *FullDuplexReport; 396 struct TransferInfo info; 397 }; 398 399 struct ServerRelay { 400 struct TransferInfo info; 401 iperf_sockaddr peer; 402 Socklen_t size_peer; 403 iperf_sockaddr local; 404 Socklen_t size_local; 405 }; 406 407 struct ReportHeader { 408 enum ReportType type; 409 enum ReportMode ReportMode; 410 void *this_report; 411 struct ReportHeader *next; 412 }; 413 414 typedef void* (* report_connection)( struct ConnectionInfo*, int ); 415 typedef void (* report_settings)( struct ReporterData* ); 416 typedef void (* report_statistics)( struct TransferInfo* ); 417 typedef void (* report_serverstatistics)( struct ConnectionInfo *, struct TransferInfo* ); 418 419 void SetSumHandlers (struct thread_Settings *inSettings, struct SumReport* sumreport); 420 struct SumReport* InitSumReport(struct thread_Settings *inSettings, int inID, int fullduplex); 421 struct ReportHeader* InitIndividualReport(struct thread_Settings *inSettings); 422 struct ReportHeader* InitConnectionReport(struct thread_Settings *inSettings, double ct); 423 struct ConnectionInfo* InitConnectOnlyReport(struct thread_Settings *thread); 424 struct ReportHeader *InitSettingsReport(struct thread_Settings *inSettings); 425 struct ReportHeader* InitServerRelayUDPReport(struct thread_Settings *inSettings, struct server_hdr *server); 426 void PostReport(struct ReportHeader *reporthdr); 427 #ifdef HAVE_STRUCT_TCP_INFO_TCPI_TOTAL_RETRANS 428 bool ReportPacket (struct ReporterData* data, struct ReportStruct *packet, struct tcp_info *tcp_stats); 429 #else 430 void ReportPacket (struct ReporterData* data, struct ReportStruct *packet); 431 #endif 432 int EndJob(struct ReportHeader *reporthdr, struct ReportStruct *packet); 433 void FreeReport(struct ReportHeader *reporthdr); 434 void FreeSumReport (struct SumReport *sumreport); 435 void FreeConnectionReport(struct ConnectionInfo *reporthdr); 436 void ReportServerUDP(struct thread_Settings *inSettings, struct server_hdr *server); 437 void ReportConnections(struct thread_Settings *inSettings ); 438 void reporter_dump_job_queue(void); 439 void IncrSumReportRefCounter(struct SumReport *sumreport); 440 int DecrSumReportRefCounter(struct SumReport *sumreport); 441 442 extern struct AwaitMutex reporter_state; 443 extern struct AwaitMutex threads_start; 444 445 extern report_connection connection_reports[]; 446 extern report_settings settings_reports[]; 447 extern report_statistics statistics_reports[]; 448 extern report_serverstatistics serverstatistics_reports[]; 449 extern report_statistics multiple_reports[]; 450 451 452 // Packet accounting routines 453 void reporter_handle_packet_null(struct ReporterData *report, struct ReportStruct *packet); 454 void reporter_handle_packet_server_udp(struct ReporterData *data, struct ReportStruct *packet); 455 void reporter_handle_packet_server_tcp(struct ReporterData *data, struct ReportStruct *packet); 456 void reporter_handle_packet_client(struct ReporterData *data, struct ReportStruct *packet); 457 void reporter_handle_packet_pps(struct ReporterData *data, struct ReportStruct *packet); 458 void reporter_handle_packet_isochronous(struct ReporterData *data, struct ReportStruct *packet); 459 460 // Reporter's conditional prints, right now have time and frame based sampling, possibly add packet based 461 int reporter_condprint_time_interval_report(struct ReporterData *data, struct ReportStruct *packet); 462 int reporter_condprint_frame_interval_report_client_udp(struct ReporterData *reporthdr, struct ReportStruct *packet); 463 int reporter_condprint_frame_interval_report_server_udp(struct ReporterData *data, struct ReportStruct *packet); 464 int reporter_condprint_frame_interval_report_server_tcp(struct ReporterData *data, struct ReportStruct *packet); 465 int reporter_condprint_frame_interval_report_client_tcp(struct ReporterData *reporthdr, struct ReportStruct *packet); 466 int reporter_condprint_burst_interval_report_client_udp(struct ReporterData *reporthdr, struct ReportStruct *packet); 467 int reporter_condprint_burst_interval_report_server_udp(struct ReporterData *data, struct ReportStruct *packet); 468 int reporter_condprint_burst_interval_report_server_tcp(struct ReporterData *data, struct ReportStruct *packet); 469 int reporter_condprint_burst_interval_report_client_tcp(struct ReporterData *reporthdr, struct ReportStruct *packet); 470 //void reporter_set_timestamps_time(struct ReporterData *stats, enum TimestampType); 471 472 // Reporter's interval output specialize routines 473 void reporter_transfer_protocol_null(struct ReporterData *stats, int final); 474 //void reporter_transfer_protocol_reports(struct ReporterData *stats, struct ReportStruct *packet); 475 //void reporter_transfer_protocol_multireports(struct ReporterData *stats, struct ReportStruct *packet); 476 void reporter_transfer_protocol_client_tcp(struct ReporterData *data, int final); 477 void reporter_transfer_protocol_client_udp(struct ReporterData *data, int final); 478 void reporter_transfer_protocol_server_tcp(struct ReporterData *data, int final); 479 void reporter_transfer_protocol_server_udp(struct ReporterData *data, int final); 480 481 // Reporter's sum output routines (per -P > 1) 482 void reporter_transfer_protocol_sum_client_tcp(struct TransferInfo *stats, int final); 483 void reporter_transfer_protocol_sum_server_tcp(struct TransferInfo *stats, int final); 484 void reporter_transfer_protocol_sum_client_udp(struct TransferInfo *stats, int final); 485 void reporter_transfer_protocol_sum_server_udp(struct TransferInfo *stats, int final); 486 void reporter_transfer_protocol_fullduplex_tcp(struct TransferInfo *stats, int final); 487 void reporter_transfer_protocol_fullduplex_udp(struct TransferInfo *stats, int final); 488 489 490 // Reporter print routines 491 // TCP server 492 void tcp_output_read(struct TransferInfo *stats); 493 void tcp_output_read_enhanced(struct TransferInfo *stats); 494 void tcp_output_read_enhanced_triptime(struct TransferInfo *stats); 495 void tcp_output_sum_read(struct TransferInfo *stats); 496 void tcp_output_sum_read_enhanced(struct TransferInfo *stats); 497 void tcp_output_sumcnt_read(struct TransferInfo *stats); 498 void tcp_output_sumcnt_read_enhanced (struct TransferInfo *stats); 499 void tcp_output_frame_read(struct TransferInfo *stats); 500 void tcp_output_frame_read_triptime(struct TransferInfo *stats); 501 void tcp_output_burst_read(struct TransferInfo *stats); 502 503 // TCP client 504 void tcp_output_write(struct TransferInfo *stats); 505 void tcp_output_sum_write(struct TransferInfo *stats); 506 void tcp_output_sumcnt_write(struct TransferInfo *stats); 507 void tcp_output_write_enhanced (struct TransferInfo *stats); 508 void tcp_output_write_enhanced_isoch (struct TransferInfo *stats); 509 void tcp_output_sum_write_enhanced (struct TransferInfo *stats); 510 void tcp_output_sumcnt_write_enhanced (struct TransferInfo *stats); 511 // TCP fullduplex 512 void tcp_output_fullduplex(struct TransferInfo *stats); 513 void tcp_output_fullduplex_enhanced(struct TransferInfo *stats); 514 void tcp_output_fullduplex_sum (struct TransferInfo *stats); 515 516 // UDP server 517 void udp_output_read(struct TransferInfo *stats); 518 void udp_output_read_enhanced(struct TransferInfo *stats); 519 void udp_output_read_enhanced_triptime(struct TransferInfo *stats); 520 void udp_output_read_enhanced_triptime_isoch(struct TransferInfo *stats); 521 void udp_output_sum_read(struct TransferInfo *stats); 522 void udp_output_sum_read_enhanced (struct TransferInfo *stats); 523 void udp_output_sumcnt(struct TransferInfo *stats); 524 void udp_output_sumcnt_read_enhanced (struct TransferInfo *stats); 525 526 //UDP client 527 void udp_output_write(struct TransferInfo *stats); 528 void udp_output_sum_write(struct TransferInfo *stats); 529 void udp_output_write_enhanced(struct TransferInfo *stats); 530 void udp_output_write_enhanced_isoch(struct TransferInfo *stats); 531 void udp_output_sum_write_enhanced (struct TransferInfo *stats); 532 void udp_output_sumcnt_write(struct TransferInfo *stats); 533 void udp_output_sumcnt_write_enhanced (struct TransferInfo *stats); 534 void udp_output_sumcnt_enhanced(struct TransferInfo *stats); 535 // UDP full duplex 536 void udp_output_fullduplex(struct TransferInfo *stats); 537 void udp_output_fullduplex_enhanced(struct TransferInfo *stats); 538 void udp_output_fullduplex_sum(struct TransferInfo *stats); 539 540 541 // CSV output 542 void udp_output_basic_csv(struct TransferInfo *stats); 543 void tcp_output_basic_csv(struct TransferInfo *stats); 544 545 // Rest of the reporter output routines 546 void reporter_print_connection_report(struct ConnectionInfo *report); 547 void reporter_print_settings_report(struct ReportSettings *report); 548 void reporter_print_server_relay_report(struct ServerRelay *report); 549 void reporter_peerversion (struct ConnectionInfo *report, uint32_t upper, uint32_t lower); 550 void PrintMSS(struct ReporterData *data); 551 void reporter_default_heading_flags(int); 552 void reporter_connect_printf_tcp_final(struct ConnectionInfo *report); 553 554 void write_UDP_AckFIN(struct TransferInfo *stats, int len); 555 556 int reporter_process_transfer_report (struct ReporterData *this_ireport); 557 int reporter_process_report (struct ReportHeader *reporthdr); 558 559 void setTransferID(struct thread_Settings *inSettings, int role_reversal); 560 561 #ifdef __cplusplus 562 } /* end extern "C" */ 563 #endif 564 565 #endif // REPORTER_H 566