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 Daedalus 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 00035 #ifndef CHOST 00036 #define CHOST 00037 #include "agent.h" 00038 #include "packet.h" 00039 #include "tcp.h" 00040 #include "tcp-fs.h" 00041 #include "tcp-int.h" 00042 #include "nilist.h" 00043 00044 #define MAX_PARALLEL_CONN 1000 00045 00046 class Segment : public slink { 00047 friend class CorresHost; 00048 friend class TcpSessionAgent; 00049 public: 00050 Segment() {ts_ = 0; 00051 seqno_ = later_acks_ = dupacks_ = dport_ = sport_ = size_ = rxmitted_ = 00052 daddr_ = 0; thresh_dupacks_ = 0; partialack_ = 0;}; 00053 protected: 00054 int seqno_; 00055 int sessionSeqno_; 00056 int daddr_; 00057 int dport_; 00058 int sport_; 00059 int size_; 00060 double ts_; /* timestamp */ 00061 int dupacks_; /* on same connection */ 00062 int later_acks_; /* on other connections */ 00063 int thresh_dupacks_; /* whether there have been a threshold # of 00064 dupacks/later acks for this segment */ 00065 int partialack_; /* whether a partial ack points to this segment */ 00066 short rxmitted_; 00067 class IntTcpAgent *sender_; 00068 }; 00069 00070 class CorresHost : public slink, public TcpFsAgent { 00071 friend class IntTcpAgent; 00072 public: 00073 CorresHost(); 00074 /* add pkt to pipe */ 00075 virtual Segment* add_pkts(int size, int seqno, int sessionSeqno, int daddr, 00076 int dport, int sport, double ts, IntTcpAgent *sender); 00077 /* remove pkt from pipe */ 00078 int clean_segs(int size, Packet *pkt, IntTcpAgent *sender, int sessionSeqno, 00079 int amt_data_acked); 00080 int rmv_old_segs(Packet *pkt, IntTcpAgent *sender, int amt_data_acked); 00081 00082 void opencwnd(int size, IntTcpAgent *sender=0); 00083 void closecwnd(int how, double ts, IntTcpAgent *sender=0); 00084 void closecwnd(int how, IntTcpAgent *sender=0); 00085 void adjust_ownd(int size); 00086 int ok_to_snd(int size); 00087 virtual void add_agent(IntTcpAgent *agent, int size, double winMult, 00088 int winInc, int ssthresh); 00089 void del_agent(IntTcpAgent *) {nActive_--;}; 00090 void agent_tout(IntTcpAgent *) {nTimeout_++;}; 00091 void agent_ftout(IntTcpAgent *) {nTimeout_--;}; 00092 void agent_rcov(IntTcpAgent *) {nFastRec_++;}; 00093 void agent_frcov(IntTcpAgent *) {nFastRec_--;}; 00094 void quench(int how); 00095 00096 protected: 00097 Islist<IntTcpAgent> conns_; /* active connections */ 00098 Islist_iter<IntTcpAgent> *connIter_; 00099 u_int nActive_; /* number of active tcp conns to this host */ 00100 u_int nTimeout_; /* number of tcp conns to this host in timeout */ 00101 u_int nFastRec_; /* number of tcp conns to this host in recovery */ 00102 double closecwTS_; 00103 double winMult_; 00104 int winInc_; 00105 TracedDouble ownd_; /* outstanding data to host */ 00106 TracedDouble owndCorrection_; /* correction factor to account for dupacks */ 00107 int proxyopt_; /* indicates whether the connections are on behalf 00108 of distinct users (like those from a proxy) */ 00109 int fixedIw_; /* fixed initial window (not a function of # conn) */ 00110 Islist<Segment> seglist_; /* list of unack'd segments to peer */ 00111 double lastackTS_; 00112 /* 00113 * State encompassing the round-trip-time estimate. 00114 * srtt and rttvar are stored as fixed point; 00115 * srtt has 3 bits to the right of the binary point, rttvar has 2. 00116 */ 00117 double wndInit_; /* should = path_mtu_ */ 00118 Segment *rtt_seg_; /* segment being timed for RTT computation */ 00119 int dontAdjustOwnd_;/* don't adjust ownd in response to dupacks */ 00120 int dontIncrCwnd_; /* set when pkt loss is suspected (e.g., there is 00121 reordering) */ 00122 int rexmtSegCount_; /* number of segments that we "suspect" need to be 00123 retransmitted */ 00124 int disableIntLossRecov_; /* disable integrated loss recovery */ 00125 00126 /* possible candidates for rxmission */ 00127 Segment *curArray_[MAX_PARALLEL_CONN]; 00128 Segment *prevArray_[MAX_PARALLEL_CONN]; /* prev segs */ 00129 /* variables for fast start */ 00130 class IntTcpAgent *connWithPktBeforeFS_; 00131 00132 /* following is for right-edge timer recovery */ 00133 /* int pending_;*/ 00134 Event timer_; 00135 inline void cancel() { 00136 (void)Scheduler::instance().cancel(&timer_); 00137 // No need to free event since it's statically allocated. 00138 /* pending_ = 0;*/ 00139 } 00140 }; 00141 00142 #endif 00143