Snoop Class Reference

#include <snoop.h>

Inheritance diagram for Snoop:

NsObject TclObject Handler Collaboration diagram for Snoop:

Collaboration graph
[legend]

Detailed Description

Definition at line 113 of file snoop.h.

Public Member Functions

virtual void debug (const char *fmt,...)
virtual int delay_bind_dispatch (const char *varName, const char *localName, TclObject *tracer)
virtual void delay_bind_init_all ()
void handle (Event *)
int isdebug () const
int next (int i)
int prev (int i)
virtual void recv (Packet *p, const char *s)
void recv (Packet *, Handler *)
virtual void recvOnly (Packet *)
 Snoop ()
int snoop_rxmit (Packet *)
int wl_next (int i)
int wl_prev (int i)

Protected Member Functions

int command (int argc, const char *const *argv)
int empty_ ()
void reset ()
void savepkt_ (Packet *, int, int)
int snoop_ack (Packet *)
double snoop_cleanbufs_ (int)
void snoop_cleanup ()
void snoop_data (Packet *)
int snoop_insert (Packet *)
int snoop_qlong ()
void snoop_rtt (double)
void snoop_wired_ack (Packet *)
void snoop_wless_data (Packet *)
int snoop_wlessloss (int)
double timeout ()
void update_state_ ()
void wlreset ()

Protected Attributes

short bufhead_
short buftail_
Handlercallback_
int debug_
short expDupacks_
int expNextAck_
u_short fstate_
double g_
int integrate_
int lastAck_
int lastSeen_
int lru_
int maxbufs_
LLSnoopparent_
SnoopPersistHandlerpersistHandler_
Packetpkts_ [SNOOP_MAXWIND]
NsObjectrecvtarget_
double rttvar_
SnoopRxmitHandlerrxmitHandler_
int rxmitStatus_
int snoopDisable_
double snoopTick_
double srtt_
double tailTime_
EventtoutPending_
int wl_bufhead_
int wl_buftail_
int wl_lastAck_
int wl_lastSeen_
int wl_state_
hdr_seqwlseqs_ [SNOOP_WLSEQS]

Friends

class SnoopPersistHandler
class SnoopRxmitHandler


Constructor & Destructor Documentation

Snoop::Snoop  ) 
 

Definition at line 68 of file snoop.cc.

References g_, lru_, maxbufs_, hdr_seq::num, pkts_, rttvar_, rxmitHandler_, rxmitStatus_, hdr_seq::seq, SNOOP_MAXWIND, SNOOP_WLSEQS, snoopDisable_, SnoopRxmitHandler, snoopTick_, srtt_, tailTime_, and wlseqs_.

00068              : NsObject(),
00069     fstate_(0), lastSeen_(-1), lastAck_(-1), 
00070     expNextAck_(0), expDupacks_(0), bufhead_(0), 
00071     toutPending_(0), buftail_(0),
00072     wl_state_(SNOOP_WLEMPTY), wl_lastSeen_(-1), wl_lastAck_(-1), 
00073     wl_bufhead_(0), wl_buftail_(0)
00074 {
00075     bind("snoopDisable_", &snoopDisable_);
00076     bind_time("srtt_", &srtt_);
00077     bind_time("rttvar_", &rttvar_);
00078     bind("maxbufs_", &maxbufs_);
00079     bind("snoopTick_", &snoopTick_);
00080     bind("g_", &g_);
00081     bind("tailTime_", &tailTime_);
00082     bind("rxmitStatus_", &rxmitStatus_);
00083     bind("lru_", &lru_);
00084 
00085     rxmitHandler_ = new SnoopRxmitHandler(this);
00086 
00087     int i;
00088     for (i = 0; i < SNOOP_MAXWIND; i++) /* data from wired->wireless */
00089         pkts_[i] = 0;
00090     for (i = 0; i < SNOOP_WLSEQS; i++) {/* data from wireless->wired */
00091         wlseqs_[i] = (hdr_seq *) malloc(sizeof(hdr_seq));
00092         wlseqs_[i]->seq = wlseqs_[i]->num = 0;
00093     }
00094     if (maxbufs_ == 0)
00095         maxbufs_ = SNOOP_MAXWIND;
00096 }


Member Function Documentation

int Snoop::command int  argc,
const char *const *  argv
[protected, virtual]
 

Reimplemented from NsObject.

Definition at line 133 of file snoop.cc.

References hdr_snoop::access(), buftail_, NsObject::command(), empty_(), parent_, pkts_, recvtarget_, rxmitStatus_, sh, SNOOP_PROPAGATE, snoop_rxmit(), and LL::uptarget().

00134 {
00135     //Tcl& tcl = Tcl::instance();
00136 
00137     if (argc == 3) {
00138         if (strcmp(argv[1], "llsnoop") == 0) {
00139             parent_ = (LLSnoop *) TclObject::lookup(argv[2]);
00140             if (parent_)
00141                 recvtarget_ = parent_->uptarget();
00142             return (TCL_OK);
00143         }
00144         
00145         if (strcmp(argv[1], "check-rxmit") == 0) {
00146             if (empty_()) {
00147                 rxmitStatus_ = SNOOP_PROPAGATE;
00148                 return (TCL_OK);
00149             }
00150 
00151             Packet *p = pkts_[buftail_];
00152             hdr_snoop *sh = hdr_snoop::access(p);
00153 
00154             if (sh->sndTime()!=-1 && sh->sndTime()<atoi(argv[2]) &&
00155                 sh->numRxmit() == 0)
00156                 /* candidate for retransmission */
00157                 rxmitStatus_ = snoop_rxmit(p);
00158             else
00159                 rxmitStatus_ = SNOOP_PROPAGATE;
00160             return (TCL_OK);
00161         }
00162     }
00163     return NsObject::command(argc, argv);
00164 }

Here is the call graph for this function:

void NsObject::debug const char *  fmt,
  ...
[virtual, inherited]
 

Definition at line 102 of file object.cc.

References NsObject::debug_.

00103 {
00104     if (!debug_)
00105         return;
00106     va_list ap;
00107     va_start(ap, fmt);
00108     vprintf(fmt, ap);
00109 }

int NsObject::delay_bind_dispatch const char *  varName,
const char *  localName,
TclObject tracer
[virtual, inherited]
 

Reimplemented in BayFullTcpAgent, Agent, MPLSAddressClassifier, LDPAgent, HbAfterRtoSctpAgent, MfrHbAfterRtoSctpAgent, MfrTimestampSctpAgent, MultipleFastRtxSctpAgent, NewRenoSctpAgent, TimestampSctpAgent, SctpAgent, FullTcpAgent, SackFullTcpAgent, RFC793eduTcpAgent, TcpSink, TcpAgent, VegasTcpAgent, XcpAgent, and XcpSink.

Definition at line 63 of file object.cc.

References NsObject::debug_.

Referenced by MPLSAddressClassifier::delay_bind_dispatch(), and Agent::delay_bind_dispatch().

00064 {
00065     if (delay_bind_bool(varName, localName, "debug_", &debug_, tracer)) 
00066         return TCL_OK;
00067     return TclObject::delay_bind_dispatch(varName, localName, tracer);
00068 }

void NsObject::delay_bind_init_all  )  [virtual, inherited]
 

Reimplemented in BayFullTcpAgent, Agent, MPLSAddressClassifier, LDPAgent, HbAfterRtoSctpAgent, MfrHbAfterRtoSctpAgent, MfrTimestampSctpAgent, MultipleFastRtxSctpAgent, NewRenoSctpAgent, TimestampSctpAgent, SctpAgent, FullTcpAgent, SackFullTcpAgent, RFC793eduTcpAgent, TcpSink, TcpAgent, VegasTcpAgent, XcpAgent, and XcpSink.

Definition at line 57 of file object.cc.

Referenced by MPLSAddressClassifier::delay_bind_init_all(), and Agent::delay_bind_init_all().

00058 {
00059     delay_bind_init_one("debug_");
00060 }

int Snoop::empty_  )  [inline, protected]
 

Definition at line 139 of file snoop.h.

References bufhead_, buftail_, fstate_, and SNOOP_FULL.

Referenced by command(), snoop_cleanbufs_(), and snoop_data().

00140         {return (bufhead_==buftail_ &&!(fstate_&SNOOP_FULL));}

void Snoop::handle Event  )  [virtual]
 

Reimplemented from NsObject.

Definition at line 227 of file snoop.cc.

References hdr_cmn::access(), LinkDelay::delay(), Connector::drop(), Packet::free(), Scheduler::instance(), parent_, PT_ACK, PT_TCP, hdr_cmn::ptype(), recvtarget_, Scheduler::schedule(), snoop_ack(), SNOOP_PROPAGATE, and snoop_wless_data().

Referenced by recv().

00228 {
00229 
00230     Packet *p = (Packet *) e;
00231     packet_t type = hdr_cmn::access(p)->ptype();
00232     //int seq = hdr_tcp::access(p)->seqno();
00233     int prop = SNOOP_PROPAGATE; // by default;  propagate ack or packet
00234     Scheduler& s = Scheduler::instance();
00235 
00236     //hdr_ll *llh = hdr_ll::access(p);
00237     if (hdr_cmn::access(p)->error()) {
00238         parent_->drop(p);   // drop packet if it's been corrupted
00239         return;
00240     }
00241 
00242     if (type == PT_ACK) 
00243         prop = snoop_ack(p); 
00244 
00245     else if (type == PT_TCP) /* XXX what about TELNET? */
00246         snoop_wless_data(p);
00247 
00248     if (prop == SNOOP_PROPAGATE)
00249         s.schedule(recvtarget_, e, parent_->delay());
00250     else {          // suppress ack
00251         /*      printf("---- %f suppressing ack %d\n", s.clock(), seq);*/
00252         Packet::free(p);
00253     }
00254 }

Here is the call graph for this function:

int NsObject::isdebug  )  const [inline, inherited]
 

Definition at line 61 of file object.h.

References NsObject::debug_.

00061 { return debug_; }

int Snoop::next int  i  )  [inline]
 

Definition at line 121 of file snoop.h.

References maxbufs_.

Referenced by SnoopRxmitHandler::handle(), snoop_ack(), snoop_cleanbufs_(), and snoop_insert().

00121 { return (i+1) % maxbufs_; }

int Snoop::prev int  i  )  [inline]
 

Definition at line 122 of file snoop.h.

References maxbufs_.

Referenced by snoop_insert().

00122 { return ((i == 0) ? maxbufs_-1 : i-1); };

void NsObject::recv Packet p,
const char *  s
[virtual, inherited]
 

Reimplemented in CMUTrace.

Definition at line 96 of file object.cc.

References Packet::free().

00097 {
00098     Packet::free(p);
00099 }

Here is the call graph for this function:

void Snoop::recv Packet ,
Handler
[virtual]
 

Implements NsObject.

Definition at line 200 of file snoop.cc.

References hdr_cmn::direction(), handle(), HDR_CMN, and hdr_cmn::UP.

Referenced by LLSnoop::recv().

00201 {   
00202     
00203     hdr_cmn *ch = HDR_CMN(p);   
00204     if(ch->direction() == hdr_cmn::UP) {
00205         handle((Event *) p);
00206         return;
00207     }
00208     
00209     packet_t type = hdr_cmn::access(p)->ptype();
00210     /* Put packet (if not ack) in cache after checking, and send it on */
00211     
00212     if (type == PT_TCP) 
00213         snoop_data(p);
00214     
00215     else if (type == PT_ACK)
00216         snoop_wired_ack(p);
00217     
00218     ch->direction() = hdr_cmn::DOWN;  // Ben added
00219     parent_->sendDown(p);   /* vector to LLSnoop's sendto() */
00220 }

Here is the call graph for this function:

virtual void NsObject::recvOnly Packet  )  [inline, virtual, inherited]
 

Reimplemented in Agent, and Trace.

Definition at line 56 of file object.h.

Referenced by Trace::recvOnly().

00056 {};

void Snoop::reset  )  [protected, virtual]
 

Reimplemented from NsObject.

Definition at line 99 of file snoop.cc.

References bufhead_, buftail_, Scheduler::cancel(), expDupacks_, expNextAck_, Packet::free(), fstate_, Scheduler::instance(), lastAck_, lastSeen_, pkts_, SNOOP_MAXWIND, and toutPending_.

Referenced by snoop_data().

00100 {
00101 //  printf("%x resetting\n", this);
00102     fstate_ = 0;
00103     lastSeen_ = -1;
00104     lastAck_ = -1;
00105     expNextAck_ = 0;
00106     expDupacks_ = 0;
00107     bufhead_ = buftail_ = 0;
00108     if (toutPending_) {
00109         Scheduler::instance().cancel(toutPending_);
00110         // xxx: I think that toutPending_ doesn't need to be freed because snoop didn't allocate it (but I'm not sure).
00111         toutPending_ = 0;
00112     };
00113     for (int i = 0; i < SNOOP_MAXWIND; i++) {
00114         if (pkts_[i]) {
00115             Packet::free(pkts_[i]);
00116             pkts_[i] = 0;
00117         }
00118     }
00119 }

Here is the call graph for this function:

void Snoop::savepkt_ Packet ,
int  ,
int 
[protected]
 

Definition at line 391 of file snoop.cc.

References hdr_snoop::access(), Scheduler::clock(), Packet::copy(), Scheduler::instance(), pkts_, and sh.

00392 {
00393     pkts_[i] = p->copy();
00394     Packet *pkt = pkts_[i];
00395     hdr_snoop *sh = hdr_snoop::access(pkt);
00396     sh->seqno() = seq;
00397     sh->numRxmit() = 0;
00398     sh->senderRxmit() = 0;
00399     sh->sndTime() = Scheduler::instance().clock();
00400 }

Here is the call graph for this function:

int Snoop::snoop_ack Packet  )  [protected]
 

Definition at line 407 of file snoop.cc.

References hdr_snoop::access(), hdr_tcp::access(), bufhead_, buftail_, expDupacks_, expNextAck_, fstate_, lastAck_, next(), pkts_, RTX_THRESH, hdr_tcp::seqno(), sh, SNOOP_CLOSED, SNOOP_MAXWIND, SNOOP_PROPAGATE, snoop_rxmit(), and SNOOP_SUPPRESS.

Referenced by handle().

00408 {
00409     Packet *pkt;
00410 
00411     int ack = hdr_tcp::access(p)->seqno();
00412 
00413     /*
00414      * There are 3 cases:
00415      * 1. lastAck_ > ack.  In this case what has happened is
00416      *    that the acks have come out of order, so we don't
00417      *    do any local processing but forward it on.
00418      * 2. lastAck_ == ack.  This is a duplicate ack. If we have
00419      *    the packet we resend it, and drop the dupack.
00420      *    Otherwise we never got it from the fixed host, so we
00421      *    need to let the dupack get through.
00422      *    Set expDupacks_ to number of packets already sent
00423      *    This is the number of dup acks to ignore.
00424      * 3. lastAck_ < ack.  Set lastAck_ = ack, and update
00425      *    the head of the buffer queue. Also clean up ack'd packets.
00426      */
00427     if (fstate_ & SNOOP_CLOSED || lastAck_ > ack) 
00428         return SNOOP_PROPAGATE; // send ack onward
00429 
00430     if (lastAck_ == ack) {  
00431         /* A duplicate ack; pure window updates don't occur in ns. */
00432 
00433         pkt = pkts_[buftail_];
00434         
00435         if (pkt == 0) 
00436             return SNOOP_PROPAGATE;
00437         
00438         hdr_snoop *sh = hdr_snoop::access(pkt);
00439 
00440         if (pkt == 0 || sh->seqno() > ack + 1) 
00441             /* don't have packet, letting thru' */
00442                 return SNOOP_PROPAGATE;
00443 
00444         /* 
00445          * We have the packet: one of 3 possibilities:
00446          * 1. We are not expecting any dupacks (expDupacks_ == 0)
00447          * 2. We are expecting dupacks (expDupacks_ > 0)
00448          * 3. We are in an inconsistent state (expDupacks_ == -1)
00449          */
00450 
00451             
00452         if (expDupacks_ == 0) { // not expecting it
00453 #define RTX_THRESH 1
00454             
00455             static int thresh = 0;
00456             if (thresh++ < RTX_THRESH) 
00457                 /* no action if under RTX_THRESH */
00458                 return SNOOP_PROPAGATE;
00459             
00460             thresh = 0;
00461             
00462             // if the packet is a sender retransmission, pass on
00463             if (sh->senderRxmit()) 
00464                 return SNOOP_PROPAGATE;
00465             
00466             /*
00467              * Otherwise, not triggered by sender.  If this is
00468              * the first dupack recd., we must determine how many
00469              * dupacks will arrive that must be ignored, and also
00470              * rexmit the desired packet.  Note that expDupacks_
00471              * will be -1 if we miscount for some reason.
00472              */
00473             
00474             
00475             expDupacks_ = bufhead_ - expNextAck_;
00476             if (expDupacks_ < 0)
00477                 expDupacks_ += SNOOP_MAXWIND;
00478             expDupacks_ -= RTX_THRESH + 1;
00479             expNextAck_ = next(buftail_);
00480 
00481             if (sh->numRxmit() == 0) 
00482                 return snoop_rxmit(pkt);
00483         } else if (expDupacks_ > 0) {
00484             expDupacks_--;
00485             return SNOOP_SUPPRESS;
00486         } else if (expDupacks_ == -1) {
00487             if (sh->numRxmit() < 2) {
00488                 return snoop_rxmit(pkt);
00489             }
00490         } else      // let sender deal with it
00491             return SNOOP_PROPAGATE;
00492     } else {        // a new ack
00493 
00494         fstate_ &= ~SNOOP_NOACK; // have seen at least 1 new ack
00495 
00496         /* free buffers */
00497         double sndTime = snoop_cleanbufs_(ack);
00498         
00499         if (sndTime != -1)
00500             snoop_rtt(sndTime);
00501 
00502         expDupacks_ = 0;
00503         expNextAck_ = buftail_;
00504         lastAck_ = ack;
00505     }
00506     return SNOOP_PROPAGATE;
00507 }

Here is the call graph for this function:

double Snoop::snoop_cleanbufs_ int   )  [protected]
 

Definition at line 611 of file snoop.cc.

References hdr_tcp::access(), hdr_snoop::access(), bufhead_, buftail_, Scheduler::cancel(), empty_(), Packet::free(), fstate_, Scheduler::instance(), next(), pkts_, rxmitHandler_, Scheduler::schedule(), hdr_tcp::seqno(), sh, SNOOP_FULL, tailTime_, timeout(), and toutPending_.

00612 {
00613     Scheduler &s = Scheduler::instance();
00614     double sndTime = -1;
00615 
00616     if (toutPending_) {
00617         s.cancel(toutPending_);
00618         // xxx: I think that toutPending_ doesn't need to be freed because snoop didn't allocate it (but I'm not sure).
00619         toutPending_ = 0;
00620     };
00621 
00622     if (empty_())
00623         return sndTime;
00624 
00625     int i = buftail_;
00626     do {
00627         hdr_snoop *sh = hdr_snoop::access(pkts_[i]);
00628         int seq = hdr_tcp::access(pkts_[i])->seqno();
00629 
00630         if (seq <= ack) {
00631             sndTime = sh->sndTime();
00632             Packet::free(pkts_[i]);
00633             pkts_[i] = 0;
00634             fstate_ &= ~SNOOP_FULL; /* XXX redundant? */
00635         } else if (seq > ack)
00636             break;
00637         i = next(i);
00638     } while (i != bufhead_);
00639 
00640     if ((i != buftail_) || (bufhead_ != buftail_)) {
00641         fstate_ &= ~SNOOP_FULL;
00642         buftail_ = i;
00643     }
00644     if (!empty_()) {
00645         toutPending_ = (Event *) (pkts_[buftail_]);
00646         s.schedule(rxmitHandler_, toutPending_, timeout());
00647         hdr_snoop *sh = hdr_snoop::access(pkts_[buftail_]);
00648         tailTime_ = sh->sndTime();
00649     }
00650 
00651     return sndTime;
00652 }

Here is the call graph for this function:

void Snoop::snoop_cleanup  )  [protected]
 

Definition at line 751 of file snoop.cc.

00752 {
00753 }

void Snoop::snoop_data Packet  )  [protected]
 

Definition at line 261 of file snoop.cc.

References hdr_tcp::access(), buftail_, Scheduler::cancel(), empty_(), fstate_, LL::ifq(), Scheduler::instance(), lastSeen_, Queue< T >::length(), Queue< T >::limit(), lru_, parent_, pkts_, reset(), rxmitHandler_, Scheduler::schedule(), hdr_tcp::seqno(), SNOOP_ALIVE, SNOOP_FULL, snoop_insert(), SNOOP_TAIL, timeout(), and toutPending_.

00262 {
00263     Scheduler &s = Scheduler::instance();
00264     int seq = hdr_tcp::access(p)->seqno();
00265     int resetPending = 0;
00266     
00267     //  printf("%x snoop_data: %f sending packet %d\n", this, s.clock(), seq);
00268     if (fstate_ & SNOOP_ALIVE && seq == 0)
00269         reset();
00270     fstate_ |= SNOOP_ALIVE;
00271     if ((fstate_ & SNOOP_FULL) && !lru_) {
00272 //      printf("snoop full, fwd'ing\n t %d h %d", buftail_, bufhead_);
00273         if (seq > lastSeen_)
00274             lastSeen_ = seq;
00275         return;
00276     }
00277     /* 
00278      * Only if the ifq is NOT full do we insert, since otherwise we want
00279      * congestion control to kick in.
00280      */
00281 
00282     if (parent_->ifq()->length() < parent_->ifq()->limit()-1)
00283         resetPending = snoop_insert(p);
00284     if (toutPending_ && resetPending == SNOOP_TAIL) {
00285         s.cancel(toutPending_);
00286         // xxx: I think that toutPending_ doesn't need to be freed because snoop didn't allocate it (but I'm not sure).
00287         toutPending_ = 0;
00288     }
00289     if (!toutPending_ && !empty_()) {
00290         toutPending_ = (Event *) (pkts_[buftail_]);
00291         s.schedule(rxmitHandler_, toutPending_, timeout());
00292     }
00293     return;
00294 }

Here is the call graph for this function:

int Snoop::snoop_insert Packet  )  [protected]
 

Definition at line 306 of file snoop.cc.

References hdr_snoop::access(), hdr_tcp::access(), bufhead_, buftail_, Scheduler::clock(), Packet::free(), fstate_, Scheduler::instance(), lastAck_, lastSeen_, next(), pkts_, prev(), hdr_tcp::seqno(), sh, SNOOP_FULL, and SNOOP_TAIL.

Referenced by snoop_data().

00307 {
00308 
00309 
00310 
00311     int i, seq = hdr_tcp::access(p)->seqno(), retval=0;
00312 
00313     if (seq <= lastAck_) 
00314         return retval;
00315     
00316     if (fstate_ & SNOOP_FULL) {
00317         /* free tail and go on */
00318         printf("snoop full, making room\n");
00319         Packet::free(pkts_[buftail_]);
00320         pkts_[buftail_] = 0;
00321         buftail_ = next(buftail_);
00322         fstate_ |= ~SNOOP_FULL;
00323     }
00324 
00325     if (seq > lastSeen_ || pkts_[buftail_] == 0) { // in-seq or empty cache
00326         i = bufhead_;
00327         bufhead_ = next(bufhead_);
00328     } else if (seq < hdr_snoop::access(pkts_[buftail_])->seqno()) {
00329         buftail_ = prev(buftail_);
00330         i = buftail_;
00331     } else {
00332         for (i = buftail_; i != bufhead_; i = next(i)) {
00333             hdr_snoop *sh = hdr_snoop::access(pkts_[i]);
00334             if (sh->seqno() == seq) {  // cached before
00335 
00336                 sh->numRxmit() = 0;
00337                 sh->senderRxmit() = 1; //must be a sender retr
00338                 sh->sndTime() = Scheduler::instance().clock();
00339                 return SNOOP_TAIL;
00340             } else if (sh->seqno() > seq) { 
00341 
00342                 //not cached before, should insert in the middle
00343                 // find the position it should be: prev(i)
00344  
00345                 Packet *temp = pkts_[prev(buftail_)];
00346                 for (int j = buftail_; j != i; j = next(j)) 
00347                     pkts_[prev(j)] = pkts_[j];
00348                 i = prev(i);
00349                 pkts_[i] = temp;   // seems not necessary. Ben comments
00350                 buftail_ = prev(buftail_);
00351                 break;
00352             }
00353         }
00354 
00355         // This should not happen, since seq must be > lastSeen, which is 
00356         // handled before in the first if.   Ben comments
00357         if (i == bufhead_)
00358             bufhead_ = next(bufhead_);
00359     }
00360     
00361     // save in the buffer
00362     savepkt_(p, seq, i);
00363     
00364     if (bufhead_ == buftail_)
00365         fstate_ |= SNOOP_FULL;
00366     /* 
00367      * If we have one of the following packets:
00368      * 1. a network-out-of-order packet, or
00369      * 2. a fast rxmit packet, or 3. a sender retransmission 
00370      * AND it hasn't already been buffered, 
00371      * then seq will be < lastSeen_. 
00372      * We mark this packet as having been due to a sender rexmit 
00373      * and use this information in snoop_ack(). We let the dupacks
00374      * for this packet go through according to expDupacks_.
00375      */
00376     if (seq < lastSeen_) { /* not in-order -- XXX should it be <= ? */
00377         if (buftail_ == i) {
00378             hdr_snoop *sh = hdr_snoop::access(pkts_[i]);
00379             sh->senderRxmit() = 1;
00380             sh->numRxmit() = 0;
00381         }
00382         expNextAck_ = buftail_;
00383         retval = SNOOP_TAIL;
00384     } else
00385         lastSeen_ = seq;
00386     
00387     return retval;
00388 }

Here is the call graph for this function:

int Snoop::snoop_qlong  )  [protected]
 

Definition at line 703 of file snoop.cc.

Referenced by snoop_rxmit().

00704 {
00705     /* For now only instantaneous lengths */
00706     //  if (parent_->ifq()->length() <= 3*parent_->ifq()->limit()/4)
00707     
00708     return 1;
00709         //  return 0;
00710 }

void Snoop::snoop_rtt double   )  [protected]
 

Definition at line 658 of file snoop.cc.

References Scheduler::clock(), Scheduler::instance(), LLSnoop::integrate(), parent_, and LLSnoop::snoop_rtt().

00659 {
00660     double rtt = Scheduler::instance().clock() - sndTime;
00661 
00662     if (parent_->integrate()) {
00663         parent_->snoop_rtt(sndTime);
00664         return;
00665     }
00666     
00667     if (rtt > 0) {
00668         srtt_ = g_*srtt_ + (1-g_)*rtt;
00669         double delta = rtt - srtt_;
00670         if (delta < 0)
00671             delta = -delta;
00672         if (rttvar_ != 0)
00673             rttvar_ = g_*delta + (1-g_)*rttvar_;
00674         else 
00675             rttvar_ = delta;
00676     }
00677 }

Here is the call graph for this function:

int Snoop::snoop_rxmit Packet  ) 
 

Definition at line 716 of file snoop.cc.

References hdr_tcp::access(), hdr_snoop::access(), Scheduler::clock(), Packet::copy(), hdr_cmn::direction(), hdr_cmn::DOWN, HDR_CMN, Scheduler::instance(), parent_, LL::sendDown(), hdr_tcp::seqno(), sh, SNOOP_MAX_RXMIT, SNOOP_PROPAGATE, and snoop_qlong().

Referenced by command(), SnoopRxmitHandler::handle(), and snoop_ack().

00717 {
00718     Scheduler& s = Scheduler::instance();
00719     if (pkt != 0) {
00720         hdr_snoop *sh = hdr_snoop::access(pkt);
00721         if (sh->numRxmit() < SNOOP_MAX_RXMIT && snoop_qlong()) {
00722             /*          && sh->seqno() == lastAck_+1)  */
00723             
00724 #if 0
00725             printf("%f Rxmitting packet %d\n", s.clock(), 
00726                    hdr_tcp::access(pkt)->seqno());
00727 #endif
00728             
00729             // need to specify direction, in this case, down
00730             hdr_cmn *ch = HDR_CMN(pkt);       
00731             ch->direction() = hdr_cmn::DOWN;  // Ben added
00732 
00733             sh->sndTime() = s.clock();
00734             sh->numRxmit() = sh->numRxmit() + 1;
00735             Packet *p = pkt->copy();
00736             parent_->sendDown(p);
00737         } else 
00738             return SNOOP_PROPAGATE;
00739     }
00740     /* Reset timeout for later time. */
00741     if (toutPending_) {
00742         s.cancel(toutPending_);
00743         // xxx: I think that toutPending_ doesn't need to be freed because snoop didn't allocate it (but I'm not sure).
00744     };
00745     toutPending_ = (Event *)pkt;
00746     s.schedule(rxmitHandler_, toutPending_, timeout());
00747     return SNOOP_SUPPRESS;
00748 }

Here is the call graph for this function:

void Snoop::snoop_wired_ack Packet  )  [protected]
 

Definition at line 560 of file snoop.cc.

References hdr_flags::access(), hdr_tcp::access(), hdr_flags::eln_, hdr_seq::seq, hdr_tcp::seqno(), SNOOP_WLEMPTY, snoop_wlessloss(), wl_bufhead_, wl_buftail_, wl_lastAck_, wl_next(), wl_state_, and wlseqs_.

00561 {
00562     hdr_tcp *th = hdr_tcp::access(p);
00563     int ack = th->seqno();
00564     int i;
00565     
00566     if (ack == wl_lastAck_ && snoop_wlessloss(ack)) {
00567         hdr_flags::access(p)->eln_ = 1;
00568     } else if (ack > wl_lastAck_) {
00569         /* update info about unack'd data */
00570         for (i = wl_buftail_; i != wl_bufhead_; i = wl_next(i)) {
00571             hdr_seq *t = wlseqs_[i];
00572             if (t->seq + t->num - 1 <= ack) {
00573                 t->seq = t->num = 0;
00574             } else if (ack < t->seq) {
00575                 break;
00576             } else if (ack < t->seq + t->num - 1) {
00577                 /* ack for part of a block */
00578                 t->num -= ack - t->seq +1;
00579                 t->seq = ack + 1;
00580                 break;
00581             }
00582         }
00583         wl_buftail_ = i;
00584         if (wl_buftail_ == wl_bufhead_)
00585             wl_state_ |= SNOOP_WLEMPTY;
00586         wl_lastAck_ = ack;
00587         /* Even a new ack could cause an ELN to be set. */
00588         if (wl_bufhead_ != wl_buftail_ && snoop_wlessloss(ack))
00589             hdr_flags::access(p)->eln_ = 1;
00590     }
00591 }

Here is the call graph for this function:

void Snoop::snoop_wless_data Packet  )  [protected]
 

Definition at line 517 of file snoop.cc.

References hdr_tcp::access(), num, hdr_seq::num, hdr_seq::seq, hdr_tcp::seqno(), SNOOP_WLALIVE, SNOOP_WLEMPTY, wl_bufhead_, wl_buftail_, wl_lastAck_, wl_lastSeen_, wl_next(), wl_prev(), wl_state_, wlreset(), and wlseqs_.

Referenced by handle().

00518 {
00519     hdr_tcp *th = hdr_tcp::access(p);
00520     int i, seq = th->seqno();
00521 
00522     if (wl_state_ & SNOOP_WLALIVE && seq == 0)
00523         wlreset();
00524     wl_state_ |= SNOOP_WLALIVE;
00525 
00526     if (wl_state_ & SNOOP_WLEMPTY && seq >= wl_lastAck_) {
00527         wlseqs_[wl_bufhead_]->seq = seq;
00528         wlseqs_[wl_bufhead_]->num = 1;
00529         wl_buftail_ = wl_bufhead_;
00530         wl_bufhead_ = wl_next(wl_bufhead_);
00531         wl_lastSeen_ = seq;
00532         wl_state_ &= ~SNOOP_WLEMPTY;
00533         return;
00534     }
00535     /* WL data list definitely not empty at this point. */
00536     if (seq >= wl_lastSeen_) {
00537         wl_lastSeen_ = seq;
00538         i = wl_prev(wl_bufhead_);
00539         if (wlseqs_[i]->seq + wlseqs_[i]->num == seq) {
00540             wlseqs_[i]->num++;
00541             return;
00542         }
00543         i = wl_bufhead_;
00544         wl_bufhead_ = wl_next(wl_bufhead_);
00545     } else if (seq == wlseqs_[i = wl_buftail_]->seq - 1) {
00546     } else
00547         return;
00548 
00549     wlseqs_[i]->seq = seq;
00550     wlseqs_[i]->num++;
00551 
00552     /* Ignore network out-of-ordering and retransmissions for now */
00553     return;
00554 }

Here is the call graph for this function:

int Snoop::snoop_wlessloss int   )  [protected]
 

Definition at line 600 of file snoop.cc.

References wl_bufhead_, wl_buftail_, and wlseqs_.

Referenced by snoop_wired_ack().

00601 {
00602     if ((wl_bufhead_ == wl_buftail_) || wlseqs_[wl_buftail_]->seq > ack+1)
00603         return 1;
00604     return 0;
00605 }

double Snoop::timeout  )  [inline, protected]
 

Definition at line 143 of file snoop.h.

References LLSnoop::integrate(), max, parent_, rttvar_, snoopTick_, srtt_, and LLSnoop::timeout().

Referenced by snoop_cleanbufs_(), and snoop_data().

00143                             { 
00144         if (!parent_->integrate())
00145             return max(srtt_+4*rttvar_, snoopTick_);
00146         else
00147             return parent_->timeout();
00148     }

Here is the call graph for this function:

void Snoop::update_state_  )  [protected]
 

int Snoop::wl_next int  i  )  [inline]
 

Definition at line 123 of file snoop.h.

References SNOOP_WLSEQS.

Referenced by snoop_wired_ack(), and snoop_wless_data().

00123 { return (i+1) % SNOOP_WLSEQS; }

int Snoop::wl_prev int  i  )  [inline]
 

Definition at line 124 of file snoop.h.

References SNOOP_WLSEQS.

Referenced by snoop_wless_data().

00124 { return ((i == 0) ? SNOOP_WLSEQS-1 : i-1);};

void Snoop::wlreset  )  [protected]
 

Definition at line 122 of file snoop.cc.

References num, SNOOP_WLEMPTY, SNOOP_WLSEQS, wl_bufhead_, wl_buftail_, wl_state_, and wlseqs_.

Referenced by snoop_wless_data().

00123 {
00124     wl_state_ = SNOOP_WLEMPTY;
00125     wl_bufhead_ = wl_buftail_ = 0;
00126     for (int i = 0; i < SNOOP_WLSEQS; i++) {
00127         wlseqs_[i]->seq = wlseqs_[i]->num = 0;
00128     }
00129 }


Friends And Related Function Documentation

friend class SnoopPersistHandler [friend]
 

Definition at line 115 of file snoop.h.

friend class SnoopRxmitHandler [friend]
 

Definition at line 114 of file snoop.h.

Referenced by Snoop().


Field Documentation

short Snoop::bufhead_ [protected]
 

Definition at line 166 of file snoop.h.

Referenced by empty_(), SnoopRxmitHandler::handle(), reset(), snoop_ack(), snoop_cleanbufs_(), and snoop_insert().

short Snoop::buftail_ [protected]
 

Definition at line 168 of file snoop.h.

Referenced by command(), empty_(), SnoopRxmitHandler::handle(), reset(), snoop_ack(), snoop_cleanbufs_(), snoop_data(), and snoop_insert().

Handler* Snoop::callback_ [protected]
 

Definition at line 153 of file snoop.h.

int NsObject::debug_ [protected, inherited]
 

Reimplemented in FECModel, FloodAgent, and LandmarkAgent.

Definition at line 66 of file object.h.

Referenced by REDQueue::command(), RedPDQueue::command(), PushbackQueue::command(), NsObject::debug(), NsObject::delay_bind_dispatch(), PushbackQueue::enque(), NsObject::isdebug(), NsObject::NsObject(), TfrcAgent::recv(), PushbackQueue::reportDrop(), SctpAgent::Reset(), REDQueue::reset(), DropTail::shrink_queue(), and Delayer::try_send().

short Snoop::expDupacks_ [protected]
 

Definition at line 161 of file snoop.h.

Referenced by reset(), and snoop_ack().

int Snoop::expNextAck_ [protected]
 

Definition at line 160 of file snoop.h.

Referenced by SnoopRxmitHandler::handle(), reset(), and snoop_ack().

u_short Snoop::fstate_ [protected]
 

Definition at line 157 of file snoop.h.

Referenced by empty_(), SnoopRxmitHandler::handle(), reset(), snoop_ack(), snoop_cleanbufs_(), snoop_data(), and snoop_insert().

double Snoop::g_ [protected]
 

Definition at line 180 of file snoop.h.

Referenced by Snoop().

int Snoop::integrate_ [protected]
 

Definition at line 181 of file snoop.h.

int Snoop::lastAck_ [protected]
 

Definition at line 159 of file snoop.h.

Referenced by SnoopRxmitHandler::handle(), reset(), snoop_ack(), and snoop_insert().

int Snoop::lastSeen_ [protected]
 

Definition at line 158 of file snoop.h.

Referenced by reset(), snoop_data(), and snoop_insert().

int Snoop::lru_ [protected]
 

Definition at line 182 of file snoop.h.

Referenced by Snoop(), and snoop_data().

int Snoop::maxbufs_ [protected]
 

Definition at line 178 of file snoop.h.

Referenced by next(), prev(), and Snoop().

LLSnoop* Snoop::parent_ [protected]
 

Definition at line 151 of file snoop.h.

Referenced by command(), handle(), snoop_data(), snoop_rtt(), snoop_rxmit(), and timeout().

SnoopPersistHandler* Snoop::persistHandler_ [protected]
 

Definition at line 155 of file snoop.h.

Packet* Snoop::pkts_[SNOOP_MAXWIND] [protected]
 

Definition at line 169 of file snoop.h.

Referenced by command(), SnoopRxmitHandler::handle(), reset(), savepkt_(), Snoop(), snoop_ack(), snoop_cleanbufs_(), snoop_data(), and snoop_insert().

NsObject* Snoop::recvtarget_ [protected]
 

Definition at line 152 of file snoop.h.

Referenced by command(), and handle().

double Snoop::rttvar_ [protected]
 

Definition at line 163 of file snoop.h.

Referenced by Snoop(), and timeout().

SnoopRxmitHandler* Snoop::rxmitHandler_ [protected]
 

Definition at line 154 of file snoop.h.

Referenced by Snoop(), snoop_cleanbufs_(), and snoop_data().

int Snoop::rxmitStatus_ [protected]
 

Definition at line 165 of file snoop.h.

Referenced by command(), and Snoop().

int Snoop::snoopDisable_ [protected]
 

Definition at line 156 of file snoop.h.

Referenced by Snoop().

double Snoop::snoopTick_ [protected]
 

Definition at line 179 of file snoop.h.

Referenced by Snoop(), and timeout().

double Snoop::srtt_ [protected]
 

Definition at line 162 of file snoop.h.

Referenced by Snoop(), and timeout().

double Snoop::tailTime_ [protected]
 

Definition at line 164 of file snoop.h.

Referenced by Snoop(), and snoop_cleanbufs_().

Event* Snoop::toutPending_ [protected]
 

Definition at line 167 of file snoop.h.

Referenced by SnoopRxmitHandler::handle(), reset(), snoop_cleanbufs_(), and snoop_data().

int Snoop::wl_bufhead_ [protected]
 

Definition at line 174 of file snoop.h.

Referenced by snoop_wired_ack(), snoop_wless_data(), snoop_wlessloss(), and wlreset().

int Snoop::wl_buftail_ [protected]
 

Definition at line 175 of file snoop.h.

Referenced by snoop_wired_ack(), snoop_wless_data(), snoop_wlessloss(), and wlreset().

int Snoop::wl_lastAck_ [protected]
 

Definition at line 173 of file snoop.h.

Referenced by snoop_wired_ack(), and snoop_wless_data().

int Snoop::wl_lastSeen_ [protected]
 

Definition at line 172 of file snoop.h.

Referenced by snoop_wless_data().

int Snoop::wl_state_ [protected]
 

Definition at line 171 of file snoop.h.

Referenced by snoop_wired_ack(), snoop_wless_data(), and wlreset().

hdr_seq* Snoop::wlseqs_[SNOOP_WLSEQS] [protected]
 

Definition at line 176 of file snoop.h.

Referenced by Snoop(), snoop_wired_ack(), snoop_wless_data(), snoop_wlessloss(), and wlreset().


The documentation for this class was generated from the following files:
Generated on Tue Mar 6 17:31:40 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6