StateSensor.cc 2.73 KB
Newer Older
Robert Ricci's avatar
Robert Ricci committed
1 2
/*
 * Copyright (c) 2006 University of Utah and the Flux Group.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 
 * {{{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 <http://www.gnu.org/licenses/>.
 * 
 * }}}
Robert Ricci's avatar
Robert Ricci committed
22 23
 */

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
// StateSensor.cc

#include "lib.h"
#include "StateSensor.h"

using namespace std;

StateSensor::StateSensor()
  : state(INITIAL)
{
  logWrite(SENSOR, "State change to INITIAL");
}

StateSensor::~StateSensor()
{
}

41
int StateSensor::getState(void) const
42
{
43 44 45 46 47 48 49 50 51 52 53
  if (sendValid || ackValid)
  {
    return state;
  }
  else
  {
    logWrite(ERROR,
             "StateSensor::getState() called with invalid data");
    return INITIAL;

  }
54 55
}

56 57
bool StateSensor::isSaturated(void) const
{
58 59 60 61 62 63 64 65 66 67
  if (sendValid || ackValid)
  {
    return saturated;
  }
  else
  {
    logWrite(ERROR,
             "StateSensor::isSaturated() called with invalid data");
    return false;
  }
68 69
}

70 71
void StateSensor::localSend(PacketInfo * packet)
{
72 73
  ackValid = false;
  sendValid = true;
74
  if (! packet->tcp->syn && state != ESTABLISHED)
75 76 77 78
  {
    state = ESTABLISHED;
    logWrite(SENSOR, "State change to ESTABLISHED");
  }
79
  calculateSaturated(packet);
80 81 82 83
}

void StateSensor::localAck(PacketInfo * packet)
{
84 85
  sendValid = false;
  ackValid = true;
86
  if (! packet->tcp->syn && state != ESTABLISHED)
87
  {
88
    state = ESTABLISHED;
89
    logWrite(SENSOR, "State change to ESTABLISHED");
90
  }
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
  calculateSaturated(packet);
}

void StateSensor::calculateSaturated(PacketInfo * packet)
{
  unsigned int snd_cwnd = packet->kernel->tcpi_snd_cwnd;
  unsigned int snd_ssthresh = packet->kernel->tcpi_snd_ssthresh;
  unsigned int window = (static_cast<unsigned int>(htons(packet->tcp->window))
    << packet->kernel->tcpi_rcv_wscale);
  unsigned int unacked = packet->kernel->tcpi_unacked * 1448;
  logWrite(SENSOR, "stateEstablished=%d,bufferFull=%d", state == ESTABLISHED,
           packet->bufferFull);
  logWrite(SENSOR, "snd_cwnd=%u,snd_ssthresh=%u,window=%u,unacked=%u",
           snd_cwnd, snd_ssthresh, window, unacked);
  saturated = (state == ESTABLISHED
               && packet->bufferFull
               // and *not* in slow start
               && !(snd_cwnd < snd_ssthresh || window <= unacked));
109
}