📄 reporter.c
字号:
// 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;}/* * Updates connection stats */int reporter_handle_packet( ReportHeader *reporthdr ) { ReportStruct *packet = &reporthdr->data[reporthdr->reporterindex]; ReporterData *data = &reporthdr->report; Transfer_Info *stats = &reporthdr->report.info; int finished = 0; data->cntDatagrams++; // If this is the last packet set the endTime if ( packet->packetID < 0 ) { data->packetTime = packet->packetTime; finished = 1; if ( reporthdr->report.mThreadMode != kMode_Client ) { data->TotalLen += packet->packetLen; } } else { // update recieved amount and time data->packetTime = packet->packetTime; reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished ); data->TotalLen += packet->packetLen; if ( packet->packetID != 0 ) { // UDP packet double transit; double deltaTransit; // from RFC 1889, Real Time Protocol (RTP) // J = J + ( | D(i-1,i) | - J ) / 16 transit = TimeDifference( packet->packetTime, packet->sentTime ); if ( data->lastTransit != 0.0 ) { deltaTransit = transit - data->lastTransit; if ( deltaTransit < 0.0 ) { deltaTransit = -deltaTransit; } stats->jitter += (deltaTransit - stats->jitter) / (16.0); } data->lastTransit = transit; // packet loss occured if the datagram numbers aren't sequential if ( packet->packetID != data->PacketID + 1 ) { if ( packet->packetID < data->PacketID + 1 ) { data->cntOutofOrder++; } else { data->cntError += packet->packetID - data->PacketID - 1; } } // never decrease datagramID (e.g. if we get an out-of-order packet) if ( packet->packetID > data->PacketID ) { data->PacketID = packet->packetID; } } } // Print a report if appropriate return reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );}/* * 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 != 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;}/* * This function handles multiple format printing by sending to the * appropriate dispatch function */int reporter_print( ReporterData *stats, int type, int end ) { switch ( type ) { case TRANSFER_REPORT: statistics_reports[stats->mode]( &stats->info ); if ( end != 0 && isPrintMSS( stats ) && !isUDP( stats ) ) { PrintMSS( stats ); } break; case SERVER_RELAY_REPORT: serverstatistics_reports[stats->mode]( &stats->connection, &stats->info ); break; case SETTINGS_REPORT: settings_reports[stats->mode]( stats ); break; case CONNECTION_REPORT: stats->info.reserved_delay = connection_reports[stats->mode]( &stats->connection, stats->info.transferID ); break; case MULTIPLE_REPORT: multiple_reports[stats->mode]( &stats->info ); break; default: fprintf( stderr, "Printing type not implemented! No Output\n" ); } fflush( stdout ); return end;}/* ------------------------------------------------------------------- * Report the MSS and MTU, given the MSS (or a guess thereof) * ------------------------------------------------------------------- */// compare the MSS against the (MTU - 40) to (MTU - 80) bytes.// 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.#define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS && inMSS >= (inMTU-80)void PrintMSS( ReporterData *stats ) { int inMSS = getsock_tcp_mss( stats->info.transferID ); if ( inMSS <= 0 ) { printf( report_mss_unsupported, stats->info.transferID ); } else { char* net; int mtu = 0; if ( checkMSS_MTU( inMSS, 1500 ) ) { net = "ethernet"; mtu = 1500; } else if ( checkMSS_MTU( inMSS, 4352 ) ) { net = "FDDI"; mtu = 4352; } else if ( checkMSS_MTU( inMSS, 9180 ) ) { net = "ATM"; mtu = 9180; } else if ( checkMSS_MTU( inMSS, 65280 ) ) { net = "HIPPI"; mtu = 65280; } else if ( checkMSS_MTU( inMSS, 576 ) ) { net = "minimum"; mtu = 576; printf( warn_no_pathmtu ); } else { mtu = inMSS + 40; net = "unknown interface"; } printf( report_mss, stats->info.transferID, inMSS, mtu, net ); }}// end ReportMSS#ifdef __cplusplus} /* end extern "C" */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -