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

1) Added a UdpSensorList class.

2) Replaced gettimeofday calls with TSC register reads.
3) Removed all recvfrom calls - no overhead for those calls & copying
packets to user space - this does not adversely affect performance.
4) More graphs!! and streamlined error/warning messages to be put into a single
log file.
parent 319e7ac5
......@@ -163,6 +163,24 @@ We currently ignore the reordering of packets/ACKs on forward/reverse paths.
If this happens persistently and is perceived as a characteristic of some links,
then it might need to be addressed.
Optimizations:
--------------
1) The UdpClient application sends packets at a fixed rate specified at the
command line. In order to keep of the time, gettimeofday() can be used. But,
on planet lab using gettimeofday() may cause the program to be scheduled
out because it is a system call. Instead, the sending times are now
being calculated by reading the values of the TSC register. Now,
the deviation between when we wish to send a packet and we actually send
it is around 2 ms against the 10+ ms when using gettimeofday.
2) Since we capture and process all UDP packets using libpcap, there is no
need to make recvfrom() calls, either at the sender or at the receiver. Those
calls have now been removed and we will not incur the overhead of the system calls
and the time to copy the packets to user space. I ran the application in a controlled
emulab environment and did not observe any increase in CPU usage when all the received
UDP packets were being dropped by the kernel ( due to full socket receive buffer ).
......
......@@ -10,7 +10,8 @@ OBJECTS=${COMPILE_DIR}/UdpClient.o \
${COMPILE_DIR}/UdpMaxDelaySensor.o \
${COMPILE_DIR}/UdpThroughputSensor.o \
${COMPILE_DIR}/UdpPacketInfo.o \
${COMPILE_DIR}/UdpSensor.o
${COMPILE_DIR}/UdpSensor.o \
${COMPILE_DIR}/UdpSensorList.o
COMMON_INCLUDES=UdpLibs.h \
......@@ -40,6 +41,9 @@ ${COMPILE_DIR}/UdpPacketInfo.o: UdpPacketInfo.cc UdpPacketInfo.h ${COMMON_INCLU
${COMPILE_DIR}/UdpSensor.o: UdpSensor.cc UdpSensor.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
${COMPILE_DIR}/UdpSensorList.o: UdpSensorList.cc UdpSensorList.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
clean:
rm -f ${COMPILE_DIR}/*.o ${EXECUTABLE}
......@@ -29,6 +29,7 @@
#include "UdpMaxDelaySensor.h"
#include "UdpPacketSensor.h"
#include "UdpState.h"
#include "UdpSensorList.h"
pcap_t *pcapDescriptor = NULL;
UdpThroughputSensor *throughputSensor;
......@@ -39,6 +40,19 @@ char localIP[16] = "";
struct UdpState globalUdpState;
struct pcap_stat pcapStats;
int currentPcapLoss = 0;
// Use this file handle to log messages - statistics and any warnings/errors.
std::ofstream logStream;
UdpSensorList *sensorList;
/* Grab the TSC register. */
inline volatile unsigned long long RDTSC() {
register unsigned long long TSC asm("eax");
asm volatile (".byte 0xf, 0x31" : : : "eax", "edx");
return TSC;
}
unsigned long long getTimeMicro()
{
struct timeval tp;
......@@ -50,11 +64,19 @@ unsigned long long getTimeMicro()
return (tmpSecVal*1000*1000 + tmpUsecVal);
}
void handleUDP(struct pcap_pkthdr const *pcap_info, struct udphdr const *udpHdr, u_char *const udpPacketStart, struct ip const *ipPacket)
void handleUDP(struct pcap_pkthdr const *pcap_info, struct udphdr const *udpHdr, unsigned char *udpPacketStart, struct ip const *ipPacket)
{
// Report any packets dropped in libpcap.
pcap_stats(pcapDescriptor, &pcapStats);
if(pcapStats.ps_drop > currentPcapLoss)
{
currentPcapLoss += pcapStats.ps_drop;
logStream <<"STAT::Number of packets lost in libpcap = "<<currentPcapLoss<<endl;
}
// Get a pointer to the data section of the UDP packet.
u_char *dataPtr = udpPacketStart + 8;
unsigned char *dataPtr = udpPacketStart + 8;
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);
......@@ -84,7 +106,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, overheadLen, timeStamp);
sensorList->capturePacket(reinterpret_cast<char *> (dataPtr), udpLen, overheadLen, timeStamp);
}
}
else if(packetType == '1')
......@@ -101,27 +123,24 @@ 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, 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);
sensorList->capturePacket(reinterpret_cast<char *> (dataPtr), udpLen, overheadLen, timeStamp);
}
}
else
{
printf("ERROR: Unknown UDP packet received from remote agent\n");
logStream <<"ERROR::Unknown format UDP packet received from remote agent"<<endl;
return;
}
}
int getLinkLayer(struct pcap_pkthdr const *pcap_info, const u_char *pkt_data)
int getLinkLayer(struct pcap_pkthdr const *pcap_info, unsigned char const *pkt_data)
{
unsigned int caplen = pcap_info->caplen;
if (caplen < sizeof(struct ether_header))
{
printf("A captured packet was too short to contain "
"an ethernet header");
logStream<<"ERROR::A captured packet was too short to contain "
"an ethernet header"<<endl;
return -1;
}
else
......@@ -131,13 +150,13 @@ int getLinkLayer(struct pcap_pkthdr const *pcap_info, const u_char *pkt_data)
}
}
void pcapCallback(u_char *user, const struct pcap_pkthdr *pcap_info, const u_char *pkt_data)
void pcapCallback(unsigned char *user, struct pcap_pkthdr const *pcap_info, unsigned char const *pkt_data)
{
int packetType = getLinkLayer(pcap_info, pkt_data);
if(packetType != ETHERTYPE_IP)
{
printf("Unknown link layer type: %d\n", packetType);
logStream<<"ERROR::Unknown link layer type: "<<packetType<<endl;
return;
}
......@@ -146,7 +165,7 @@ void pcapCallback(u_char *user, const struct pcap_pkthdr *pcap_info, const u_cha
if(bytesLeft < sizeof(struct ip))
{
printf("Captured packet was too short to contain an IP header.\n");
logStream<<"ERROR::Captured packet was too short to contain an IP header"<<endl;
return;
}
......@@ -157,19 +176,19 @@ void pcapCallback(u_char *user, const struct pcap_pkthdr *pcap_info, const u_cha
if(ipVersion != 4)
{
printf("Captured IP packet is not IPV4.\n");
logStream<<"ERROR::Captured IP packet is not IPV4."<<endl;
return;
}
if(ipHeaderLength < 5)
{
printf("Captured IP packet has header less than the minimum 20 bytes.\n");
logStream<<"ERROR::Captured IP packet has header less than the minimum 20 bytes.\n"<<endl;
return;
}
if(ipPacket->ip_p != IPPROTO_UDP)
{
printf("Captured packet is not a UDP packet.\n");
logStream<<"ERROR::Captured packet is not a UDP packet.\n"<<endl;
return;
}
......@@ -185,14 +204,14 @@ void pcapCallback(u_char *user, const struct pcap_pkthdr *pcap_info, const u_cha
if(bytesLeft < sizeof(struct udphdr))
{
printf("Captured packet is too small to contain a UDP header.\n");
logStream<<"ERROR::Captured packet is too small to contain a UDP header."<<endl;
return;
}
handleUDP(pcap_info,udpPacket,udpPacketStart, ipPacket);
}
void init_pcap(char *interface, unsigned int portNumber)
int init_pcap(char *interface, unsigned int portNumber)
{
struct bpf_program bpfProg;
char errBuf[PCAP_ERRBUF_SIZE];
......@@ -209,7 +228,7 @@ void init_pcap(char *interface, unsigned int portNumber)
if(pcapDescriptor == NULL)
{
printf("Error opening device %s with libpcap = %s\n", interface, errBuf);
logStream<<"ERROR::Error opening device "<<interface<<" with libpcap = "<< errBuf<<endl;
exit(1);
}
......@@ -218,6 +237,8 @@ void init_pcap(char *interface, unsigned int portNumber)
pcap_setnonblock(pcapDescriptor, 1, errBuf);
return pcap_get_selectable_fd(pcapDescriptor);
}
int main(int argc, char *argv[])
......@@ -233,11 +254,12 @@ int main(int argc, char *argv[])
/* check command line args */
if(argc < 7)
if(argc < 8)
{
printf("usage : %s <local-interface> <local-IP> <serverName> <packetCount> <packetSize> <SendRate-bps>\n", argv[0]);
printf("usage : %s <local-interface> <local-IP> <serverName> <packetCount> <packetSize> <SendRate-bps> <CPU-MHZ Integer>\n", argv[0]);
exit(1);
}
logStream.open("stats.log", std::ios::out);
strcpy(localIP, argv[2]);
/* get server IP address (no check if input is IP address or DNS name */
......@@ -245,7 +267,7 @@ int main(int argc, char *argv[])
if(h==NULL)
{
printf("%s: unknown host '%s' \n", argv[0], argv[3]);
logStream<<"ERROR:: "<<argv[0]<<": unknown host"<< argv[3]<<endl;
exit(1);
}
......@@ -262,7 +284,7 @@ int main(int argc, char *argv[])
if(sd<0)
{
printf("%s: cannot open socket \n",argv[0]);
logStream<<"ERROR:: "<<argv[0]<<": cannot open socket."<<endl;
exit(1);
}
......@@ -274,7 +296,7 @@ int main(int argc, char *argv[])
// Set the socket descriptor to be non-blocking.
if( fcntl(sd, F_SETFL, flags) < 0)
{
printf("Error setting non blocking socket flags with fcntl.\n");
logStream<<"ERROR::Error setting non blocking socket flags with fcntl."<<endl;
exit(1);
}
......@@ -287,25 +309,23 @@ int main(int argc, char *argv[])
if(rc<0)
{
printf("%s: cannot bind port\n", argv[0]);
logStream<<"ERROR::"<<argv[0]<<": cannot bind port 3200"<<endl;
exit(1);
}
flags = 0;
// Initialize the libpcap filter.
init_pcap(argv[1], htons(cliAddr.sin_port));
// Open a file and pass the handle to the throughput sensor.
std::ofstream logStream;
logStream.open("stats.log", std::ios::out);
// Initialize the sensors.
packetSensor = new UdpPacketSensor(globalUdpState);
throughputSensor = new UdpThroughputSensor(globalUdpState, logStream);
maxDelaySensor = new UdpMaxDelaySensor(globalUdpState, logStream);
minDelaySensor = new UdpMinDelaySensor(globalUdpState, logStream);
sensorList = new UdpSensorList(logStream);
sensorList->addSensor(UDP_PACKET_SENSOR);
sensorList->addSensor(UDP_THROUGHPUT_SENSOR);
sensorList->addSensor(UDP_MINDELAY_SENSOR);
sensorList->addSensor(UDP_MAXDELAY_SENSOR);
// Initialize the libpcap filter.
int pcapFD = init_pcap(argv[1], htons(cliAddr.sin_port));
char packetData[1600];
unsigned short int curSeqNum = 0;
......@@ -330,25 +350,37 @@ int main(int argc, char *argv[])
int overheadLen = 20 + 8 + 14 + 4;
// Fill in the MHz of the CPU - should be read from /proc/cpuinfo
long freqDivisor = atoi(argv[7]);
//long freqDivisor = 601;
long long timeInterval = 800000000 / sendRate;
timeInterval *= (packetLen + overheadLen);
timeInterval /= 100;
lastSendTime = getTimeMicro();
//lastSendTime = getTimeMicro();
lastSendTime = RDTSC();
echoLen = sizeof(echoServAddr);
FILE *sendDevFile = fopen("SendDeviation.log", "w");
/* send data */
while(true)
{
if(curSeqNum < packetCount)
{
// UDP sends do not block - we don't need to
// UDP sendTo blocks in Linux - we need to
// check if the socket is ready for writing.
FD_SET(sd, &writeFdSet);
select(sd + 1,NULL,&writeFdSet, NULL,&selectTimeout);
// Check whether any data is available in the pcap buffer
// for reading.
FD_SET(pcapFD, &readFdSet);
select(sd + pcapFD + 1,&readFdSet,&writeFdSet, NULL,&selectTimeout);
if(FD_ISSET(pcapFD, &readFdSet) != 0)
{
pcap_dispatch(pcapDescriptor, 1, pcapCallback, NULL);
}
if(FD_ISSET(sd, &writeFdSet) != 0)
{
......@@ -360,10 +392,16 @@ 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)
curTime = getTimeMicro();
if(curTime - lastSendTime > timeInterval)
// curTime = getTimeMicro();
// if( (curTime - lastSendTime) > timeInterval)
curTime = RDTSC();
if( (curTime - lastSendTime) > timeInterval*freqDivisor)
{
logStream << "SendDeviation:TIME="<<curTime<<",Deviation="<< curTime - lastSendTime - timeInterval<<std::endl;
logStream << "SendDeviation:TIME="<<curTime<<",Deviation="<< (curTime - lastSendTime)/freqDivisor - timeInterval<<std::endl;
// logStream << "SendDeviation:TIME="<<curTime<<",Deviation="<< (curTime - lastSendTime) - timeInterval<<std::endl;
curSeqNum++;
// Indicate that this is a data UDP packet - not an ACK.
......@@ -396,34 +434,18 @@ int main(int argc, char *argv[])
if(rc < 0)
{
printf("WARNING:Blocked in send = %d\n",errno);
}
else
{
pcap_dispatch(pcapDescriptor, 1, pcapCallback, NULL);
logStream<<"WARNING::Blocked in send, errno = "<<errno<<endl;
}
}
else
{
usleep(timeInterval - ( curTime - lastSendTime)/freqDivisor );
// usleep(timeInterval - ( curTime - lastSendTime));
}
}
}
// Check whether any data is available in the receive buffer
// for reading.
FD_SET(sd, &readFdSet);
select(sd + 1, &readFdSet, NULL, NULL,&selectTimeout);
if(FD_ISSET(sd, &readFdSet) != 0)
{
n = recvfrom(sd, msg, MAX_MSG, 0,
(struct sockaddr *) &echoServAddr, &echoLen);
if(n > 0)
pcap_dispatch(pcapDescriptor, 1, pcapCallback, NULL);
}
}
fclose(sendDevFile);
return 0;
}
......@@ -20,7 +20,9 @@ namespace globalConsts {
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;
const static int minAckPacketSize = 1 + 2*USHORT_INT_SIZE + 2*ULONG_LONG_SIZE;
}
enum {UDP_PACKET_SENSOR, UDP_THROUGHPUT_SENSOR, UDP_MINDELAY_SENSOR, UDP_MAXDELAY_SENSOR};
#endif
#include "UdpMaxDelaySensor.h"
UdpMaxDelaySensor::UdpMaxDelaySensor(UdpState &udpStateVal, ofstream &outStreamVal)
UdpMaxDelaySensor::UdpMaxDelaySensor(UdpState &udpStateVal, ofstream &logStreamVal)
: maxDelay(0),
udpStateInfo(udpStateVal),
outStream(outStreamVal)
logStream(logStreamVal)
{
}
UdpMaxDelaySensor::~UdpMaxDelaySensor()
{
}
......@@ -18,7 +23,7 @@ void UdpMaxDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsi
{
if(Len < globalConsts::minAckPacketSize)
{
cout << "Error: UDP packet data sent to MaxDelaySensor::localAck was less than the "
logStream << "ERROR::UDP packet data sent to MaxDelaySensor::localAck was less than the "
" required minimum "<< globalConsts::minAckPacketSize << " bytes\n";
return;
}
......@@ -30,7 +35,7 @@ void UdpMaxDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsi
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 echoedTimestamp = *(unsigned long long *)(packetData + 1 + 2*globalConsts::USHORT_INT_SIZE + globalConsts::ULONG_LONG_SIZE);
unsigned long long oneWayQueueDelay;
bool eventFlag = false;
......@@ -73,9 +78,10 @@ void UdpMaxDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsi
if(eventFlag == true)
{
// Report the maximum delay
cout << "New Max Delay = " << maxDelay << "\n";
logStream << "VALUE::New Max Delay = " << maxDelay << "\n";
}
outStream << "MAXD:TIME="<<timeStamp<<",MAXD="<<maxDelay<<endl;
logStream << "MAXD:TIME="<<timeStamp<<",MAXD="<<maxDelay<<endl;
logStream << "ACTUAL_MAXD:TIME="<<timeStamp<<",ACTUAL_MAXD="<<oneWayQueueDelay<<endl;
udpStateInfo.maxDelay = maxDelay;
}
......@@ -10,14 +10,17 @@ class UdpSensor;
class UdpMaxDelaySensor:public UdpSensor{
public:
explicit UdpMaxDelaySensor(UdpState &udpStateVal, ofstream &outStreamVal);
explicit UdpMaxDelaySensor(UdpState &udpStateVal, ofstream &logStreamVal);
~UdpMaxDelaySensor();
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;
ofstream &logStream;
};
#endif
#include "UdpMinDelaySensor.h"
UdpMinDelaySensor::UdpMinDelaySensor(UdpState &udpStateVal, ofstream &outStreamVal)
UdpMinDelaySensor::UdpMinDelaySensor(UdpState &udpStateVal, ofstream &logStreamVal)
: minDelay(ULONG_LONG_MAX),
udpStateInfo(udpStateVal),
outStream(outStreamVal)
logStream(logStreamVal)
{
}
UdpMinDelaySensor::~UdpMinDelaySensor()
{
}
......@@ -19,7 +24,7 @@ void UdpMinDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsi
{
if(Len < globalConsts::minAckPacketSize)
{
cout << "Error: UDP packet data sent to MinDelaySensor::localAck was less than the "
logStream << "ERROR::UDP packet data sent to MinDelaySensor::localAck was less than the "
" required minimum "<< globalConsts::minAckPacketSize << " bytes\n";
return;
}
......@@ -31,7 +36,7 @@ void UdpMinDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsi
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 echoedTimestamp = *(unsigned long long *)(packetData + 1 + 2*globalConsts::USHORT_INT_SIZE + globalConsts::ULONG_LONG_SIZE);
unsigned long long oneWayDelay;
bool eventFlag = false;
......@@ -73,8 +78,8 @@ void UdpMinDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsi
// 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";
logStream << "VALUE::New Min delay = " << minDelay << "\n";
}
outStream << "MIND:TIME="<<timeStamp<<",MIND="<<minDelay<<endl;
logStream << "MIND:TIME="<<timeStamp<<",MIND="<<minDelay<<endl;
udpStateInfo.minDelay = minDelay;
}
......@@ -10,14 +10,17 @@ class UdpSensor;
class UdpMinDelaySensor:public UdpSensor{
public:
explicit UdpMinDelaySensor(UdpState &udpStateVal, ofstream &outStreamVal);
explicit UdpMinDelaySensor(UdpState &udpStateVal, ofstream &logStreamVal);
~UdpMinDelaySensor();
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;
ofstream &logStream;
};
#endif
......@@ -11,3 +11,8 @@ UdpPacketInfo::UdpPacketInfo(unsigned short int seqVal,unsigned short int packet
{
}
UdpPacketInfo::~UdpPacketInfo()
{
}
......@@ -3,8 +3,10 @@
class UdpPacketInfo{
public:
UdpPacketInfo::UdpPacketInfo();
UdpPacketInfo::UdpPacketInfo(unsigned short int, unsigned short int, unsigned long long);
UdpPacketInfo();
UdpPacketInfo(unsigned short int, unsigned short int, unsigned long long);
~UdpPacketInfo();
unsigned short int seqNum;
unsigned short int packetSize;
unsigned long long timeStamp;
......
#include "UdpPacketSensor.h"
UdpPacketSensor::UdpPacketSensor(UdpState &udpStateVal)
UdpPacketSensor::UdpPacketSensor(UdpState &udpStateVal, ofstream &logStreamVal)
:udpStateInfo(udpStateVal),
lastSeenSeqNum(-1)
lastSeenSeqNum(-1),
logStream(logStreamVal)
{
}
......@@ -20,7 +21,7 @@ void UdpPacketSensor::localSend(char *packetData, int Len, int overheadLen, unsi
if(Len < minSize)
{
cout << "Error: UDP packet data sent to PacketSensor::localSend was less than the "
logStream << "ERROR::UDP packet data sent to PacketSensor::localSend was less than the "
" required minimum "<< minSize << " bytes\n";
return;
}
......@@ -43,6 +44,7 @@ void UdpPacketSensor::localSend(char *packetData, int Len, int overheadLen, unsi
sentPacketList.push_back(tmpPacketInfo);
}
udpStateInfo.libpcapSendLoss += (seqNum - lastSeenSeqNum - 1);
}
}
......@@ -60,7 +62,7 @@ void UdpPacketSensor::localAck(char *packetData, int Len, int overheadLen, unsig
{
if(Len < globalConsts::minAckPacketSize)
{
cout << "Error: UDP packet data sent to PacketSensor::localAck was less than the "
logStream << "ERROR::UDP packet data sent to PacketSensor::localAck was less than the "
" minimum "<< globalConsts::minAckPacketSize << " bytes\n";
return;
}
......@@ -75,7 +77,7 @@ void UdpPacketSensor::localAck(char *packetData, int Len, int overheadLen, unsig
if(listIterator == sentPacketList.end())
{
cout << "WARNING: Unknown seq number "<<seqNum<<" is being ACKed. "
logStream << "WARNING::Unknown seq number "<<seqNum<<" is being ACKed. "