00001 /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 00002 /* 00003 * Copyright (c) 1997 Regents of the University of California. 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 3. All advertising materials mentioning features or use of this software 00015 * must display the following acknowledgement: 00016 * This product includes software developed by the MASH Research 00017 * Group at the University of California Berkeley. 00018 * 4. Neither the name of the University nor of the Research Group may be 00019 * used to endorse or promote products derived from this software without 00020 * specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00023 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00028 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00029 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00031 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00032 * SUCH DAMAGE. 00033 * 00034 * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/tcp/snoop.h,v 1.14 2002/05/06 22:23:16 difa Exp $ (UCB) 00035 */ 00036 00037 #ifndef ns_snoop_h 00038 #define ns_snoop_h 00039 00040 #include "scheduler.h" 00041 #include "packet.h" 00042 #include "ip.h" 00043 #include "tcp.h" 00044 #include "ll.h" 00045 #include "mac.h" 00046 #include "flags.h" 00047 #include "template.h" 00048 00049 /* Snoop states */ 00050 #define SNOOP_ACTIVE 0x01 /* connection active */ 00051 #define SNOOP_CLOSED 0x02 /* connection closed */ 00052 #define SNOOP_NOACK 0x04 /* no ack seen yet */ 00053 #define SNOOP_FULL 0x08 /* snoop cache full */ 00054 #define SNOOP_RTTFLAG 0x10 /* can compute RTT if this is set */ 00055 #define SNOOP_ALIVE 0x20 /* connection has been alive past 1 sec */ 00056 #define SNOOP_WLALIVE 0x40 /* wl connection has been alive past 1 sec */ 00057 #define SNOOP_WLEMPTY 0x80 00058 00059 #define SNOOP_MAXWIND 100 /* XXX */ 00060 #define SNOOP_WLSEQS 8 00061 #define SNOOP_MIN_TIMO 0.100 /* in seconds */ 00062 #define SNOOP_MAX_RXMIT 10 /* quite arbitrary at this point */ 00063 #define SNOOP_PROPAGATE 1 00064 #define SNOOP_SUPPRESS 2 00065 00066 #define SNOOP_MAKEHANDLER 1 00067 #define SNOOP_TAIL 1 00068 00069 struct hdr_seq { 00070 int seq; 00071 int num; 00072 }; 00073 00074 struct hdr_snoop { 00075 int seqno_; 00076 int numRxmit_; 00077 int senderRxmit_; 00078 double sndTime_; 00079 00080 static int offset_; 00081 inline static int& offset() { return offset_; } 00082 inline static hdr_snoop* access(const Packet* p) { 00083 return (hdr_snoop*) p->access(offset_); 00084 } 00085 00086 inline int& seqno() { return seqno_; } 00087 inline int& numRxmit() { return numRxmit_; } 00088 inline int& senderRxmit() { return senderRxmit_; } 00089 inline double& sndTime() { return sndTime_; } 00090 }; 00091 00092 class LLSnoop : public LL { 00093 public: 00094 LLSnoop() : LL() { bind("integrate_", &integrate_);} 00095 void recv(Packet *, Handler *); 00096 void snoop_rtt(double); 00097 inline double timeout() { 00098 return max(srtt_+4*rttvar_, snoopTick_); 00099 } 00100 inline int integrate() { return integrate_; } 00101 protected: 00102 int integrate_; 00103 double srtt_; 00104 double rttvar_; 00105 double g_; 00106 double snoopTick_; /* minimum rxmission timer granularity */ 00107 }; 00108 00109 00110 class SnoopRxmitHandler; 00111 class SnoopPersistHandler; 00112 00113 class Snoop : public NsObject { 00114 friend class SnoopRxmitHandler; 00115 friend class SnoopPersistHandler; 00116 public: 00117 Snoop(); 00118 void recv(Packet *, Handler *); 00119 void handle(Event *); 00120 int snoop_rxmit(Packet *); 00121 inline int next(int i) { return (i+1) % maxbufs_; } 00122 inline int prev(int i) { return ((i == 0) ? maxbufs_-1 : i-1); }; 00123 inline int wl_next(int i) { return (i+1) % SNOOP_WLSEQS; } 00124 inline int wl_prev(int i) { return ((i == 0) ? SNOOP_WLSEQS-1 : i-1);}; 00125 00126 protected: 00127 int command(int argc, const char*const* argv); 00128 void reset(); 00129 void wlreset(); 00130 void snoop_data(Packet *); 00131 int snoop_ack(Packet *); 00132 void snoop_wless_data(Packet *); 00133 void snoop_wired_ack(Packet *); 00134 int snoop_wlessloss(int); 00135 double snoop_cleanbufs_(int); 00136 void snoop_rtt(double); 00137 int snoop_qlong(); 00138 int snoop_insert(Packet *); 00139 inline int empty_() 00140 {return (bufhead_==buftail_ &&!(fstate_&SNOOP_FULL));} 00141 void savepkt_(Packet *, int, int); 00142 void update_state_(); 00143 inline double timeout() { 00144 if (!parent_->integrate()) 00145 return max(srtt_+4*rttvar_, snoopTick_); 00146 else 00147 return parent_->timeout(); 00148 } 00149 void snoop_cleanup(); 00150 00151 LLSnoop *parent_; /* the parent link layer object */ 00152 NsObject* recvtarget_; /* where packet is passed up the stack */ 00153 Handler *callback_; 00154 SnoopRxmitHandler *rxmitHandler_; /* used in rexmissions */ 00155 SnoopPersistHandler *persistHandler_; /* for connection (in)activity */ 00156 int snoopDisable_; /* disable snoop for this mobile */ 00157 u_short fstate_; /* state of connection */ 00158 int lastSeen_; /* first byte of last packet buffered */ 00159 int lastAck_; /* last byte recd. by mh for sure */ 00160 int expNextAck_; /* expected next ack after dup sequence */ 00161 short expDupacks_; /* expected number of dup acks */ 00162 double srtt_; /* smoothed rtt estimate */ 00163 double rttvar_; /* linear deviation */ 00164 double tailTime_; /* time at which earliest unack'd pkt sent */ 00165 int rxmitStatus_; 00166 short bufhead_; /* next pkt goes here */ 00167 Event *toutPending_; /* # pending timeouts */ 00168 short buftail_; /* first unack'd pkt */ 00169 Packet *pkts_[SNOOP_MAXWIND]; /* ringbuf of cached pkts */ 00170 00171 int wl_state_; 00172 int wl_lastSeen_; 00173 int wl_lastAck_; 00174 int wl_bufhead_; 00175 int wl_buftail_; 00176 hdr_seq *wlseqs_[SNOOP_WLSEQS]; /* ringbuf of wless data */ 00177 00178 int maxbufs_; /* max number of pkt bufs */ 00179 double snoopTick_; /* minimum rxmission timer granularity */ 00180 double g_; /* gain in EWMA for srtt_ and rttvar_ */ 00181 int integrate_; /* integrate loss rec across active conns */ 00182 int lru_; /* an lru cache? */ 00183 }; 00184 00185 class SnoopRxmitHandler : public Handler { 00186 public: 00187 SnoopRxmitHandler(Snoop *s) : snoop_(s) {} 00188 void handle(Event *event); 00189 protected: 00190 Snoop *snoop_; 00191 }; 00192 00193 class SnoopPersistHandler : public Handler { 00194 public: 00195 SnoopPersistHandler(Snoop *s) : snoop_(s) {} 00196 //void handle(Event *); 00197 protected: 00198 Snoop *snoop_; 00199 }; 00200 00201 #endif
1.3.3