/* * Process reports starting with "reporthdr" */ int reporter_process_report ( ReportHeader *reporthdr ) { int need_free = 0; // Recursively process reports if ( reporthdr->next != NULL ) { if ( reporter_process_report( reporthdr->next ) ) { // If we are done with this report then free it ReportHeader *temp = reporthdr->next; reporthdr->next = reporthdr->next->next; free( temp ); } } if ( (reporthdr->report.type & SETTINGS_REPORT) != 0 ) { reporthdr->report.type &= ~SETTINGS_REPORT; return reporter_print( &reporthdr->report, SETTINGS_REPORT, 1 ); } else if ( (reporthdr->report.type & CONNECTION_REPORT) != 0 ) { reporthdr->report.type &= ~CONNECTION_REPORT; reporter_print( &reporthdr->report, CONNECTION_REPORT, (reporthdr->report.type == 0 ? 1 : 0) ); if ( reporthdr->multireport != NULL && isMultipleReport( (&reporthdr->report) )) { if ( (reporthdr->multireport->report->type & CONNECTION_REPORT) != 0 ) { reporthdr->multireport->report->type &= ~CONNECTION_REPORT; reporter_print( reporthdr->multireport->report, CONNECTION_REPORT, (reporthdr->report.type == 0 ? 1 : 0) ); } } } else if ( (reporthdr->report.type & SERVER_RELAY_REPORT) != 0 ) { reporthdr->report.type &= ~SERVER_RELAY_REPORT; return reporter_print( &reporthdr->report, SERVER_RELAY_REPORT, 1 ); } if ( (reporthdr->report.type & TRANSFER_REPORT) != 0 ) { // If there are more packets to process then handle them if ( reporthdr->reporterindex >= 0 ) { // Need to make sure we do not pass the "agent" while ( reporthdr->reporterindex != reporthdr->agentindex - 1 ) { if ( reporthdr->reporterindex == NUM_REPORT_STRUCTS - 1 ) { if ( reporthdr->agentindex == 0 ) { break; } else { reporthdr->reporterindex = 0; } } else { reporthdr->reporterindex++; } if ( reporter_handle_packet( reporthdr ) ) { // No more packets to process //reporthdr->reporterindex = -1; break; } } } // If the agent is done with the report then free it if ( reporthdr->agentindex == -1 ) { need_free = 1; } } return need_free; }
/* * Prints reports conditionally */ int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int force ) { if ( force != 0 ) { stats->info.cntOutofOrder = stats->cntOutofOrder; // assume most of the time out-of-order packets are not // duplicate packets, so conditionally subtract them from the lost packets. stats->info.cntError = stats->cntError; if ( stats->info.cntError > stats->info.cntOutofOrder ) { stats->info.cntError -= stats->info.cntOutofOrder; } stats->info.cntDatagrams = (isUDP(stats) ? stats->PacketID : stats->cntDatagrams); stats->info.TotalLen = stats->TotalLen; stats->info.startTime = 0; stats->info.endTime = TimeDifference( stats->packetTime, stats->startTime ); stats->info.free = 1; reporter_print( stats, TRANSFER_REPORT, force ); if ( isMultipleReport(stats) ) { reporter_handle_multiple_reports( multireport, &stats->info, force ); } } else while ((stats->intervalTime.tv_sec != 0 || stats->intervalTime.tv_usec != 0) && TimeDifference( stats->nextTime, stats->packetTime ) < 0 ) { stats->info.cntOutofOrder = stats->cntOutofOrder - stats->lastOutofOrder; stats->lastOutofOrder = stats->cntOutofOrder; // assume most of the time out-of-order packets are not // duplicate packets, so conditionally subtract them from the lost packets. stats->info.cntError = stats->cntError - stats->lastError; if ( stats->info.cntError > stats->info.cntOutofOrder ) { stats->info.cntError -= stats->info.cntOutofOrder; } stats->lastError = stats->cntError; stats->info.cntDatagrams = (isUDP( stats ) ? stats->PacketID - stats->lastDatagrams : stats->cntDatagrams - stats->lastDatagrams); stats->lastDatagrams = (isUDP( stats ) ? stats->PacketID : stats->cntDatagrams); stats->info.TotalLen = stats->TotalLen - stats->lastTotal; stats->lastTotal = stats->TotalLen; stats->info.startTime = stats->info.endTime; stats->info.endTime = TimeDifference( stats->nextTime, stats->startTime ); TimeAdd( stats->nextTime, stats->intervalTime ); stats->info.free = 0; reporter_print( stats, TRANSFER_REPORT, force ); if ( isMultipleReport(stats) ) { reporter_handle_multiple_reports( multireport, &stats->info, force ); } } return force; }
/* * Handles summing of threads */ void reporter_handle_multiple_reports( MultiHeader *reporthdr, Transfer_Info *stats, int force ) { if ( reporthdr != NULL ) { if ( reporthdr->threads > 1 ) { int i; Transfer_Info *current = NULL; // Search for start Time for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) { current = &reporthdr->data[i]; if ( current->startTime == stats->startTime ) { break; } } if ( current->startTime != stats->startTime ) { // Find first available for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) { current = &reporthdr->data[i]; if ( current->startTime < 0 ) { break; } } current->cntDatagrams = stats->cntDatagrams; current->cntError = stats->cntError; current->cntOutofOrder = stats->cntOutofOrder; current->TotalLen = stats->TotalLen; current->mFormat = stats->mFormat; current->endTime = stats->endTime; current->jitter = stats->jitter; current->startTime = stats->startTime; current->free = 1; } else { current->cntDatagrams += stats->cntDatagrams; current->cntError += stats->cntError; current->cntOutofOrder += stats->cntOutofOrder; current->TotalLen += stats->TotalLen; current->mFormat = stats->mFormat; if ( current->endTime < stats->endTime ) { current->endTime = stats->endTime; } if ( current->jitter < stats->jitter ) { current->jitter = stats->jitter; } current->free++; if ( current->free == reporthdr->threads ) { void *reserved = reporthdr->report->info.reserved_delay; current->free = force; memcpy( &reporthdr->report->info, current, sizeof(Transfer_Info) ); current->startTime = -1; reporthdr->report->info.reserved_delay = reserved; reporter_print( reporthdr->report, MULTIPLE_REPORT, force ); } } } } }
/* * Prints reports conditionally */ int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int force ) { if ( force ) { #ifdef HAVE_STRUCT_TCP_INFO_TCPI_TOTAL_RETRANS gettcpistats(stats); #endif stats->info.cntOutofOrder = stats->cntOutofOrder; // assume most of the time out-of-order packets are not // duplicate packets, so conditionally subtract them from the lost packets. stats->info.cntError = stats->cntError; if ( stats->info.cntError > stats->info.cntOutofOrder ) { stats->info.cntError -= stats->info.cntOutofOrder; } stats->info.cntDatagrams = ((stats->info.mUDP == kMode_Server) ? stats->PacketID : stats->cntDatagrams); stats->info.TotalLen = stats->TotalLen; stats->info.startTime = 0; stats->info.endTime = TimeDifference( stats->packetTime, stats->startTime ); stats->info.transit.minTransit = stats->info.transit.totminTransit; stats->info.transit.maxTransit = stats->info.transit.totmaxTransit; stats->info.transit.cntTransit = stats->info.transit.totcntTransit; stats->info.transit.sumTransit = stats->info.transit.totsumTransit; stats->info.transit.meanTransit = stats->info.transit.totmeanTransit; stats->info.transit.m2Transit = stats->info.transit.totm2Transit; stats->info.transit.vdTransit = stats->info.transit.totvdTransit; if (stats->info.mTCP == kMode_Client) { stats->info.tcp.write.WriteErr = stats->info.tcp.write.totWriteErr; stats->info.tcp.write.WriteCnt = stats->info.tcp.write.totWriteCnt; stats->info.tcp.write.TCPretry = stats->info.tcp.write.totTCPretry; } if (stats->info.mTCP == kMode_Server) { int ix; stats->info.tcp.read.cntRead = stats->info.tcp.read.totcntRead; for (ix = 0; ix < 8; ix++) { stats->info.tcp.read.bins[ix] = stats->info.tcp.read.totbins[ix]; } } if (stats->info.endTime > 0) { stats->info.IPGcnt = (int) (stats->cntDatagrams / stats->info.endTime); } else { stats->info.IPGcnt = 0; } stats->info.IPGsum = 1; stats->info.free = 1; reporter_print( stats, TRANSFER_REPORT, force ); if ( isMultipleReport(stats) ) { reporter_handle_multiple_reports( multireport, &stats->info, force ); } } else while ((stats->intervalTime.tv_sec != 0 || stats->intervalTime.tv_usec != 0) && TimeDifference( stats->nextTime, stats->packetTime ) < 0 ) { #ifdef HAVE_STRUCT_TCP_INFO_TCPI_TOTAL_RETRANS gettcpistats(stats); #endif stats->info.cntOutofOrder = stats->cntOutofOrder - stats->lastOutofOrder; stats->lastOutofOrder = stats->cntOutofOrder; // assume most of the time out-of-order packets are not // duplicate packets, so conditionally subtract them from the lost packets. stats->info.cntError = stats->cntError - stats->lastError; if ( stats->info.cntError > stats->info.cntOutofOrder ) { stats->info.cntError -= stats->info.cntOutofOrder; } stats->lastError = stats->cntError; stats->info.cntDatagrams = ((stats->info.mUDP == kMode_Server) ? stats->PacketID - stats->lastDatagrams : stats->cntDatagrams - stats->lastDatagrams); stats->lastDatagrams = ((stats->info.mUDP == kMode_Server) ? stats->PacketID : stats->cntDatagrams); stats->info.TotalLen = stats->TotalLen - stats->lastTotal; stats->lastTotal = stats->TotalLen; stats->info.startTime = stats->info.endTime; stats->info.endTime = TimeDifference( stats->nextTime, stats->startTime ); TimeAdd( stats->nextTime, stats->intervalTime ); stats->info.free = 0; reporter_print( stats, TRANSFER_REPORT, force ); if ( isMultipleReport(stats) ) { reporter_handle_multiple_reports( multireport, &stats->info, force ); } // Reset stats used by SUM now that the SUM has been reported if (stats->info.mEnhanced) { if (stats->info.mUDP) { stats->info.IPGcnt = 0; stats->info.IPGsum = 0; } else if (stats->info.mTCP == (char)kMode_Client) { stats->info.tcp.write.WriteCnt = 0; stats->info.tcp.write.WriteErr = 0; } else if (stats->info.mTCP == (char)kMode_Server) { int ix; stats->info.tcp.read.cntRead = 0; for (ix = 0; ix < 8; ix++) { stats->info.tcp.read.bins[ix] = 0; } } } } return force; }
/* * Handles summing of threads */ void reporter_handle_multiple_reports( MultiHeader *reporthdr, Transfer_Info *stats, int force ) { if ( reporthdr != NULL ) { if ( reporthdr->threads > 1 ) { int i; Transfer_Info *current = NULL; // Search for start Time for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) { current = &reporthdr->data[i]; if ( current->startTime == stats->startTime ) { break; } } if ( current->startTime != stats->startTime ) { // Find first available for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) { current = &reporthdr->data[i]; if ( current->startTime < 0 ) { break; } } current->cntDatagrams = stats->cntDatagrams; current->cntError = stats->cntError; current->cntOutofOrder = stats->cntOutofOrder; current->TotalLen = stats->TotalLen; current->mFormat = stats->mFormat; current->mEnhanced = stats->mEnhanced; current->endTime = stats->endTime; current->jitter = stats->jitter; current->startTime = stats->startTime; current->IPGcnt = stats->IPGcnt; current->startTime = stats->startTime; current->IPGsum = stats->IPGsum; current->mUDP = stats->mUDP; current->mTCP = stats->mTCP; if (stats->mTCP == kMode_Server) { int ix; current->tcp.read.cntRead = stats->tcp.read.cntRead; for (ix = 0; ix < 8; ix++) { current->tcp.read.bins[ix] = stats->tcp.read.bins[ix]; } } else if (stats->mTCP == kMode_Client) { current->tcp.write.WriteErr = stats->tcp.write.WriteErr; current->tcp.write.WriteCnt = stats->tcp.write.WriteCnt; #ifdef HAVE_STRUCT_TCP_INFO_TCPI_TOTAL_RETRANS current->tcp.write.TCPretry = stats->tcp.write.TCPretry; #endif } current->free = 1; } else { current->cntDatagrams += stats->cntDatagrams; current->cntError += stats->cntError; current->cntOutofOrder += stats->cntOutofOrder; current->TotalLen += stats->TotalLen; current->IPGcnt += stats->IPGcnt; if (stats->mTCP == kMode_Server) { int ix; current->tcp.read.cntRead += stats->tcp.read.cntRead; for (ix = 0; ix < 8; ix++) { current->tcp.read.bins[ix] += stats->tcp.read.bins[ix]; } } else if (stats->mTCP == kMode_Client) { current->tcp.write.WriteErr += stats->tcp.write.WriteErr; current->tcp.write.WriteCnt += stats->tcp.write.WriteCnt; #ifdef HAVE_STRUCT_TCP_INFO_TCPI_TOTAL_RETRANS current->tcp.write.TCPretry += stats->tcp.write.TCPretry; #endif } if ( current->endTime < stats->endTime ) { current->endTime = stats->endTime; } if ( current->jitter < stats->jitter ) { current->jitter = stats->jitter; } current->free++; if ( current->free == reporthdr->threads ) { void *reserved = reporthdr->report->info.reserved_delay; current->free = force; memcpy( &reporthdr->report->info, current, sizeof(Transfer_Info) ); current->startTime = -1; reporthdr->report->info.reserved_delay = reserved; reporter_print( reporthdr->report, MULTIPLE_REPORT, force ); } } } } }