(If you have followed the instructions in this page ( click here), the directory NS_DIR will be ~/cs558/NS)
The header definition is as follows:
class TcpAgent : public Agent { friend class XcpEndsys; public: TcpAgent(); virtual ~TcpAgent() {free(tss);} virtual void recv(Packet*, Handler*); virtual void timeout(int tno); virtual void timeout_nonrtx(int tno); int command(int argc, const char*const* argv); virtual void sendmsg(int nbytes, const char *flags = 0); void trace(TracedVar* v); virtual void advanceby(int delta); ... // Numerous variabls... } |
Click on tcp.h and look for the "class TcpAgent" definition to see the full definition.
The TCP agent measures the RTT of each packet.
The RTT estimates are used to set the time out value for packets.
void TcpAgent::opencwnd() { double increment; if (cwnd_ < ssthresh_) { // perform slow start algorithm // There is only one slow start alg. now, // But you can add more... } else { // perform a congestion avoidance algorithm // based on the value of the variable "wnd_option_" } // if maxcwnd_ is set (= nonzero), make sure cwnd_ <= maxcwnd_ if (maxcwnd_ && (int(cwnd_) > maxcwnd_)) cwnd_ = maxcwnd_; } |
You can change the slow start algorithm by inserting code in the "then" part of "if (cwnd_ < ssthresh_)
You can change the congestion avoidance algorithm by inserting code in the "else" part of "if (cwnd_ < ssthresh_)
(cwnd controls the the congestion window size)
(ssthresh controls HOW the congestion window size is increased)
For example:
slowdown( CLOSE_SSTHRESH_HALF | CLOSE_CWND_RESTART ) // performs a slow start |
// **************************************** // Reduce Slow Start Threshold (ssthresh) // **************************************** if ( how & CLOSE_SSTHRESH_HALF ) { ssthresh_ = cwnd_ / 2; } else if ( how & THREE_QUARTER_SSTHRESH ) { ... } // **************************************** // Reduce Congestion Window (cwnd) // **************************************** if ( how & CLOSE_CWND_HALF ) { cwnd_ = cwnd_ / 2; } else if ( how & CLOSE_CWND_RESTART ) { cwnd_ = 1; } else if ... (more variants available, but omitted here) |
set tcp [new Agent/TCP/Reno] $tcp set windowOption_ 99 ;# Select my new TCP algorithm |
(Don't laugh, this was how TCP worked before 1988)
void TcpAgent::opencwnd() { double increment; cwnd_ = 10; // Add these lines in "tcp.cc" return; // These have become "dead code" if (cwnd_ < ssthresh_) { switch (wnd_option_) { ..... |
cd ~/cs558/NS make |
You should see:
cs558 (330)> make g++ -c -Wall -DTCP_DELAY_BIND_ALL ...... -o tcp/tcp.o tcp/tcp.cc g++ -o ns \ common/tclAppInit.o tools/random.o tools/rng.o tools/ranvar.o ...... |
I have attachec an NS script below...
NOTE: you need to run this program with the MODIFIED NS program inside /home/cs558000/cs558/NS/bin/ns
This NS can be used to run the NS script "FixedCWND.tcl":
class TcpAgent : public Agent { ... (existing definitions) /* ------------------------------------------ Cheung: my new variables ------------------------------------------ */ int FixedWindowSize; }; |
void TcpAgent::opencwnd() { double increment; if (cwnd_ < ssthresh_) { switch (wnd_option_) { case 98: cwnd_ = FixedWindowSize; break; (other cases omitted) ..... |
bind( "Y", &X ); |
(You put the statement in the constructor so that the statement will be executed when an object of that class is created !!!)
TcpAgent::TcpAgent() ... { bind( "FixedWindowSize", &FixedWindowSize); } |
To initialize the "bound" variable, we add this set command in the file tcl/lib/ns-default.tcl (a script that is used to initial all bound variables):
Agent/TCP set FixedWindowSize 0 |
static class TcpClass : public TclClass { public: TcpClass() : TclClass("Agent/TCP") {} TclObject* create(int , const char*const*) { return (new TcpAgent()); } }; static TclClass class_tcp; // force constructor to be run once... |