Commit 4ff262c1 authored by Pramod R Sanaga's avatar Pramod R Sanaga

1) Removed potential memory leaks & added destructors for all classes.

2) Changed the number of redundant ACKs being sent to vary based on ACK size.
3) Libpcap loss at the sender is now handled - by sending packet sizes and
send times in the packets and having them echoed back in ACKs. Reordered
ACKs are detected as being seperate from libpcap loss and are ignored.
4) updated the plot creation python script to give out loss, maximum delay graphs.
parent 31c18595
......@@ -22,7 +22,7 @@
#define REMOTE_SERVER_PORT 1500
#define MAX_MSG 1600
#define SNAPLEN 128
#define SNAPLEN 1600
#include "UdpThroughputSensor.h"
#include "UdpMinDelaySensor.h"
......@@ -50,71 +50,12 @@ unsigned long long getTimeMicro()
return (tmpSecVal*1000*1000 + tmpUsecVal);
}
// This is not being used - because we are using libpcap.
// This is useful if SO_TIMESTAMP option is used instead of the timestamps given by libpcap.
void handleUDPMsg(struct sockaddr_in *clientAddr, char *udpMessage, int messageLen, struct timeval *timeStampVal)
{
/*
printf("Destination IP address = %s\n", inet_ntoa(ipPacket->ip_dst));
printf("Source port = %d\n", ntohs(udpHdr->source));
printf("Dest port = %d\n\n", ntohs(udpHdr->dest));
*/
//printf("Data being received = %c, %u, %lld, %u\n", *(unsigned char *)(dataPtr), *(unsigned int *)(dataPtr + 1), *(unsigned long long*)(dataPtr + 5), udpLen);
unsigned char packetType = udpMessage[0];
unsigned long long timeStamp = 0;
unsigned long long tmpSecVal = timeStampVal->tv_sec;
unsigned long long tmpUsecVal = timeStampVal->tv_usec;
timeStamp = (tmpSecVal*1000*1000 + tmpUsecVal);
int overheadLen = 46;
if(packetType == '0')// This is a udp data packet arriving here. Send an
// application level acknowledgement packet for it.
// TODO:The packet can also be leaving from this host - our libpcap filter
// ignores those for now - as such, nothing needs to be done for such packets.
{
/*
if(strcmp( inet_ntoa(ipPacket->ip_dst),"10.1.2.2" ) != 0 )
{
packetSensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp);
}
*/
}
else if(packetType == '1')
{
// We received an ACK, pass it on to the sensors.
// TODO: Ignore the ACKs being sent out from this host.
// TODO: For now, we are just passing the packet data part.
// For this to work correctly when integrated with magent,
// we also need to pass the local port, remote port and
// remote IP address, so that the connection can be looked up.
//Pass the received packet to udp sensors:
packetSensor->capturePacket(udpMessage, messageLen, overheadLen, timeStamp);
minDelaySensor->capturePacket(udpMessage, messageLen, overheadLen, timeStamp);
maxDelaySensor->capturePacket(udpMessage, messageLen,overheadLen, timeStamp);
throughputSensor->capturePacket(udpMessage, messageLen, overheadLen, timeStamp);
}
else
{
printf("ERROR: Unknown UDP packet received from remote agent\n");
return;
}
}
void handleUDP(struct pcap_pkthdr const *pcap_info, struct udphdr const *udpHdr, u_char *const udpPacketStart, struct ip const *ipPacket)
{
// Get a pointer to the data section of the UDP packet.
u_char *dataPtr = udpPacketStart + 8;
unsigned short udpLen = ntohs(udpHdr->len);
unsigned short udpLen = ntohs(udpHdr->len) - 8;
//printf("Data being received = %c, %u, %lld, %u\n", *(unsigned char *)(dataPtr), *(unsigned int *)(dataPtr + 1), *(unsigned long long*)(dataPtr + 5), udpLen);
......@@ -143,7 +84,7 @@ void handleUDP(struct pcap_pkthdr const *pcap_info, struct udphdr const *udpHdr,
{
if(strcmp( inet_ntoa(ipPacket->ip_dst),localIP ) != 0 )
{
packetSensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp);
packetSensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen, overheadLen, timeStamp);
}
}
else if(packetType == '1')
......@@ -160,10 +101,10 @@ void handleUDP(struct pcap_pkthdr const *pcap_info, struct udphdr const *udpHdr,
if(strcmp( inet_ntoa(ipPacket->ip_dst),localIP ) == 0 )
{
// Pass the captured packet to the udp sensors.
packetSensor->capturePacket(reinterpret_cast<char *> (dataPtr), udpLen - 8, overheadLen, timeStamp);
minDelaySensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp);
maxDelaySensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp);
throughputSensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp);
packetSensor->capturePacket(reinterpret_cast<char *> (dataPtr), udpLen, overheadLen, timeStamp);
minDelaySensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen, overheadLen, timeStamp);
maxDelaySensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen, overheadLen, timeStamp);
throughputSensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen, overheadLen, timeStamp);
}
}
else
......@@ -356,19 +297,18 @@ int main(int argc, char *argv[])
init_pcap(argv[1], htons(cliAddr.sin_port));
// Open a file and pass the handle to the throughput sensor.
std::ofstream throughputStream;
std::ofstream logStream;
throughputStream.open("Throughput.log", std::ios::out);
logStream.open("stats.log", std::ios::out);
// Initialize the sensors.
packetSensor = new UdpPacketSensor(globalUdpState);
throughputSensor = new UdpThroughputSensor(globalUdpState, throughputStream);
maxDelaySensor = new UdpMaxDelaySensor(globalUdpState);
minDelaySensor = new UdpMinDelaySensor(globalUdpState);
throughputSensor = new UdpThroughputSensor(globalUdpState, logStream);
maxDelaySensor = new UdpMaxDelaySensor(globalUdpState, logStream);
minDelaySensor = new UdpMinDelaySensor(globalUdpState, logStream);
char packetData[1600];
unsigned int curSeqNum = 0;
unsigned long long sendTime;
unsigned short int curSeqNum = 0;
// Timeout for the non-blocking socket reads and writes.
struct timeval selectTimeout;
......@@ -384,7 +324,8 @@ int main(int argc, char *argv[])
// Number of packets, Size of the packets to be sent, and their sending rate.
packetCount = atoi(argv[4]);
unsigned long long lastSendTime = 0;
int packetLen = atoi(argv[5]);
unsigned long long curTime;
unsigned short int packetLen = atoi(argv[5]);
long sendRate = atoi(argv[6]);
int overheadLen = 20 + 8 + 14 + 4;
......@@ -396,6 +337,8 @@ int main(int argc, char *argv[])
lastSendTime = getTimeMicro();
echoLen = sizeof(echoServAddr);
FILE *sendDevFile = fopen("SendDeviation.log", "w");
/* send data */
while(true)
{
......@@ -417,18 +360,35 @@ int main(int argc, char *argv[])
// For now, take a command line argument giving the rate
// at which UDP packets should be sent ( this rate includes
// the overhead for UDP, IP & ethernet headers ( &ethernet checksum)
if(getTimeMicro() - lastSendTime > timeInterval)
curTime = getTimeMicro();
if(curTime - lastSendTime > timeInterval)
{
logStream << "SendDeviation:TIME="<<curTime<<",Deviation="<< curTime - lastSendTime - timeInterval<<std::endl;
curSeqNum++;
// Indicate that this is a data UDP packet - not an ACK.
packetData[0] = '0';
// Put the sequence number of the packet.
memcpy(&packetData[1],&curSeqNum, sizeof(unsigned int));
memcpy(&packetData[1],&curSeqNum, globalConsts::USHORT_INT_SIZE);
// Copy the size of the packet.. This can be
// by the sensors in case they miss this packet
// because of libpcap buffer overflow.
// The size of the packet & its timestamp at the
// sender are echoed in the ACKs.
memcpy(&packetData[1 + globalConsts::USHORT_INT_SIZE],&packetLen, globalConsts::USHORT_INT_SIZE);
// Copy the timestamp of when this packet is being sent.
// This timestamp will not be as accurate as
// the one captured by libpcap, but can be
// used as a fallback option in case we miss
// this packet because of a libpcap buffer overflow.
memcpy(&packetData[1 + 2*globalConsts::USHORT_INT_SIZE], &curTime, globalConsts::ULONG_LONG_SIZE);
memcpy(&packetData[1 + sizeof(unsigned int)],&packetLen, sizeof(unsigned int));
sendTime = getTimeMicro();
lastSendTime = sendTime;
lastSendTime = curTime;
rc = sendto(sd, packetData, packetLen, flags,
(struct sockaddr *) &remoteServAddr,
......@@ -464,5 +424,6 @@ int main(int argc, char *argv[])
}
fclose(sendDevFile);
return 0;
}
......@@ -12,4 +12,15 @@
#include <climits>
#include <limits.h>
namespace globalConsts {
const short int USHORT_INT_SIZE = sizeof(unsigned short int);
const short int ULONG_LONG_SIZE = sizeof(unsigned long long);
const short int UCHAR_SIZE = sizeof(unsigned char);
const static int redunAckSize = 2*USHORT_INT_SIZE + ULONG_LONG_SIZE;
const static int seqNumSize = USHORT_INT_SIZE;
const static int minAckPacketSize = 1 + 2*USHORT_INT_SIZE + ULONG_LONG_SIZE;
}
#endif
#include "UdpMaxDelaySensor.h"
UdpMaxDelaySensor::UdpMaxDelaySensor(UdpState &udpStateVal)
UdpMaxDelaySensor::UdpMaxDelaySensor(UdpState &udpStateVal, ofstream &outStreamVal)
: maxDelay(0),
udpStateInfo(udpStateVal)
udpStateInfo(udpStateVal),
outStream(outStreamVal)
{
}
......@@ -15,36 +16,47 @@ void UdpMaxDelaySensor::localSend(char *packetData, int Len,int overheadLen, uns
void UdpMaxDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp)
{
int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long);
if(Len < minSize)
if(Len < globalConsts::minAckPacketSize)
{
cout << "Error: UDP packet data sent to MaxDelaySensor::localAck was less than the "
" required minimum "<< minSize << " bytes\n";
udpStateInfo.ackError = true;
" required minimum "<< globalConsts::minAckPacketSize << " bytes\n";
return;
}
// Something went wrong with this packet - either the packet was not
// the minimum size or it was a re-ordered ACK - don't do anything
// This is a re-ordered ACK - don't do anything
// with it - just return.
if( udpStateInfo.ackError == true )
return;
int numRedunAcks = static_cast<int>(packetData[0]);
vector<UdpPacketInfo * >::iterator vecIterator;
unsigned int seqNum = *(unsigned int *)(packetData + 1);
unsigned short int seqNum = *(unsigned short int *)(packetData + 1);
unsigned short int echoedPacketSize = *(unsigned short int *)(packetData + 1 + globalConsts::USHORT_INT_SIZE);
unsigned long long echoedTimestamp = *(unsigned long long *)(packetData + 1 + 2*globalConsts::USHORT_INT_SIZE);
unsigned long long oneWayQueueDelay;
bool eventFlag = false;
vector<UdpPacketInfo>::iterator vecIterator;
vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), seqNum));
// Find the one way RTT for this packet.
oneWayQueueDelay = (timeStamp - (*vecIterator)->timeStamp)/2;
// We lost this packet send time due to loss in libpcap, use the
// time echoed in the ACK packet.
if(udpStateInfo.isAckFake == true)
oneWayQueueDelay = (timeStamp - echoedTimestamp)/2;
else
oneWayQueueDelay = (timeStamp - (*vecIterator).timeStamp)/2;
// Scale the value of one way RTT, so that it is correct for a transmission
// size of 1500 bytes.
oneWayQueueDelay = ( oneWayQueueDelay )*1500 / (overheadLen + Len + 1);
// 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.
if(udpStateInfo.isAckFake == true)
oneWayQueueDelay = ( oneWayQueueDelay )*1518 / (overheadLen + echoedPacketSize);
else
oneWayQueueDelay = ( oneWayQueueDelay )*1518 / ((*vecIterator).packetSize);
// Find the queuing delay for this packet, by subtracting the
// one way minimum delay from the above value.
......@@ -63,6 +75,7 @@ void UdpMaxDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsi
// Report the maximum delay
cout << "New Max Delay = " << maxDelay << "\n";
}
outStream << "MAXD:TIME="<<timeStamp<<",MAXD="<<maxDelay<<endl;
udpStateInfo.maxDelay = maxDelay;
}
......@@ -10,13 +10,14 @@ class UdpSensor;
class UdpMaxDelaySensor:public UdpSensor{
public:
explicit UdpMaxDelaySensor(UdpState &udpStateVal);
explicit UdpMaxDelaySensor(UdpState &udpStateVal, ofstream &outStreamVal);
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:
unsigned long long maxDelay;
UdpState &udpStateInfo;
ofstream &outStream;
};
#endif
#include "UdpMinDelaySensor.h"
UdpMinDelaySensor::UdpMinDelaySensor(UdpState &udpStateVal)
UdpMinDelaySensor::UdpMinDelaySensor(UdpState &udpStateVal, ofstream &outStreamVal)
: minDelay(ULONG_LONG_MAX),
udpStateInfo(udpStateVal)
udpStateInfo(udpStateVal),
outStream(outStreamVal)
{
}
......@@ -16,36 +17,47 @@ void UdpMinDelaySensor::localSend(char *packetData, int Len,int overheadLen,unsi
void UdpMinDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp)
{
int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long);
if(Len < minSize)
if(Len < globalConsts::minAckPacketSize)
{
cout << "Error: UDP packet data sent to MinDelaySensor::localAck was less than the "
" required minimum "<< minSize << " bytes\n";
udpStateInfo.ackError = true;
" required minimum "<< globalConsts::minAckPacketSize << " bytes\n";
return;
}
// Something went wrong with this packet - either the packet was not
// the minimum size or it was a re-ordered ACK - don't do anything
// 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);
unsigned short int echoedPacketSize = *(unsigned short int *)(packetData + 1 + globalConsts::USHORT_INT_SIZE);
unsigned long long echoedTimestamp = *(unsigned long long *)(packetData + 1 + 2*globalConsts::USHORT_INT_SIZE);
int numRedunAcks = static_cast<int>(packetData[0]);
vector<UdpPacketInfo * >::iterator vecIterator;
unsigned int seqNum = *(unsigned int *)(packetData + 1);
unsigned long long oneWayDelay;
bool eventFlag = false;
vector<UdpPacketInfo >::iterator vecIterator;
vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), seqNum));
// Calculate the one way delay as half of RTT.
oneWayDelay = (timeStamp - (*vecIterator)->timeStamp)/2;
// We lost this packet send time due to loss in libpcap, use the
// time echoed in the ACK packet.
if(udpStateInfo.isAckFake == true)
oneWayDelay = (timeStamp - echoedTimestamp)/2;
else
oneWayDelay = (timeStamp - (*vecIterator).timeStamp)/2;
// Calculate the delay for the maximum sized packet.
oneWayDelay = ( oneWayDelay ) * 1500 / (overheadLen + Len + 1);
// 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.
if(udpStateInfo.isAckFake == true)
oneWayDelay = ( oneWayDelay ) * 1518 / (overheadLen + echoedPacketSize);
else
oneWayDelay = ( oneWayDelay ) * 1518 / ( (*vecIterator).packetSize);
// Set this as the new minimum one way delay.
if(oneWayDelay < minDelay)
......@@ -54,47 +66,15 @@ void UdpMinDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsi
minDelay = oneWayDelay;
}
int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long);
int seqNumSize = sizeof(unsigned int);
// We should not be calculating the minimum delay based on the
// redundant ACKs - because we cannot exactly calculate their
// RTT values, from just the receiver timestamps.
/*
if(numRedunAcks > 0)
{
int i;
unsigned int redunSeqNum;
unsigned long timeDiff;
for(i = 0;i < numRedunAcks; i++)
{
redunSeqNum = *(unsigned int *)(packetData + minSize + i*redunAckSize);
timeDiff = *(unsigned long *)(packetData + minSize + i*redunAckSize + seqNumSize);
vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), redunSeqNum));
if(vecIterator != udpStateInfo.recentSentPackets.end())
{
oneWayDelay = (timeStamp - timeDiff - (*vecIterator)->timeStamp ) /2;
oneWayDelay = ( oneWayDelay ) * 1500 / ( (*vecIterator)->packetSize + overheadLen );
if(oneWayDelay > 0 && oneWayDelay < minDelay)
{
eventFlag = true;
minDelay = oneWayDelay;
minDelayBytes = (*vecIterator)->packetSize + overheadLen;
}
}
}
}
*/
// Send an event message to the monitor to change the value of minimum one way delay.
if(eventFlag == true)
{
cout << "New Min delay = " << minDelay << "\n";
}
outStream << "MIND:TIME="<<timeStamp<<",MIND="<<minDelay<<endl;
udpStateInfo.minDelay = minDelay;
}
......@@ -10,13 +10,14 @@ class UdpSensor;
class UdpMinDelaySensor:public UdpSensor{
public:
explicit UdpMinDelaySensor(UdpState &udpStateVal);
explicit UdpMinDelaySensor(UdpState &udpStateVal, ofstream &outStreamVal);
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:
unsigned long long minDelay;
UdpState &udpStateInfo;
ofstream &outStream;
};
#endif
#include "UdpPacketInfo.h"
UdpPacketInfo::UdpPacketInfo(unsigned int seqVal, unsigned int packetSizeVal, unsigned long long timeStampVal, bool isFastPacketVal)
UdpPacketInfo::UdpPacketInfo()
{
}
UdpPacketInfo::UdpPacketInfo(unsigned short int seqVal,unsigned short int packetSizeVal, unsigned long long timeStampVal)
:seqNum(seqVal),
packetSize(packetSizeVal),
timeStamp(timeStampVal),
isFastPacket(isFastPacketVal),
lastTimeDiff(0)
timeStamp(timeStampVal)
{
}
......@@ -3,12 +3,13 @@
class UdpPacketInfo{
public:
explicit UdpPacketInfo::UdpPacketInfo(unsigned int, unsigned int, unsigned long long, bool);
unsigned int seqNum;
unsigned int packetSize;
UdpPacketInfo::UdpPacketInfo();
UdpPacketInfo::UdpPacketInfo(unsigned short int, unsigned short int, unsigned long long);
unsigned short int seqNum;
unsigned short int packetSize;
unsigned long long timeStamp;
bool isFastPacket;
unsigned long long lastTimeDiff;
bool isFake;
};
#endif
#include "UdpPacketSensor.h"
UdpPacketSensor::UdpPacketSensor(UdpState &udpStateVal)
:udpStateInfo(udpStateVal)
:udpStateInfo(udpStateVal),
lastSeenSeqNum(-1)
{
lastPacketTime = 0;
}
UdpPacketSensor::~UdpPacketSensor()
{
// Empty the list used to store the packets.
sentPacketList.clear();
}
void UdpPacketSensor::localSend(char *packetData, int Len, int overheadLen, unsigned long long timeStamp)
{
int minSize = 2*sizeof(unsigned int);
int minSize = 2*globalConsts::USHORT_INT_SIZE;
if(Len < minSize)
{
cout << "Error: UDP packet data sent to PacketSensor::localSend was less than the "
" required minimum "<< minSize << " bytes\n";
udpStateInfo.sendError = true;
return;
}
udpStateInfo.sendError = false;
unsigned int seqNum = *(unsigned int *)(packetData);
unsigned int packetSize = *(unsigned int *)(packetData + sizeof(unsigned int));
bool isFastPacket = false;
unsigned long long sendTimeDelta = 0;
unsigned short int seqNum = *(unsigned short int *)(packetData);
unsigned short int packetSize = *(unsigned short int *)(packetData + globalConsts::USHORT_INT_SIZE) + overheadLen;
UdpPacketInfo tmpPacketInfo;
if(lastPacketTime == 0)
lastPacketTime = timeStamp;
else
if(lastSeenSeqNum != -1)
{
// We missed some packets because of loss in libpcap buffer.
// Add fake packets to the sent list, their sizes and time stamps
// are unknown - but they can be gathered from the ACK packets.
if(seqNum > (lastSeenSeqNum + 1))
{
for(int i = 1;i < seqNum - lastSeenSeqNum ; i++)
{
tmpPacketInfo.seqNum = lastSeenSeqNum + i;
tmpPacketInfo.isFake = true;
sendTimeDelta = timeStamp - lastPacketTime;
lastPacketTime = timeStamp;
sentPacketList.push_back(tmpPacketInfo);
}
}
}
if(! sentPacketList.empty())
sentPacketList.back()->lastTimeDiff = sendTimeDelta;
sentPacketList.push_back(new UdpPacketInfo(seqNum, packetSize, timeStamp, isFastPacket));
lastSeenSeqNum = seqNum;
tmpPacketInfo.seqNum = seqNum;
tmpPacketInfo.packetSize = packetSize;
tmpPacketInfo.timeStamp = timeStamp;
tmpPacketInfo.isFake = false;
sentPacketList.push_back(tmpPacketInfo);
}
void UdpPacketSensor::localAck(char *packetData, int Len, int overheadLen, unsigned long long timeStamp)
{
int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long);
if(Len < minSize)
if(Len < globalConsts::minAckPacketSize)
{
cout << "Error: UDP packet data sent to PacketSensor::localAck was less than the "
" minimum "<< minSize << " bytes\n";
udpStateInfo.ackError = true;
" minimum "<< globalConsts::minAckPacketSize << " bytes\n";
return;
}
unsigned int seqNum = *(unsigned int *)(packetData + 1);
unsigned short int seqNum = *(unsigned short int *)(packetData + 1);
// Find the entry for the packet this ACK is acknowledging, and
// remove it from the sent(&unacked) packet list.
list<UdpPacketInfo * >::iterator listIterator;
list<UdpPacketInfo >::iterator listIterator;
listIterator = find_if(sentPacketList.begin(), sentPacketList.end(), bind2nd(equalSeqNum(), seqNum));
if(listIterator == sentPacketList.end())
{
cout << "ERROR: Unacked packet list is incorrect Or incorrect"
"acknowledgement received for seqNum = "<<seqNum<<" in PacketSensor::localAck\n";
cout << "WARNING: Unknown seq number "<<seqNum<<" is being ACKed. "
"We might have received "
" a reordered ACK, which has already been ACKed using redundant ACKs .\n";
udpStateInfo.ackError = true;
return;
}
udpStateInfo.ackError = false;
else
udpStateInfo.ackError = false;
int i;
// We received an ACK correctly(without reordering), but we dont have any record of ever
// sending the original packet(Actually, we have a fake packet inserted into our send list)
// -- this indicates libpcap loss.
if( (*listIterator).isFake == true)
udpStateInfo.isAckFake = true;
else
udpStateInfo.isAckFake = false;
// Remove the old state information.
for(i = 0;i < udpStateInfo.recentSentPackets.size(); i++)
delete udpStateInfo.recentSentPackets[i];
// Remove the old state information.
udpStateInfo.recentSentPackets.clear();
udpStateInfo.packetLoss = 0;
udpStateInfo.fastPacketLoss = 0;
udpStateInfo.lostPacketDelay = 0;
udpStateInfo.lastSentTime = (ULONG_LONG_MAX);
int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long);
int numRedunAcks = static_cast<int>(packetData[0]);
int i;
unsigned char numRedunAcksChar = 0;
int numRedunAcks = 0;
// Read how many redundant ACKs are being sent in this packet.
memcpy(&numRedunAcksChar, &packetData[0], globalConsts::UCHAR_SIZE);
numRedunAcks = static_cast<int>(numRedunAcksChar);
// Store an iterator to the current seqNum being acknowledge, and delete it at the end.
list<UdpPacketInfo * >::iterator curPacketIterator = listIterator;
list<UdpPacketInfo >::iterator curPacketIterator = listIterator;
// Look at the redundant ACKs first.
UdpPacketInfo tmpPacketInfo;
if(numRedunAcks > 0)
{
unsigned int redunSeqNum;
unsigned short int redunSeqNum;
for(i = 0; i < numRedunAcks; i++)
{
redunSeqNum = *(unsigned int *)(packetData + minSize + i*redunAckSize);
redunSeqNum = *(unsigned short int *)(packetData + globalConsts::minAckPacketSize + i*globalConsts::redunAckSize);
listIterator = sentPacketList.end();
// Check whether the packet that this redundant ACK refers to exists
......@@ -108,18 +129,24 @@ void UdpPacketSensor::localAck(char *packetData, int Len, int overheadLen, unsig
// from the list and consider it acked.
if(listIterator != curPacketIterator && listIterator != sentPacketList.end())
{
udpStateInfo.recentSentPackets.push_back(new UdpPacketInfo((*listIterator)->seqNum, (*listIterator)->packetSize, (*listIterator)->timeStamp, (*listIterator)->isFastPacket) );
tmpPacketInfo.seqNum = (*listIterator).seqNum;
tmpPacketInfo.packetSize = (*listIterator).packetSize;
tmpPacketInfo.timeStamp = (*listIterator).timeStamp;
tmpPacketInfo.isFake = (*listIterator).isFake;
if( (*listIterator)->timeStamp < udpStateInfo.lastSentTime)
udpStateInfo.lastSentTime = (*listIterator)->timeStamp;
udpStateInfo.recentSentPackets.push_back(tmpPacketInfo);
delete (*listIterator);
sentPacketList.erase(listIterator);
}
}
}
udpStateInfo.recentSentPackets.push_back(new UdpPacketInfo((*curPacketIterator)->seqNum, (*curPacketIterator)->packetSize, (*curPacketIterator)->timeStamp, (*curPacketIterator)->isFastPacket));
tmpPacketInfo.seqNum = (*curPacketIterator).seqNum;
tmpPacketInfo.packetSize = (*curPacketIterator).packetSize;
tmpPacketInfo.timeStamp = (*curPacketIterator).timeStamp;
tmpPacketInfo.isFake = (*curPacketIterator).isFake;
udpStateInfo.recentSentPackets.push_back(tmpPacketInfo);
// Check for packet loss - if we have any unacked packets with sequence
// numbers less than the received ACK seq number, then the packets/or their ACKS
......@@ -127,18 +154,12 @@ void UdpPacketSensor::localAck(char *packetData, int Len, int overheadLen, unsig
// Find out how many packets were lost.
listIterator = find_if(sentPacketList.begin(), curPacketIterator, bind2nd(lessSeqNum(), seqNum ));
listIterator = find_if(sentPacketList.begin(), curPacketIterator, bind2nd(lessSeqNum(), seqNum));
if( (listIterator != sentPacketList.end()) && (listIterator != curPacketIterator ))
{
do{
if( (*listIterator)->timeStamp < udpStateInfo.lastSentTime)
udpStateInfo.lastSentTime = (*listIterator)->timeStamp;
udpStateInfo.lostPacketDelay += (*listIterator)->lastTimeDiff;
delete (*listIterator);
sentPacketList.erase(listIterator);
listIterator = sentPacketList.end();
......@@ -151,8 +172,5 @@ void UdpPacketSensor::localAck(char *packetData, int Len, int overheadLen, unsig