Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

Snoop Class Reference

#include <snoop.h>

Inheritance diagram for Snoop:

Inheritance graph
[legend]
Collaboration diagram for Snoop:

Collaboration graph
[legend]
List of all members.

Public Member Functions

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

Protected Member Functions

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

Protected Attributes

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

Friends

class SnoopRxmitHandler
class SnoopPersistHandler

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_WLEMPTY, 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, FullTcpAgent, SackFullTcpAgent, RFC793eduTcpAgent, TcpSink, TcpAgent, and VegasTcpAgent.

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, FullTcpAgent, SackFullTcpAgent, RFC793eduTcpAgent, TcpSink, TcpAgent, and VegasTcpAgent.

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(), hdr_cmn::error(), Packet::free(), Scheduler::instance(), packet_t, 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::access(), hdr_cmn::direction(), hdr_cmn::DOWN, handle(), HDR_CMN, packet_t, parent_, PT_ACK, PT_TCP, hdr_cmn::ptype(), LL::sendDown(), snoop_data(), snoop_wired_ack(), 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.

Referenced by snoop_insert().

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_, hdr_tcp::seqno(), sh, snoop_cleanbufs_(), SNOOP_CLOSED, SNOOP_MAXWIND, SNOOP_NOACK, SNOOP_PROPAGATE, snoop_rtt(), 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_.

Referenced by snoop_ack().

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_.

Referenced by recv().

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(), expNextAck_, Packet::free(), fstate_, Scheduler::instance(), lastAck_, lastSeen_, next(), pkts_, prev(), savepkt_(), hdr_snoop::seqno(), 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(), g_, Scheduler::instance(), LLSnoop::integrate(), parent_, rttvar_, LLSnoop::snoop_rtt(), and srtt_.

Referenced by snoop_ack().

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::cancel(), Scheduler::clock(), Packet::copy(), hdr_cmn::direction(), hdr_cmn::DOWN, HDR_CMN, Scheduler::instance(), parent_, rxmitHandler_, Scheduler::schedule(), LL::sendDown(), hdr_tcp::seqno(), sh, SNOOP_MAX_RXMIT, SNOOP_PROPAGATE, snoop_qlong(), SNOOP_SUPPRESS, timeout(), and toutPending_.

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::num, hdr_seq::seq, hdr_tcp::seqno(), SNOOP_WLEMPTY, snoop_wlessloss(), wl_bufhead_, wl_buftail_, wl_lastAck_, wl_next(), wl_state_, and wlseqs_.

Referenced by recv().

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(), 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_(), snoop_data(), and snoop_rxmit().

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 hdr_seq::num, hdr_seq::seq, 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().


Member Data 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(), RedPDQueue::enque(), PushbackQueue::enque(), NsObject::isdebug(), NsObject::NsObject(), TfrcAgent::recv(), PushbackQueue::reportDrop(), and REDQueue::reset().

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(), snoop_ack(), and snoop_insert().

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(), and snoop_rtt().

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(), recv(), 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(), snoop_rtt(), and timeout().

SnoopRxmitHandler* Snoop::rxmitHandler_ [protected]
 

Definition at line 154 of file snoop.h.

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

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(), snoop_rtt(), 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_(), snoop_data(), and snoop_rxmit().

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 Apr 20 13:24:43 2004 for NS2.26SourcesOriginal by doxygen 1.3.3