Commit ff60e6d7 authored by Pramod R Sanaga's avatar Pramod R Sanaga
Browse files

*** empty log message ***

parent 26d3a7a9
#include "UdpAvgThroughputSensor.h"
UdpAvgThroughputSensor::UdpAvgThroughputSensor(UdpLossSensor *lossSensorVal,UdpState &udpStateVal, std::ofstream &logStreamVal)
: lastAckTime(0),
throughputKbps(0.0),
udpStateInfo(udpStateVal),
logStream(logStreamVal)
{
lossSensor = lossSensorVal;
minSamples = 0;
queuePtr = 0;
}
UdpAvgThroughputSensor::~UdpAvgThroughputSensor()
{
}
void UdpAvgThroughputSensor::localSend(char *packetData, int Len, int overheadLen, unsigned long long timeStamp)
{
// Do nothing.
}
void UdpAvgThroughputSensor::localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp)
{
if(Len < globalConsts::minAckPacketSize )
{
logStream << "ERROR::UDP packet data sent to ThroughputSensor::localAck was less than the "
" required minimum "<< globalConsts::minAckPacketSize<< " bytes\n";
return;
}
// This is a re-ordered ACK - don't do anything
// with it - just return.
if( udpStateInfo.ackError == true )
return;
// Find out how many redundant ACKs this packet is carrying - 0 to 121.
unsigned char numRedunAcksChar = 0;
memcpy(&numRedunAcksChar, &packetData[0], globalConsts::UCHAR_SIZE);
int numRedunAcks = static_cast<int>(numRedunAcksChar);
int numThroughputAcks = 1;
double avgThroughput = 0;
// This is the timestamp at the receiver, when the original packet was received.
unsigned long long currentAckTimeStamp = *(unsigned long long *)(packetData + 1 + 2*globalConsts::USHORT_INT_SIZE );
// This is the first ACK we have seen, store its receiver timestamp
// and return, we cannot calculate throughput from just one ACK - at least 2.
if(lastAckTime == 0)
{
lastAckTime = currentAckTimeStamp;
return;
}
unsigned short int seqNum = *(unsigned int *)(packetData + 1);
unsigned short int echoedPacketSize = *(unsigned short int *)(packetData + 1 + globalConsts::USHORT_INT_SIZE);
unsigned long long ackTimeDiff = (currentAckTimeStamp - lastAckTime);
vector<UdpPacketInfo>::iterator vecIterator;
UdpAck tmpUdpAck;
unsigned long long timeDiff = 0;
// Average the throughput over all the packets being acknowledged.
if(numRedunAcks > 0)
{
int i;
unsigned short int redunSeqNum;
unsigned short int redunPacketSize;
for(i = 0;i < numRedunAcks; i++)
{
redunSeqNum = *(unsigned short int *)(packetData + 1 + globalConsts::minAckPacketSize + i*globalConsts::redunAckSize);
redunPacketSize = *(unsigned short int *)(packetData + 1 + globalConsts::minAckPacketSize + i*globalConsts::redunAckSize + globalConsts::USHORT_INT_SIZE);
// Find if this redundant ACK is useful - or it was acked before.
vecIterator = find_if(udpStateInfo.currentAckedPackets.begin(), udpStateInfo.currentAckedPackets.end(), bind2nd(equalSeqNum(), redunSeqNum));
if(vecIterator != udpStateInfo.currentAckedPackets.end())
{
// Calculate throughput for the packet being acked by
// the redundant ACK.
numThroughputAcks++;
timeDiff = *(unsigned long long *)(packetData + 1 + globalConsts::minAckPacketSize + i*globalConsts::redunAckSize + globalConsts::seqNumSize);
if(ackTimeDiff - timeDiff == 0)
continue;
tmpUdpAck.timeTaken = ackTimeDiff - timeDiff;
// We lost the record of the size of this packet due to libpcap
// loss, use the length echoed back in the ACK.
if((*vecIterator).isFake == true)
{
avgThroughput += 8000000.0*( static_cast<double> ( redunPacketSize )) / ( static_cast<double>(ackTimeDiff - timeDiff)*1024.0 );
tmpUdpAck.packetSize = redunPacketSize;
}
else
{
avgThroughput += 8000000.0*( static_cast<double> ( (*vecIterator).packetSize )) / ( static_cast<double>(ackTimeDiff - timeDiff)*1024.0 );
tmpUdpAck.packetSize = (*vecIterator).packetSize;
}
ackList[queuePtr] = tmpUdpAck;
queuePtr = (queuePtr + 1)%100;
if(minSamples < 100)
minSamples++;
ackTimeDiff = timeDiff;
}
}
}
if(ackTimeDiff == 0)
{
calculateTput(timeStamp);
lastAckTime = currentAckTimeStamp;
return;
}
// Calculate the throughput for the current packet being ACKed.
vecIterator = find_if(udpStateInfo.currentAckedPackets.begin(), udpStateInfo.currentAckedPackets.end(), bind2nd(equalSeqNum(), seqNum));
if(vecIterator == udpStateInfo.currentAckedPackets.end())
{
printf("Error - Incorrect ack packets state passed to AvgThroughputSensor \n\n\n");
return;
}
// We lost the record of the size of this packet due to libpcap
// loss, use the length echoed back in the ACK.
if(udpStateInfo.isAckFake == true)
{
avgThroughput += 8000000.0*( static_cast<double> (echoedPacketSize )) / ( static_cast<double>(ackTimeDiff)*1024.0 );
tmpUdpAck.packetSize = echoedPacketSize;
}
else
{
avgThroughput += 8000000.0*( static_cast<double> ((*vecIterator).packetSize )) / ( static_cast<double>(ackTimeDiff)*1024.0 );
tmpUdpAck.packetSize = (*vecIterator).packetSize;
}
tmpUdpAck.timeTaken = ackTimeDiff - timeDiff;
ackList[queuePtr] = tmpUdpAck;
queuePtr = queuePtr + 1;
minSamples++;
if(minSamples < 100)
minSamples++;
calculateTput(timeStamp);
// Save the receiver timestamp of this ACK packet, so that we can
// use for calculating throughput for the next ACK packet.
lastAckTime = currentAckTimeStamp;
}
void UdpAvgThroughputSensor::calculateTput(unsigned long long timeStamp)
{
// We don't have enough samples to calculate the average throughput.
if(minSamples < 5)
return;
int sampleCount = ( minSamples < 100 )?minSamples:100;
int i, index;
unsigned long long timePeriod = 0;
long packetSizeSum = 0;
for(i = 0;(i < sampleCount&& timePeriod < 500000); i++)
{
index = (queuePtr - i + 100)%100;
timePeriod += ackList[index].timeTaken;
packetSizeSum += ackList[index].packetSize;
}
throughputKbps = 8000000.0*( static_cast<double> (packetSizeSum )) / ( static_cast<double>(timePeriod)*1024.0 );
// Calculate the average throughput.
// Send a message to the monitor with the new bandwidth.
if(lossSensor->getPacketLoss() == 0)
{
// Send this available bandwidth as a tentative value.
// To be used for dummynet events only if it is greater
// than the last seen value.
//logStream << "VALUE::Tentative bandwidth for seqNum = "<<seqNum<<", value = "<< throughputKbps <<"acktimeDiff = "<<ackTimeDiff<<"\n";
logStream << "AVGTPUT:TIME="<<timeStamp<<",TENTATIVE="<<throughputKbps<<endl;
logStream << "LOSS:TIME="<<timeStamp<<",LOSS=0"<<endl;
}
else
{
// Send this as the authoritative available bandwidth value.
//logStream << "VALUE::Authoritative bandwidth for seqNum = "<<seqNum<<", value = "<< throughputKbps <<"ackTimeDiff = "<<ackTimeDiff<<"\n";
logStream << "AVGTPUT:TIME="<<timeStamp<<",AUTHORITATIVE="<<throughputKbps<<endl;
logStream << "LOSS:TIME="<<timeStamp<<",LOSS="<<lossSensor->getPacketLoss()<<endl;
lossSensor->resetLoss();
}
logStream << "STAT:TOTAL_LOSS = "<<lossSensor->totalLoss<<endl;
}
#ifndef UDP_AVG_THROUGHPUT_SENSOR_PELAB_H
#define UDP_AVG_THROUGHPUT_SENSOR_PELAB_H
#include "UdpLibs.h"
#include "UdpState.h"
#include "UdpSensor.h"
#include "UdpLossSensor.h"
class UdpSensor;
class UdpLossSensor;
class UdpAvgThroughputSensor:public UdpSensor{
public:
explicit UdpAvgThroughputSensor(UdpLossSensor *lossSensorVal, UdpState &udpStateVal, ofstream &logStreamVal);
~UdpAvgThroughputSensor();
void localSend(char *packetData, int Len, int overheadLen, unsigned long long timeStamp);
void localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp);
private:
void calculateTput(unsigned long long timeStamp);
unsigned long long lastAckTime;
UdpLossSensor *lossSensor;
double throughputKbps;
UdpState &udpStateInfo;
ofstream &logStream;
UdpAck ackList[100];
int minSamples;
int queuePtr;
};
#endif
#include "UdpLossSensor.h"
UdpLossSensor::UdpLossSensor(UdpPacketSensor *packetHistoryVal, UdpRttSensor *rttSensorVal, UdpState &udpStateVal, ofstream &logStreamVal)
: packetLoss(0),
udpStateInfo(udpStateVal),
logStream(logStreamVal)
{
packetHistory = packetHistoryVal;
rttSensor = rttSensorVal;
totalLoss = 0;
}
UdpLossSensor::~UdpLossSensor()
{
}
void UdpLossSensor::localSend(char *packetData, int Len,int overheadLen, unsigned long long timeStamp)
{
}
void UdpLossSensor::localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp)
{
if(Len < globalConsts::minAckPacketSize)
{
logStream << "ERROR::UDP packet data sent to RttSensor::localAck was less than the "
" required minimum "<< globalConsts::minAckPacketSize << " bytes\n";
return;
}
// This is a re-ordered ACK - don't do anything
// with it - just return.
if( udpStateInfo.ackError == true )
return;
unsigned short int seqNum = *(unsigned short int *)(packetData + 1);
list<UdpPacketInfo>& unAckedPackets = packetHistory->getUnAckedPacketList();
list<UdpPacketInfo>::iterator vecIterator = unAckedPackets.begin();
list<UdpPacketInfo>::iterator tempIterator;
unsigned long long ewmaRtt = rttSensor->getRtt();
unsigned long long ewmaDevRtt = rttSensor->getDevRtt();
while(vecIterator != unAckedPackets.end())
{
if(seqNum > (*vecIterator).seqNum + 10 || ( timeStamp > (*vecIterator).timeStamp + 10*( ewmaRtt + 4*ewmaDevRtt)) )
{
tempIterator = vecIterator;
vecIterator++;
unAckedPackets.erase(tempIterator);
packetLoss++;
}
else
vecIterator++;
}
}
long UdpLossSensor::getPacketLoss()
{
return packetLoss;
}
void UdpLossSensor::resetLoss()
{
totalLoss += packetLoss;
packetLoss = 0;
}
#ifndef UDP_LOSS_SENSOR_PELAB_H
#define UDP_LOSS_SENSOR_PELAB_H
#include "UdpLibs.h"
#include "UdpState.h"
#include "UdpSensor.h"
#include "UdpPacketSensor.h"
#include "UdpRttSensor.h"
class UdpSensor;
class UdpPacketSensor;
class UdpRttSensor;
class UdpLossSensor:public UdpSensor{
public:
explicit UdpLossSensor(UdpPacketSensor *packetHistoryVal, UdpRttSensor *rttSensorVal, UdpState &udpStateVal, ofstream &logStreamVal);
~UdpLossSensor();
void localSend(char *packetData, int Len,int overheadLen, unsigned long long timeStamp);
void localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp);
long getPacketLoss();
void resetLoss();
long totalLoss;
private:
long packetLoss;
UdpState &udpStateInfo;
ofstream &logStream;
UdpPacketSensor *packetHistory;
UdpRttSensor *rttSensor;
};
#endif
#include "UdpRttSensor.h"
UdpRttSensor::UdpRttSensor(UdpState &udpStateVal, ofstream &logStreamVal)
: ewmaRtt(0),
ewmaDevRtt(0),
udpStateInfo(udpStateVal),
logStream(logStreamVal)
{
}
UdpRttSensor::~UdpRttSensor()
{
}
void UdpRttSensor::localSend(char *packetData, int Len,int overheadLen, unsigned long long timeStamp)
{
}
void UdpRttSensor::localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp)
{
if(Len < globalConsts::minAckPacketSize)
{
logStream << "ERROR::UDP packet data sent to RttSensor::localAck was less than the "
" required minimum "<< globalConsts::minAckPacketSize << " bytes\n";
return;
}
// This is a re-ordered ACK - don't do anything
// with it - just return.
if( udpStateInfo.ackError == true )
return;
// We lost information about this packet's send time due to loss
// in libpcap - don't use this packet for calculating RTT.
if(udpStateInfo.isAckFake == true)
return;
unsigned short int seqNum = *(unsigned short int *)(packetData + 1);
unsigned long long currentRtt;
vector<UdpPacketInfo>::iterator vecIterator;
vecIterator = find_if(udpStateInfo.currentAckedPackets.begin(), udpStateInfo.currentAckedPackets.end(), bind2nd(equalSeqNum(), seqNum));
// Find the RTT for this packet.
currentRtt = (timeStamp - (*vecIterator).timeStamp)/2;
// Scale the value of one way RTT, so that it is correct for a transmission
// size of 1518 bytes.
// We lost this packet size details due to loss in libpcap, use the
// size echoed in the ACK packet - this does not included the header
// overhead for the packet - we assume that the packet on the reverse path
// has the same overhead length as the original packet.
currentRtt = ( currentRtt )*1518 / ((*vecIterator).packetSize);
double alpha = 0.25, beta = 0.125;
if(ewmaRtt == 0)
{
ewmaRtt = currentRtt;
}
else
{
if(ewmaDevRtt == 0)
{
if(currentRtt > ewmaRtt)
ewmaDevRtt = currentRtt - ewmaRtt ;
else
ewmaDevRtt = ewmaRtt - currentRtt ;
}
else
{
if(currentRtt > ewmaRtt)
ewmaDevRtt = ewmaDevRtt*(1 - beta) + beta*(currentRtt - ewmaRtt);
else
ewmaDevRtt = ewmaDevRtt*(1 - beta) + beta*(ewmaRtt - currentRtt );
}
ewmaRtt = ewmaRtt*(1 - alpha) + currentRtt*alpha;
}
//cout<<"Current RTT = "<<currentRtt<<", emwaRtt = "<<ewmaRtt<<", dev = "<<ewmaDevRtt<<"\n\n";
}
unsigned long long UdpRttSensor::getRtt()
{
return ewmaRtt;
}
unsigned long long UdpRttSensor::getDevRtt()
{
return ewmaDevRtt;
}
#ifndef UDP_RTT_SENSOR_PELAB_H
#define UDP_RTT_SENSOR_PELAB_H
#include "UdpLibs.h"
#include "UdpState.h"
#include "UdpSensor.h"
class UdpSensor;
class UdpRttSensor:public UdpSensor{
public:
explicit UdpRttSensor(UdpState &udpStateVal, ofstream &logStreamVal);
~UdpRttSensor();
void localSend(char *packetData, int Len,int overheadLen, unsigned long long timeStamp);
void localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp);
unsigned long long getRtt();
unsigned long long getDevRtt();
private:
unsigned long long ewmaRtt, ewmaDevRtt;
UdpState &udpStateInfo;
ofstream &logStream;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment