Ejemplo n.º 1
0
/*
 * 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;
    double usec_transit;

    data->packetTime = packet->packetTime;
    stats->socket = packet->socket;
    if ( packet->packetID < 0 ) {
        finished = 1;
        if ( reporthdr->report.mThreadMode != kMode_Client ) {
            data->TotalLen += packet->packetLen;
        }
    } else {
	if (!packet->emptyreport) {
	    // update fields common to TCP and UDP, client and server
	    data->TotalLen += packet->packetLen;
	    // update fields common to UDP client and server
            if ( isUDP( data ) ) {
		data->cntDatagrams++;
		stats->IPGsum += TimeDifference(data->packetTime, data->IPGstart );
		stats->IPGcnt++;
		data->IPGstart = data->packetTime;
		// Finally, update UDP server fields
		if (stats->mUDP == kMode_Server) {
		    //subsequent packets
		    double transit;
		    double deltaTransit;            
		    transit = TimeDifference( packet->packetTime, packet->sentTime );
		    // 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;
		    }
		    if (stats->transit.totcntTransit == 0) {
			// Very first packet
			stats->transit.minTransit = transit;
			stats->transit.maxTransit = transit;
			stats->transit.sumTransit = transit;
			stats->transit.cntTransit = 1;
			stats->transit.totminTransit = transit;
			stats->transit.totmaxTransit = transit;
			stats->transit.totsumTransit = transit;
			stats->transit.totcntTransit = 1;
			// For variance, working units is microseconds
			usec_transit = transit * 1e6;
			stats->transit.vdTransit = usec_transit;
			stats->transit.meanTransit = usec_transit;
			stats->transit.m2Transit = usec_transit * usec_transit;
			stats->transit.totvdTransit = usec_transit;
			stats->transit.totmeanTransit = usec_transit;
			stats->transit.totm2Transit = usec_transit * usec_transit;
		    } else {
			// from RFC 1889, Real Time Protocol (RTP) 
			// J = J + ( | D(i-1,i) | - J ) / 
			// Compute jitter
			deltaTransit = transit - stats->transit.lastTransit;
			if ( deltaTransit < 0.0 ) {
			    deltaTransit = -deltaTransit;
			}
			stats->jitter += (deltaTransit - stats->jitter) / (16.0);
			// Compute end/end delay stats
			stats->transit.sumTransit += transit;
			stats->transit.cntTransit++;
			stats->transit.totsumTransit += transit;
			stats->transit.totcntTransit++;
			// mean min max tests
			if (transit < stats->transit.minTransit) {
			    stats->transit.minTransit=transit;
			}
			if (transit < stats->transit.totminTransit) {
			    stats->transit.totminTransit=transit;
			}
			if (transit > stats->transit.maxTransit) {
			    stats->transit.maxTransit=transit;
			}
			if (transit > stats->transit.totmaxTransit) {
			    stats->transit.totmaxTransit=transit;
			}
			// For variance, working units is microseconds
			// variance interval
			usec_transit = transit * 1e6;
			stats->transit.vdTransit = usec_transit - stats->transit.meanTransit;
			stats->transit.meanTransit = stats->transit.meanTransit + (stats->transit.vdTransit / stats->transit.cntTransit);
			stats->transit.m2Transit = stats->transit.m2Transit + (stats->transit.vdTransit * (usec_transit - stats->transit.meanTransit));
			// variance total
			stats->transit.totvdTransit = usec_transit - stats->transit.totmeanTransit;
			stats->transit.totmeanTransit = stats->transit.totmeanTransit + (stats->transit.totvdTransit / stats->transit.totcntTransit);
			stats->transit.totm2Transit = stats->transit.totm2Transit + (stats->transit.totvdTransit * (usec_transit - stats->transit.totmeanTransit));
		    }
		    stats->transit.lastTransit = transit;
		}
	    } else if (reporthdr->report.mThreadMode == kMode_Server && (packet->packetLen > 0)) {
		int bin;
		// mean min max tests
		stats->tcp.read.cntRead++;
		stats->tcp.read.totcntRead++;
		bin = (int)floor((packet->packetLen -1)/stats->tcp.read.binsize);
		stats->tcp.read.bins[bin]++;
		stats->tcp.read.totbins[bin]++;
	    } else if (reporthdr->report.mThreadMode == kMode_Client) {
		if (packet->errwrite) { 
		    stats->tcp.write.WriteErr++;
		    stats->tcp.write.totWriteErr++;
		}
		else { 
		    stats->tcp.write.WriteCnt++;
		    stats->tcp.write.totWriteCnt++;
		}
	    }
	} else if ((stats->mUDP == kMode_Server) &&	\
		   (stats->transit.cntTransit == 0)) {
	    // This is the case when empty reports
	    // cross the report interval boundary
	    // Hence, set the per interval min to infinity
	    // and the per interval max and sum to zero
	    stats->transit.minTransit = FLT_MAX;
	    stats->transit.maxTransit = FLT_MIN;
	    stats->transit.sumTransit = 0;
	    stats->transit.vdTransit = 0;
	    stats->transit.meanTransit = 0;
	    stats->transit.m2Transit = 0;
	}
    }
    // Print a report if appropriate
    return reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );
}
Ejemplo n.º 2
0
/*
 * 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 = 0.0;
            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);
                stats->delay += transit*1000;
                stats->delay_total += transit*1000;
            }
            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++;
                    if (reporthdr->report.mThreadMode != kMode_Client)
                    {
                        struct out_of_order_packet *oop;
                        if (!(oop = (struct out_of_order_packet *) malloc(sizeof(struct out_of_order_packet))))
                        {
                            fprintf(stderr, "Out of memory");
                            exit(1);
                        }
                        oop->packetID = packet->packetID;
#ifndef WIN32
                        //printf("Packet %d out of order\n", packet->packetID);
                        LIST_INSERT_HEAD(&(data->out_of_order_packets), oop, list);
#endif
                    }
                } else {
                    data->cntError += packet->packetID - data->PacketID - 1;
                    if (reporthdr->report.mThreadMode != kMode_Client)
                    {
                        struct lost_packet_interval *lpi;
                        if (!(lpi = (struct lost_packet_interval *) malloc(sizeof(struct lost_packet_interval))))
                        {
                            fprintf(stderr, "Out of memory");
                            exit(1);
                        }
                        lpi->from = (data->PacketID + 1);
                        lpi->to = (packet->packetID - 1);
#ifndef WIN32
                        LIST_INSERT_HEAD(&data->lost_packets, lpi, list);
                        /*
                        printf("Packet %d revealed a loss gap from %d, "
                            "total loss %d\n", packet->packetID,
                            data->PacketID, data->cntError);
                        */
#endif
                    }
                }
            }
            // 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 );
}