]> sjero.net Git - iperf/blobdiff - src/Reporter.c
Native IPv6 support for iperf
[iperf] / src / Reporter.c
index 73143b33b7e268df04b89baaa1a9f0640e2270eb..c5eff5c35ba5a48e3610073272ea588db7a9a7dd 100644 (file)
@@ -111,6 +111,7 @@ report_statistics multiple_reports[kReport_MAXIMUM] = {
 char buffer[64]; // Buffer for printing
 ReportHeader *ReportRoot = NULL;
 extern Condition ReportCond;
+extern Condition ReportDoneCond;
 int reporter_process_report ( ReportHeader *report );
 void process_report ( ReportHeader *report );
 int reporter_handle_packet( ReportHeader *report );
@@ -155,23 +156,20 @@ MultiHeader* InitMulti( thread_Settings *agent, int inID ) {
                 data->mLocalhost = agent->mLocalhost;
                 data->mBufLen = agent->mBufLen;
                 data->mMSS = agent->mMSS;
-                data->mTCPWin = agent->mTCPWin;
+                data->mWinSize = agent->mWinSize;
                 data->flags = agent->flags;
+                data->mProtocol = agent->mProtocol;
                 data->mThreadMode = agent->mThreadMode;
                 data->mode = agent->mReportMode;
                 data->info.mFormat = agent->mFormat;
                 data->info.mTTL = agent->mTTL;
-                if ( isUDP( agent ) ) {
+                if ( isPacketOriented( agent ) ) {
                     multihdr->report->info.mUDP = (char)agent->mThreadMode;
                 }
                 if ( isConnectionReport( agent ) ) {
                     data->type |= CONNECTION_REPORT;
                     data->connection.peer = agent->peer;
-                    data->connection.size_peer = agent->size_peer;
-                    SockAddr_setPortAny( &data->connection.peer );
                     data->connection.local = agent->local;
-                    data->connection.size_local = agent->size_local;
-                    SockAddr_setPortAny( &data->connection.local );
                 }
             }
         } else {
@@ -236,13 +234,14 @@ ReportHeader* InitReport( thread_Settings *agent ) {
             data->mLocalhost = agent->mLocalhost;
             data->mBufLen = agent->mBufLen;
             data->mMSS = agent->mMSS;
-            data->mTCPWin = agent->mTCPWin;
+            data->mWinSize = agent->mWinSize;
             data->flags = agent->flags;
+            data->mProtocol = agent->mProtocol;
             data->mThreadMode = agent->mThreadMode;
             data->mode = agent->mReportMode;
             data->info.mFormat = agent->mFormat;
             data->info.mTTL = agent->mTTL;
-            if ( isUDP( agent ) ) {
+            if ( isPacketOriented( agent ) ) {
                 reporthdr->report.info.mUDP = (char)agent->mThreadMode;
             }
         } else {
@@ -268,9 +267,7 @@ ReportHeader* InitReport( thread_Settings *agent ) {
         if ( reporthdr != NULL ) {
             data->type |= CONNECTION_REPORT;
             data->connection.peer = agent->peer;
-            data->connection.size_peer = agent->size_peer;
             data->connection.local = agent->local;
-            data->connection.size_local = agent->size_local;
         } else {
             FAIL(1, "Out of Memory!!\n", agent);
         }
@@ -338,7 +335,7 @@ void ReportPacket( ReportHeader* agent, ReportStruct *packet ) {
             // item
             while ( index == 0 ) {
                 Condition_Signal( &ReportCond );
-                thread_rest();
+                Condition_Wait( &ReportDoneCond );
                 index = agent->reporterindex;
             }
             agent->agentindex = 0;
@@ -346,7 +343,7 @@ void ReportPacket( ReportHeader* agent, ReportStruct *packet ) {
         // Need to make sure that reporter is not about to be "lapped"
         while ( index - 1 == agent->agentindex ) {
             Condition_Signal( &ReportCond );
-            thread_rest();
+            Condition_Wait( &ReportDoneCond );
             index = agent->reporterindex;
         }
         
@@ -370,7 +367,6 @@ void ReportPacket( ReportHeader* agent, ReportStruct *packet ) {
  */
 void CloseReport( ReportHeader *agent, ReportStruct *packet ) {
     if ( agent != NULL) {
-
         /*
          * Using PacketID of -1 ends reporting
          */
@@ -441,16 +437,16 @@ void ReportSettings( thread_Settings *agent ) {
             data->type = SETTINGS_REPORT;
             data->mBufLen = agent->mBufLen;
             data->mMSS = agent->mMSS;
-            data->mTCPWin = agent->mTCPWin;
+            data->mWinSize = agent->mWinSize;
             data->flags = agent->flags;
+            data->mProtocol = agent->mProtocol;
             data->mThreadMode = agent->mThreadMode;
             data->mPort = agent->mPort;
+            data->mMcastIface = agent->mMcastIface;
             data->info.mFormat = agent->mFormat;
             data->info.mTTL = agent->mTTL;
             data->connection.peer = agent->peer;
-            data->connection.size_peer = agent->size_peer;
             data->connection.local = agent->local;
-            data->connection.size_local = agent->size_local;
     
     #ifdef HAVE_THREAD
             /*
@@ -510,9 +506,7 @@ void ReportServerUDP( thread_Settings *agent, server_hdr *server ) {
             stats->cntDatagrams = ntohl( server->datagrams );
             stats->mUDP = (char)kMode_Server;
             reporthdr->report.connection.peer = agent->local;
-            reporthdr->report.connection.size_peer = agent->size_local;
             reporthdr->report.connection.local = agent->peer;
-            reporthdr->report.connection.size_local = agent->size_peer;
             
 #ifdef HAVE_THREAD
             /*
@@ -553,6 +547,7 @@ void reporter_spawn( thread_Settings *thread ) {
         }
         Condition_Unlock ( ReportCond );
 
+again:
         if ( ReportRoot != NULL ) {
             ReportHeader *temp = ReportRoot;
             //Condition_Unlock ( ReportCond );
@@ -575,9 +570,12 @@ void reporter_spawn( thread_Settings *thread ) {
                 // finished with report so free it
                 free( temp );
                 Condition_Unlock ( ReportCond );
+                Condition_Signal( &ReportDoneCond );
+                if (ReportRoot)
+                    goto again;
             }
-            // yield control of CPU is another thread is waiting
-            thread_rest();
+            Condition_Signal( &ReportDoneCond );
+            usleep(10000);
         } else {
             //Condition_Unlock ( ReportCond );
         }
@@ -667,24 +665,26 @@ int reporter_handle_packet( ReportHeader *reporthdr ) {
     Transfer_Info *stats = &reporthdr->report.info;
     int finished = 0;
 
+    // update received amount and time
+    data->TotalLen  += packet->packetLen;
+    data->packetTime = packet->packetTime;
     data->cntDatagrams++;
-    // If this is the last packet set the endTime
-    if ( packet->packetID < 0 ) {
-        data->packetTime = packet->packetTime;
+
+    if (packet->packetID < 0) {
+        // This is the last packet (FIN)
         finished = 1;
-        if ( reporthdr->report.mThreadMode != kMode_Client ) {
-            data->TotalLen += packet->packetLen;
+        if (isConnectionLess(&reporthdr->report)) {
+            // connectionless protocols don't count the last payload
+            if (reporthdr->report.mThreadMode == kMode_Client)
+                data->TotalLen -= packet->packetLen;
+        } else {
+            // connection-oriented protocols dont't count the FIN
+            data->cntDatagrams--;
         }
-    } 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;
-            
+    } else if ( packet->packetID != 0 ) {
+            // UDP or DCCP packet
+            double transit, deltaTransit;
+
             // from RFC 1889, Real Time Protocol (RTP) 
             // J = J + ( | D(i-1,i) | - J ) / 16 
             transit = TimeDifference( packet->packetTime, packet->sentTime );
@@ -696,7 +696,7 @@ int reporter_handle_packet( ReportHeader *reporthdr ) {
                 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 ) {
@@ -709,9 +709,7 @@ int reporter_handle_packet( ReportHeader *reporthdr ) {
             if ( packet->packetID > data->PacketID ) {
                 data->PacketID = packet->packetID;
             }
-        }
     }
-
     // Print a report if appropriate
     return reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );
 }
@@ -786,11 +784,14 @@ int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int
         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;
+        if (isConnectionLess(stats))
+                stats->info.cntDatagrams = stats->PacketID;
+        else
+                stats->info.cntDatagrams = stats->cntDatagrams;
+        stats->info.TotalLen  = stats->TotalLen;
         stats->info.startTime = 0;
-        stats->info.endTime = TimeDifference( stats->packetTime, stats->startTime );
-        stats->info.free = 1;
+        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 );
@@ -808,9 +809,13 @@ int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int
             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);
+        if (isConnectionLess(stats)) {
+                stats->info.cntDatagrams = stats->PacketID - stats->lastDatagrams;
+                stats->lastDatagrams     = stats->PacketID;
+        } else {
+                stats->info.cntDatagrams = stats->cntDatagrams - stats->lastDatagrams;
+                stats->lastDatagrams     = stats->cntDatagrams;
+        }
         stats->info.TotalLen = stats->TotalLen - stats->lastTotal;
         stats->lastTotal = stats->TotalLen;
         stats->info.startTime = stats->info.endTime;
@@ -833,7 +838,7 @@ 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 ) ) {
+            if ( end != 0 && isPrintMSS( stats ) && !isConnectionLess( stats ) ) {
                 PrintMSS( stats );
             }
             break;
@@ -860,6 +865,8 @@ int reporter_print( ReporterData *stats, int type, int end ) {
 
 /* -------------------------------------------------------------------
  * Report the MSS and MTU, given the MSS (or a guess thereof)
+ * This works for connection-oriented protocols only: it expects
+ * the protocol to be either TCP or DCCP and will give error otherwise
  * ------------------------------------------------------------------- */
 
 // compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
@@ -867,8 +874,11 @@ int reporter_print( ReporterData *stats, int type, int end ) {
 
 #define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS  &&  inMSS >= (inMTU-80)
 
-void PrintMSS( ReporterData *stats ) {
-    int inMSS = getsock_tcp_mss( stats->info.transferID );
+void PrintMSS( ReporterData *stats )
+{
+    int inMSS = stats->mProtocol == kProto_TCP
+              ?   getsock_tcp_mss( stats->info.transferID )
+              :   getsock_dccp_mps( stats->info.transferID );
 
     if ( inMSS <= 0 ) {
         printf( report_mss_unsupported, stats->info.transferID );