/*
* Copyright (c) 2006 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
* This file is part of the Emulab network testbed software.
*
* This file is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this file. If not, see .
*
* }}}
*/
#include "UdpMinDelaySensor.h"
#include "CommandOutput.h"
using namespace std;
UdpMinDelaySensor::UdpMinDelaySensor(UdpPacketSensor const *udpPacketSensorVal)
: minDelay(ULONG_LONG_MAX),
packetHistory(udpPacketSensorVal)
{
}
UdpMinDelaySensor::~UdpMinDelaySensor()
{
}
unsigned long long UdpMinDelaySensor::getMinDelay() const
{
return minDelay;
}
void UdpMinDelaySensor::localSend(PacketInfo *packet)
{
// Do nothing.
sendValid = true;
ackValid = false;
}
void UdpMinDelaySensor::localAck(PacketInfo *packet)
{
// This is a re-ordered ACK or an incorrect packet - don't do anything
// with it - just return.
// If this packet is ACKing a packet that we lost due to libpcap send loss,
// dont use this packet timestamp for RTT calculations.
if( packetHistory->isAckValid() == false || packetHistory->isAckFake() == true )
{
ackValid = false;
sendValid = false;
return;
}
ackValid = true;
sendValid = false;
unsigned short int seqNum = *(unsigned short int *)(packet->payload + 1);
unsigned long long oneWayDelay;
bool eventFlag = false;
vector::iterator vecIterator;
vector ackedPackets = packetHistory->getAckedPackets();
vecIterator = find_if(ackedPackets.begin(), ackedPackets.end(), bind2nd(equalSeqNum(), seqNum));
unsigned long long timeStamp = packet->packetTime.toMicroseconds();
oneWayDelay = (timeStamp - (*vecIterator).timeStamp)/2;
// Calculate the delay for the maximum sized packet.
oneWayDelay = ( oneWayDelay ) * 1518 / ( (*vecIterator).packetSize);
// Set this as the new minimum one way delay.
if(oneWayDelay < minDelay)
{
eventFlag = true;
minDelay = oneWayDelay;
}
// 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.
// Send an event message to the monitor to change the value of minimum one way delay.
if(eventFlag == true)
{
ostringstream messageBuffer;
messageBuffer << "delay="<<(minDelay)/1000;
global::output->eventMessage(messageBuffer.str(), packet->elab, CommandOutput::FORWARD_PATH);
global::output->eventMessage(messageBuffer.str(), packet->elab, CommandOutput::BACKWARD_PATH);
logWrite(SENSOR,"VALUE::New Min delay = %llu",minDelay);
}
logWrite(SENSOR,"MIND:TIME=%llu,MIND=%llu",timeStamp,minDelay);
}