Commit 907503de authored by Pramod R Sanaga's avatar Pramod R Sanaga

Initial Checkin of UDP code for FlexLab

parent 32983db4
EXECUTABLE=UdpClient
CC=g++ -g
CFLAGS=
COMPILE_DIR=.OBJECTS
OBJECTS=${COMPILE_DIR}/UdpClient.o \
${COMPILE_DIR}/UdpPacketSensor.o \
${COMPILE_DIR}/UdpMinDelaySensor.o \
${COMPILE_DIR}/UdpMaxDelaySensor.o \
${COMPILE_DIR}/UdpThroughputSensor.o \
${COMPILE_DIR}/UdpPacketInfo.o \
${COMPILE_DIR}/UdpSensor.o
COMMON_INCLUDES=UdpLibs.h \
UdpState.h
${EXECUTABLE}: ${OBJECTS}
${CC} -o $@ ${CFLAGS} $+ -lpcap
${COMPILE_DIR}/UdpClient.o: UdpClient.cc UdpPacketSensor.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
${COMPILE_DIR}/UdpMinDelaySensor.o: UdpMinDelaySensor.cc UdpMinDelaySensor.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
${COMPILE_DIR}/UdpMaxDelaySensor.o: UdpMaxDelaySensor.cc UdpMaxDelaySensor.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
${COMPILE_DIR}/UdpThroughputSensor.o: UdpThroughputSensor.cc UdpThroughputSensor.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
${COMPILE_DIR}/UdpPacketSensor.o: UdpPacketSensor.cc UdpPacketSensor.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
${COMPILE_DIR}/UdpPacketInfo.o: UdpPacketInfo.cc UdpPacketInfo.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
${COMPILE_DIR}/UdpSensor.o: UdpSensor.cc UdpSensor.h ${COMMON_INCLUDES}
${CC} -c ${CFLAGS} -o $@ $<
clean:
rm -f ${COMPILE_DIR}/*.o ${EXECUTABLE}
EXECUTABLE=UdpServer
${EXECUTABLE}: UdpServer.cc
g++ -o $@ UdpServer.cc -lpcap
This diff is collapsed.
This diff is collapsed.
#ifndef UDPLIBS_PELAB_H
#define UDPLIBS_PELAB_H
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <list>
#include <cstdlib>
#include <algorithm>
#include <functional>
#include <climits>
#include <limits.h>
#endif
#include "UdpMaxDelaySensor.h"
UdpMaxDelaySensor::UdpMaxDelaySensor(UdpState &udpStateVal)
: maxDelay(0),
udpStateInfo(udpStateVal)
{
}
void UdpMaxDelaySensor::localSend(char *packetData, int Len, unsigned long long timeStamp)
{
}
void UdpMaxDelaySensor::localAck(char *packetData, int Len, unsigned long long timeStamp)
{
int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long);
unsigned long long tmpMaxDelay = maxDelay;
if(Len < minSize)
{
cout << "Error: UDP packet data sent to MaxDelaySensor::localAck was less than the "
" required minimum "<< minSize << " bytes\n";
return;
}
//int numRedunAcks = (Len - minSize)/redunAckSize;
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;
vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), seqNum));
oneWayDelay = (timeStamp - (*vecIterator)->timeStamp)/2;
//cout <<" IN maxdelay timestamp = "<<timeStamp<<", sent time = "<<(*vecIterator)->timeStamp<<endl;
oneWayDelay = ( oneWayDelay )*1500 / (Len + 1);
// Set this as the new maximum one way delay.
if(oneWayDelay > tmpMaxDelay)
{
eventFlag = true;
tmpMaxDelay = oneWayDelay;
}
int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long);
int seqNumSize = sizeof(unsigned int);
/*
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;
if(oneWayDelay > 0 && oneWayDelay > maxDelay)
{
eventFlag = true;
maxDelay = oneWayDelay;
}
}
}
}
*/
// Send an event message to the monitor to change the value of maximum one way delay.
maxDelay = tmpMaxDelay - udpStateInfo.minDelay;
if(udpStateInfo.packetLoss != 0 || eventFlag == true)
{
// Report the maximum delay
cout << "New Max Delay = " << maxDelay << "\n";
}
udpStateInfo.maxDelay = maxDelay;
}
#ifndef UDP_MAX_DELAY_SENSOR_PELAB_H
#define UDP_MAX_DELAY_SENSOR_PELAB_H
#include "UdpLibs.h"
#include "UdpState.h"
#include "UdpSensor.h"
class UdpSensor;
class UdpMaxDelaySensor:public UdpSensor{
public:
explicit UdpMaxDelaySensor(UdpState &udpStateVal);
void localSend(char *packetData, int Len, unsigned long long timeStamp);
void localAck(char *packetData, int Len, unsigned long long timeStamp);
private:
unsigned long long maxDelay;
UdpState &udpStateInfo;
};
#endif
#include "UdpMinDelaySensor.h"
UdpMinDelaySensor::UdpMinDelaySensor(UdpState &udpStateVal)
: minDelay(ULONG_LONG_MAX),
udpStateInfo(udpStateVal)
{
}
void UdpMinDelaySensor::localSend(char *packetData, int Len,unsigned long long timeStamp)
{
// Do nothing.
}
void UdpMinDelaySensor::localAck(char *packetData, int Len, unsigned long long timeStamp)
{
int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long);
if(Len < minSize)
{
cout << "Error: UDP packet data sent to MinDelaySensor::localAck was less than the "
" required minimum "<< minSize << " bytes\n";
return;
}
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;
vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), seqNum));
oneWayDelay = (timeStamp - (*vecIterator)->timeStamp)/2;
long minDelayBytes = 0;
// Calculate the delay for the maximum possibly sized packet.
oneWayDelay = ( oneWayDelay ) * 1500 / (Len + 1);
// Set this as the new minimum one way delay.
if(oneWayDelay < minDelay)
{
eventFlag = true;
minDelay = oneWayDelay;
// One byte was chopped off in the base sensor class.
// Add that to the packet length.
minDelayBytes = Len + 1;
}
int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long);
int seqNumSize = sizeof(unsigned int);
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 );
if(oneWayDelay > 0 && oneWayDelay < minDelay)
{
eventFlag = true;
minDelay = oneWayDelay;
minDelayBytes = (*vecIterator)->packetSize;
}
}
}
}
// 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";
}
udpStateInfo.minDelay = minDelay;
udpStateInfo.minDelayBytes = minDelayBytes;
}
#ifndef UDP_MIN_DELAY_SENSOR_PELAB_H
#define UDP_MIN_DELAY_SENSOR_PELAB_H
#include "UdpLibs.h"
#include "UdpState.h"
#include "UdpSensor.h"
class UdpSensor;
class UdpMinDelaySensor:public UdpSensor{
public:
explicit UdpMinDelaySensor(UdpState &udpStateVal);
void localSend(char *packetData, int Len, unsigned long long timeStamp);
void localAck(char *packetData, int Len, unsigned long long timeStamp);
private:
unsigned long long minDelay;
UdpState &udpStateInfo;
};
#endif
#include "UdpPacketInfo.h"
UdpPacketInfo::UdpPacketInfo(unsigned int seqVal, unsigned int packetSizeVal, unsigned long long timeStampVal, bool isFastPacketVal)
:seqNum(seqVal),
packetSize(packetSizeVal),
timeStamp(timeStampVal),
isFastPacket(isFastPacketVal),
lastTimeDiff(0)
{
}
#ifndef UDP_PACKET_INFO_PELAB_H
#define UDP_PACKET_INFO_PELAB_H
class UdpPacketInfo{
public:
UdpPacketInfo::UdpPacketInfo(unsigned int, unsigned int, unsigned long long, bool);
unsigned int seqNum;
unsigned int packetSize;
unsigned long long timeStamp;
bool isFastPacket;
unsigned long long lastTimeDiff;
};
#endif
#include "UdpPacketSensor.h"
UdpPacketSensor::UdpPacketSensor(UdpState &udpStateVal)
:udpStateInfo(udpStateVal)
{
lastPacketTime = 0;
}
void UdpPacketSensor::localSend(char *packetData, int Len, unsigned long long timeStamp)
{
int minSize = 2*sizeof(unsigned int);
if(Len < minSize)
{
cout << "Error: UDP packet data sent to PacketSensor::localSend was less than the "
" required minimum "<< minSize << " bytes\n";
return;
}
unsigned int seqNum = *(unsigned int *)(packetData);
unsigned int packetSize = *(unsigned int *)(packetData + sizeof(unsigned int));
bool isFastPacket = false;
unsigned long long sendTimeDelta = 0;
cout <<" Packet no = "<<seqNum<<" being sent at = "<<timeStamp<<endl;
if(lastPacketTime == 0)
lastPacketTime = timeStamp;
else
{
cout <<"Time since last send and this send = "<< timeStamp - lastPacketTime <<endl;
sendTimeDelta = timeStamp - lastPacketTime;
lastPacketTime = timeStamp;
// cout << "Send time delta = "<<sendTimeDelta<<", min delay = "<<udpStateInfo.minDelay<<endl;
if(sendTimeDelta < udpStateInfo.minDelay)
isFastPacket = 1;
// We did not receive an ACK back, so we dont know the minimum
// one way delay. Treat all packets as fast packets until we
// find out the min. delay - this lowers the throughput a bit
// in case of packet loss if the packets were not being sent
// faster than min delay.
if(udpStateInfo.minDelay == 0)
isFastPacket = 1;
}
if(! sentPacketList.empty())
sentPacketList.back()->lastTimeDiff = sendTimeDelta;
sentPacketList.push_back(new UdpPacketInfo(seqNum, packetSize, timeStamp, isFastPacket));
}
void UdpPacketSensor::localAck(char *packetData, int Len, unsigned long long timeStamp)
{
int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long);
int i;
// Remove the old state information.
for(i = 0;i < udpStateInfo.recentSentPackets.size(); i++)
delete udpStateInfo.recentSentPackets[i];
udpStateInfo.recentSentPackets.clear();
udpStateInfo.packetLoss = 0;
udpStateInfo.fastPacketLoss = 0;
udpStateInfo.lostPacketDelay = 0;
udpStateInfo.lastSentTime = (ULONG_LONG_MAX);
if(Len < minSize)
{
cout << "Error: UDP packet data sent to PacketSensor::localAck was less than the "
" minimum "<< minSize << " bytes\n";
return;
}
int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long);
int numRedunAcks = static_cast<int>(packetData[0]);
unsigned int seqNum = *(unsigned 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;
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";
return;
}
// Store an iterator to the current seqNum being acknowledge, and delete it at the end.
list<UdpPacketInfo * >::iterator curPacketIterator = listIterator;
// Look at the redundant ACKs first.
if(numRedunAcks > 0)
{
unsigned int redunSeqNum;
for(i = 0; i < numRedunAcks; i++)
{
redunSeqNum = *(unsigned int *)(packetData + minSize + i*redunAckSize);
listIterator = sentPacketList.end();
// Check whether the packet that this redundant ACK refers to exists
// in our list of sent ( but unacked ) packets. It might not exist
// if its ACK was not lost earlier.
//listIterator = find_if(sentPacketList.begin(), sentPacketList.end(), bind2nd(equalSeqNum(), redunSeqNum));
listIterator = find_if(sentPacketList.begin(), curPacketIterator, bind2nd(equalSeqNum(), redunSeqNum));
// An unacked packet exists with this sequence number, delete it
// 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) );
if( (*listIterator)->timeStamp < udpStateInfo.lastSentTime)
udpStateInfo.lastSentTime = (*listIterator)->timeStamp;
delete (*listIterator);
sentPacketList.erase(listIterator);
}
}
}
udpStateInfo.recentSentPackets.push_back(new UdpPacketInfo((*curPacketIterator)->seqNum, (*curPacketIterator)->packetSize, (*curPacketIterator)->timeStamp, (*curPacketIterator)->isFastPacket));
// 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
// were lost - treat this as congestion on the forward path.
// Find out how many packets were lost.
listIterator = find_if(sentPacketList.begin(), sentPacketList.end(), bind2nd(lessSeqNum(), seqNum ));
if(listIterator != sentPacketList.end())
{
do{
if( (*listIterator)->timeStamp < udpStateInfo.lastSentTime)
udpStateInfo.lastSentTime = (*listIterator)->timeStamp;
if( (*listIterator)->isFastPacket)
udpStateInfo.fastPacketLoss++;
udpStateInfo.lostPacketDelay += (*listIterator)->lastTimeDiff;
delete (*listIterator);
sentPacketList.erase(listIterator);
listIterator = sentPacketList.end();
udpStateInfo.packetLoss++;
listIterator = find_if(sentPacketList.begin(), curPacketIterator, bind2nd(lessSeqNum(), seqNum ));
}
while( (listIterator != sentPacketList.end()) && (listIterator != curPacketIterator) );
}
if( (*curPacketIterator)->timeStamp < udpStateInfo.lastSentTime)
udpStateInfo.lastSentTime = (*curPacketIterator)->timeStamp;
delete (*curPacketIterator);
sentPacketList.erase(curPacketIterator);
}
#ifndef UDP_PACKET_SENSOR_PELAB_H
#define UDP_PACKET_SENSOR_PELAB_H
#include "UdpLibs.h"
#include "UdpState.h"
#include "UdpSensor.h"
#include "UdpPacketInfo.h"
using namespace std;
class UdpPacketInfo;
//class equalSeqNum;
class UdpSensor;
class UdpPacketSensor:public UdpSensor{
public:
explicit UdpPacketSensor(UdpState &udpStateVal);
void localSend(char *packetData, int Len,unsigned long long timeStamp);
void localAck(char *packetData, int Len,unsigned long long timeStamp);
private:
list<UdpPacketInfo *> sentPacketList;
UdpState & udpStateInfo;
unsigned long long lastPacketTime;
};
#endif
#include "UdpSensor.h"
using namespace std;
UdpSensor::UdpSensor()
{
}
void UdpSensor::capturePacket(char *packetData, int Len, unsigned long long timeStamp)
{
if(Len < 1)
{
cout << "Error: UDP packet data sent to Sensor was less than "
" 1 byte in size\n";
return;
}
if(packetData[0] == '0')
{
localSend( (packetData+1), Len - 1, timeStamp );
}
else if(packetData[0] == '1')
{
localAck( (packetData + 1), Len - 1, timeStamp );
}
}
#ifndef _UDP_SENSOR_PELAB_H
#define _UDP_SENSOR_PELAB_H
#include "UdpLibs.h"
class UdpSensor{
public:
UdpSensor();
virtual void localSend(char *packetData, int Len,unsigned long long timeStamp)=0;
virtual void localAck(char *packetData, int Len,unsigned long long timeStamp)=0;
void capturePacket(char *packetData, int Len,unsigned long long timeStamp);
};
#endif
This diff is collapsed.
#ifndef UDP_STATE_PELAB_H
#define UDP_STATE_PELAB_H
#include "UdpLibs.h"
#include "UdpPacketInfo.h"
using namespace std;
class UdpPacketInfo;
struct UdpState{
// vector of info about packets sent from this host,
// sequence number, timestamp & size of the packet.
vector< UdpPacketInfo * > recentSentPackets;
// Indicates the number of packets lost ( in a batch of 4 sent packets )
// updated whenever an ACK is received.
int packetLoss, fastPacketLoss;
unsigned long long lastSentTime;
unsigned long long minDelay;
unsigned long long maxDelay;
unsigned long long minAckTimeDiff;
unsigned long long queuingDelay;
unsigned long long lostPacketDelay;
long minDelayBytes;
};
class equalSeqNum:public binary_function<const UdpPacketInfo * , unsigned int, bool> {
public:
bool operator()(const UdpPacketInfo *packet, unsigned int seqNum) const
{
return (packet->seqNum == seqNum);
}
};
class lessSeqNum:public binary_function<const UdpPacketInfo *, int, bool> {
public:
bool operator()(const UdpPacketInfo *packet,unsigned int seqNum) const
{
return (packet->seqNum < seqNum);
}
};
#endif
#include "UdpThroughputSensor.h"
UdpThroughputSensor::UdpThroughputSensor(UdpState &udpStateVal, ofstream &outStreamVal)
: lastAckTime(-1),
throughputKbps(0.0),
udpStateInfo(udpStateVal),
outStream(outStreamVal)
{
udpStateInfo.minAckTimeDiff = 999999999;
}
void UdpThroughputSensor::localSend(char *packetData, int Len, unsigned long long timeStamp)
{
// Do nothing.
}
void UdpThroughputSensor::localAck(char *packetData, int Len, unsigned long long timeStamp)
{
int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long);
if(Len < minSize )
{
cout << "Error: UDP packet data sent to ThroughputSensor::localAck was less than the "
" required minimum "<< minSize << " bytes\n";
return;
}
int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long);
int seqNumSize = sizeof(unsigned int);
//int numRedunAcks = (Len - minSize)/redunAckSize;
int numRedunAcks = static_cast<int>(packetData[0]);
int numThroughputAcks = 1;
double avgThroughput = 0;
unsigned long long currentAckTimeStamp = *(unsigned long long *)(packetData + 1 + sizeof(unsigned int));
if(lastAckTime == -1)
{
lastAckTime = currentAckTimeStamp;
return;
}
unsigned int seqNum;
seqNum = *(unsigned int *)(packetData + 1);
unsigned long ackTimeDiff = currentAckTimeStamp - lastAckTime;