sir,
I am trying to write trace code in mkc-source.cc and mkc-source.h
file but I am not understand how to implement this code.Below
mkc-source.cc and mkc-source.h file here:
---------------------------------mkc-source.cc---------------------------------------------------------------------------
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include "packet.h"
#include "mkc-source.h"
#include "flags.h"
#include "random.h"
#include "basetrace.h"
#include "hdr_qs.h"
#include "ip.h"
int hdr_mkc::offset_;
int hdr_mkc_ack::offset_;
/*
* Declare the MKC packet header class
*/
static class MKCHeaderClass : public PacketHeaderClass {
public:
MKCHeaderClass() : PacketHeaderClass("PacketHeader/MKC",
sizeof(hdr_mkc)) {
bind_offset(&hdr_mkc::offset_);
}
} class_MKChdr;
/*
* Declare the MKC acknowledgement header class
*/
static class MKC_ACKHeaderClass : public PacketHeaderClass {
public:
MKC_ACKHeaderClass() : PacketHeaderClass("PacketHeader/MKC_ACK",
sizeof(hdr_mkc_ack)) {
bind_offset(&hdr_mkc_ack::offset_);
}
} class_MKC_ackhdr;
/*
* Declare the class of MKC sender agent
*/
static class MKCClass : public TclClass {
public:
MKCClass() : TclClass("Agent/MKC") {}
TclObject* create(int, const char*const*) {
return (new MKCAgent());
}
} class_MKC;
/*
* Constructor of an MKC sender agent
*/
MKCAgent::MKCAgent() : Agent(PT_MKC), send_timer_(this)
{
bind("packetSize_", &size_);
bind("rate_", &rate_);
bind("init_rate_", &init_rate_);
bind("alpha_", &alpha_);
bind("beta_", &beta_);
bind("pkt_loss_", &pkt_loss_);
bind("fid_", &fid_);
}
/*
* Initialization of an MKC sender
*/
void MKCAgent::start()
{
rate_ = init_rate_; // set the initial rate
delta_ = -1; // set delta interval to -1
loss_seqno_ = -1; // set packet loss sequence number to -1
max_loss_seqno_ = -1; // set maximum packet loss sequence number to -1
pkt_loss_ = 2; // set packet loss to an invalid value 2
current_ack_seqno_ = 0;// packet sequence number starts from 0
size_ = size_ * 8; // in bits
last_ack_seqno_ = 0; // sequence number of the last non-duplicate
feedback
cur_pkt_seqno_ = 0; // packet sequence number starts from 0
cur_rid = -1; // bottleneck router is undecided
ref_rate = -1; // reference rate
is_rtt_expired_ = 0; // whether an RTT elapsed after the last rate
change
switch_in_progress = 0;// no bottleneck switching is in progress
seqno_last_rtt = 0; // sequence number of the first packet of the
last bottleneck switching
active_ = 1; // sender is active
printf("Flow %d starts at time %f\n", fid_,
Scheduler::instance().clock());
send_timer_.resched(size_ / rate_); // send out the first packet
}
/*
* Termination of an MKC sender
*/
void MKCAgent::stop()
{
active_ = 0;
send_timer_.force_cancel();
}
/*
* Definition of the tcl commands
*/
int MKCAgent::command(int argc, const char*const* argv)
{
if (argc==2) {
if (strcmp(argv[1],"start")==0) {
start();
return TCL_OK;
}
if (strcmp(argv[1],"stop")==0) {
stop();
return TCL_OK;
}
}
return (Agent::command(argc, argv));
}
/*
* Receive a feedback from the network
*/
void MKCAgent::recv(Packet *pkt, Handler *)
{
double now = Scheduler::instance().clock();
hdr_mkc_ack *nck = hdr_mkc_ack::access(pkt);
// manage bottleneck switching
if (nck->rid != cur_rid && nck->flost != 2 && switch_in_progress == 0)
{
// authorize a bottleneck switch if and only if the difference
between the
// old packet loss and the one carried in the ack is greater
than 0.001
double diff = fabs(nck->flost - pkt_loss_);
if (diff > 0.01)
{
cur_rid = nck->rid; // change the membership
// In the progress of switching, delay response to
feedbacks by one RTT
// + one Delta interval. This is accomplished by
variable
switch_in_progress:
// 0 -- no switching in progress, 1 -- start switching,
// 2 -- one RTT elpased, 3 -- one Delta interval elapsed
switch_in_progress = 1;
seqno_last_rtt = cur_pkt_seqno_;
max_loss_seqno_ = nck->loss_seqno;
is_rtt_expired_ = 0;
printf("At time %f, bottleneck of flow %d switched to
%d\n", now,
fid_, cur_rid);
}
}
loss_seqno_=nck->loss_seqno;
// determine whether one RTT has elapsed since the last *potential
bottleneck switch was detected*
if (switch_in_progress == 1 && nck->pkt_seqno >= seqno_last_rtt)
{
max_loss_seqno_ = loss_seqno_;
last_ack_seqno_ = nck->pkt_seqno;
is_rtt_expired_ = 1;
switch_in_progress = 2;
}
// check whether the ACK is valid
if (nck->flost != 2)
{
// determine whether one RTT has elapsed since the last *rate
change*
if (nck->pkt_seqno >= seqno_last_rtt && is_rtt_expired_ == 0)
is_rtt_expired_ = 1;
// don't forget to update the max loss sequence number while
the RTT
is not expired
if (loss_seqno_>max_loss_seqno_ && is_rtt_expired_ == 0)
{
max_loss_seqno_ = loss_seqno_;
last_ack_seqno_ = nck->pkt_seqno;
}
// delay by one RTT and respond to the first non-duplicate ACK
if(loss_seqno_ > max_loss_seqno_ && is_rtt_expired_ == 1)
{
max_loss_seqno_ = loss_seqno_; // update the max
packet loss seqno
current_ack_seqno_ = nck->pkt_seqno;
if (switch_in_progress != 0)
switch_in_progress ++;
// adjust rate only when no bottleneck switching is in
progress
if (switch_in_progress == 0)
{
pkt_loss_ = nck->flost;
delta_ = nck->delta;
ref_rate = get_ref_rate();
rate_ = (double)(1 - beta_ * pkt_loss_) *
ref_rate + alpha_;
seqno_last_rtt = cur_pkt_seqno_;
is_rtt_expired_ = 0; // reset the timer
}
last_ack_seqno_ = nck->pkt_seqno;
if (switch_in_progress == 3)
switch_in_progress = 0;
nextpkt(); // schedule the next packet to be sent
}
}
Packet::free(pkt); // release memory
}
/*
* Calculate the reference rate based on the rate sequence numbers.
* We assume that there is no packet reordering.
*/
double MKCAgent::get_ref_rate()
{
double volume = 0; // amount of data sent in the last Delta interval
if (current_ack_seqno_ >= last_ack_seqno_)
{
volume = (current_ack_seqno_ - last_ack_seqno_) * size_;
last_ack_seqno_ = current_ack_seqno_;
}
else
{
printf("Error when computing reference rate!\n");
exit(0);
}
// start calculating reference rate
if (delta_ != 0)
return(volume/delta_);
else
{
printf("Error: delta = 0, fail to compute reference rate!\n");
exit(0);
}
}
/*
* Schedule the time when the next packet will be sent
*/
void MKCSendTimer::expire(Event *) {
a_->nextpkt();
}
/*
* Schedule the time when the next packet is sent
*/
void MKCAgent::nextpkt()
{
double next; // the next timeout
// send a packet immediately
sendpkt();
if(rate_ == 0){
printf("Error: rate cannot be zero!\n");
exit(0);
}
next = size_ / rate_; // inter-packet interval
send_timer_.resched(next);// set the timeout for the next packet
}
/*
* Send out a packet
*/
void MKCAgent::sendpkt()
{
if (active_) {
Packet* p = allocpkt();
hdr_mkc *MKCh = hdr_mkc::access(p);
double now = Scheduler::instance().clock();
MKCh->loss_seqno=max_loss_seqno_; // the
loss_seqno is updated by
the receiver
MKCh->is_changed=0; //
indicate that "flost" is not modified
by any router
MKCh->flost=2;
// packet loss is initially zero
MKCh->psize = size_; // packet size in bits
MKCh->pkt_seqno = cur_pkt_seqno_; // packet sequence
number
cur_pkt_seqno_++; // increment packet
sequence
number by 1
send(p, 0);
}
}
-------------------------------------------mkc-source.h------------------------------------
#ifndef MKC_CLASS
#define MKC_CLASS 1
#include "agent.h"
#include "packet.h"
#include <math.h>
#define SIZE 1000000
/*
* Define MKC packet header format
*/
struct hdr_mkc {
int loss_seqno; // packetloss sequence number,
marked by the router
int pkt_seqno; // packet sequence number
int is_changed; // binary variable, 1 -- field
"flost" is modified;
0 -- otherwise
int psize; // packet size
int rid; // router ID
double flost; // packet loss of the most congested
link
double delta; // sampling interval at the bottleneck
router
static int offset_; // offset for this header
inline static int& offset() {
return offset_;
}
inline static hdr_mkc* access(const Packet* p) {
return (hdr_mkc*) p->access(offset_);
}
};
/*
* Define the MKC ACK header format
*/
struct hdr_mkc_ack {
int loss_seqno; // packetloss sequence number
int pkt_seqno; // packet sequence number
int rid; // router ID
double flost; // packet loss of the most congested
router in the path
double delta; // sampling interval at the bottleneck
router
static int offset_; // offset for this header
inline static int& offset()
{
return offset_;
}
inline static hdr_mkc_ack* access(const Packet* p) {
return (hdr_mkc_ack*) p->access(offset_);
}
};
class MKCAgent;
/*
* Define the timer used to schedule packets to be sent
*/
class MKCSendTimer : public TimerHandler {
public:
MKCSendTimer(MKCAgent *a) : TimerHandler() { a_ = a; }
virtual void expire(Event *e);
protected:
MKCAgent *a_;
};
/*
* Define the sender agent of MKC
*/
class MKCAgent : public Agent
{
friend class MKCSendTimer;
public:
MKCAgent();
int command(int argc, const char*const* argv);
void recv(Packet*, Handler*); // called upon each packet arrival
void sendpkt(); // send out a packet
void nextpkt(); // scheduler the time when the next
packet is sent
void start(); // initializaiton
void stop(); // terminate the sender
double get_ref_rate(); // calculate the reference rate
protected:
MKCSendTimer send_timer_; // timer of sending packets
int active_; // is the sender still active?
int size_; // packet size
int cur_rid; // ID of the current
bottleneck router
int max_loss_seqno_; // max seq perceived by the
sender so far
int loss_seqno_; // packet loss seq of the
current ack
int cur_pkt_seqno_; // current packet sequence
number
int last_ack_seqno_; // packet sequence
number of the last ACK
int current_ack_seqno_; // packet sequence
number of the current ACK
int seqno_last_rtt; // sequence number of
the out-going packet
at the end of the last RTT
int is_rtt_expired_; // whether or not one rtt has
elapsed
int switch_in_progress; // if a bottleneck
switching is in
progress, delay the response to it
int wait_one_more_interval; // delay response to ACK by one RTT
+ one delta interval
double rate_; // current sending rate
double ref_rate; // reference rate of the MKC control
equation
double pkt_loss_; // packet loss of the bottleneck link
double delta_; // sampling interval at the
bottleneck router
double init_rate_; // initial sending rate
double alpha_; // increment constant
double beta_; // gain parameter
};
#endif
please help me to solve above problem its urgent
thank you......