00001 /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 00002 /* 00003 * Copyright (c) 1991-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 Computer Systems 00017 * Engineering Group at Lawrence Berkeley Laboratory. 00018 * 4. Neither the name of the University nor of the Laboratory may be used 00019 * 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 00036 #include "agent.h" 00037 #include "packet.h" 00038 #include "ip.h" 00039 #include "timer-handler.h" 00040 #include "random.h" 00041 00042 #define SMALLFLOAT 0.0000001 00043 00044 /* receiver response */ 00045 00046 #define DECREASE 1 00047 #define NORMAL 2 00048 #define INCREASE 3 00049 00050 #define MAXSEQ 1073741824 /* Number that curseq_ is set to for */ 00051 /* "infinite send" (2^30) */ 00052 00053 00054 /* modes of rate change */ 00055 #define SLOW_START 1 00056 #define CONG_AVOID 2 00057 #define RATE_DECREASE 3 00058 #define OUT_OF_SLOW_START 4 00059 00060 struct hdr_tfrc { 00061 00062 // RFC 3448 specifies that the data packet include the sequence 00063 // number, timestamp, and RTT estimate. 00064 int seqno; //data sequence number 00065 double timestamp; //time this message was sent 00066 double rtt; //RTT estimate of sender 00067 // "rate" is used by one of the experimental algorithms, RBPH. 00068 double rate; //sender's current rate 00069 // In a real implementation, tzero, psize, and fsize 00070 // would not be in the packet header. 00071 // They are here for convenience. 00072 double tzero; //RTO in Umass eqn 00073 int psize; //Packet size. 00074 int fsize; //The default large packet size for VoIP. 00075 // UrgentFlag is used to request that a loss report be sent 00076 // immediately. 00077 int UrgentFlag; //Urgent Flag 00078 // "round_id" is used by PreciseLoss_, a variant for more 00079 // precise loss events that is on by default. 00080 int round_id ; //round id. 00081 00082 static int offset_; // offset for this header 00083 inline static int& offset() { 00084 return offset_; 00085 } 00086 inline static hdr_tfrc* access(const Packet* p) { 00087 return (hdr_tfrc*) p->access(offset_); 00088 } 00089 00090 }; 00091 00092 struct hdr_tfrc_ack { 00093 00094 // RFC 3448 specifies that feedback packets must include the 00095 // timestamp_echo, timestamp_offset, flost, and 00096 // rate_since_last_report. 00097 double timestamp_offset; //offset since we received data packet 00098 double timestamp_echo; //timestamp from the last data packet 00099 double flost; //frequency of loss indications 00100 double rate_since_last_report; //what it says ... 00101 // Used in optional variants: 00102 int losses; // number of losses in last RTT 00103 double NumFeedback_; //number of times/RTT feedback is to be sent 00104 // Used for statistics-reporting only: 00105 double true_loss; // true loss event rate. 00106 // Not used: 00107 int seqno; // not sure yet 00108 double timestamp; //time this nack was sent 00109 00110 00111 static int offset_; // offset for this header 00112 inline static int& offset() { 00113 return offset_; 00114 } 00115 inline static hdr_tfrc_ack* access(const Packet* p) { 00116 return (hdr_tfrc_ack*) p->access(offset_); 00117 } 00118 }; 00119 00120 class TfrcAgent; 00121 00122 class TfrcSendTimer : public TimerHandler { 00123 public: 00124 TfrcSendTimer(TfrcAgent *a) : TimerHandler() { a_ = a; } 00125 virtual void expire(Event *e); 00126 protected: 00127 TfrcAgent *a_; 00128 }; 00129 00130 class TfrcNoFeedbackTimer : public TimerHandler { 00131 public: 00132 TfrcNoFeedbackTimer(TfrcAgent *a) : TimerHandler() { a_ = a; } 00133 virtual void expire(Event *e); 00134 protected: 00135 TfrcAgent *a_; 00136 }; 00137 00138 class TfrcAgent : public Agent { 00139 friend class TfrcSendTimer; 00140 friend class TfrcNoFeedbackTimer; 00141 public: 00142 TfrcAgent(); 00143 void recv(Packet*, Handler*); 00144 void sendpkt(); 00145 void nextpkt(); 00146 int command(int argc, const char*const* argv); 00147 void start(); 00148 void stop(); 00149 void update_rtt(double tao, double now); 00150 void increase_rate(double p); 00151 void decrease_rate(); 00152 double rfc3390(int size); 00153 double initial_rate(); 00154 void slowstart(); 00155 void reduce_rate_on_no_feedback(); 00156 void advanceby(int delta); 00157 void sendmsg(int nbytes, const char *flags = 0); 00158 protected: 00159 TfrcSendTimer send_timer_; 00160 TfrcNoFeedbackTimer NoFeedbacktimer_; 00161 00162 /* "accurate" estimates for formula */ 00163 double rtt_; /*EWMA version*/ 00164 double rttcur_; /*Instantaneous version*/ 00165 double rttvar_; 00166 double tzero_; 00167 double sqrtrtt_; /*The mean of the sqrt of the RTT*/ 00168 00169 int ca_; //Enable Sqrt(RTT) based congestion avoidance mode 00170 00171 /* TCP variables for tracking RTT */ 00172 int t_srtt_; 00173 int t_rtt_; 00174 int t_rttvar_; 00175 int rttvar_exp_; 00176 double t_rtxcur_; 00177 double tcp_tick_; 00178 int T_SRTT_BITS; 00179 int T_RTTVAR_BITS; 00180 int srtt_init_; 00181 int rttvar_init_; 00182 double rtxcur_init_; 00183 /* End of TCP variables for tracking RTT */ 00184 00185 // Dynamic state: 00186 int maxseq_; // max seq produced by the app so far 00187 int seqno_; // next seq to be sent 00188 int psize_; 00189 double rate_; // send rate 00190 double oldrate_; // allows rate to be changed gradually 00191 double delta_; // allows rate to be changed gradually 00192 int rate_change_; // slow start, cong avoid, decrease ... 00193 double last_change_; // time last change in rate was made 00194 double rcvrate ; // TCP friendly rate based on current RTT 00195 // and recever-provded loss estimate 00196 double maxrate_; // prevents sending at more than 2 times the 00197 // rate at which the receiver is _receving_ 00198 double ss_maxrate_; // max rate for during slowstart 00199 TracedInt ndatapack_; // number of packets sent 00200 TracedInt ndatabytes_; // number of bytes sent 00201 TracedDouble true_loss_rate_; // true loss event rate, 00202 int active_; // have we shut down? 00203 int round_id ; // round id 00204 int first_pkt_rcvd ; // first ack received yet? 00205 double last_pkt_time_; // time the last data packet was sent 00206 int maxqueue_; // max queue from application 00207 int UrgentFlag; // urgent flag 00208 int all_idle_; // has the sender been idle since the 00209 // nofeedback timer was set? 00210 double lastlimited_; // time sender was last datalimited. 00211 // End of dynamic state. 00212 00213 // Parameters: 00214 int InitRate_; // initial send rate 00215 double df_; // decay factor for accurate RTT estimate 00216 double ssmult_; // during slow start, increase rate by this 00217 // factor every rtt 00218 int bval_; // value of B for the formula 00219 double overhead_; // if > 0, dither outgoing packets 00220 int ecn_ ; // Set to 1 for an ECN-capable connection. 00221 double minrto_ ; // for experimental purposes, for a minimum 00222 // RTO value (for use in the TCP-friendly 00223 // equation). 00224 double rate_init_; // Static value for initial rate, in 00225 // packets per RTT. 00226 // for statistics only 00227 int SndrType_; // 0 -> infinite sender, 1 -> need FTP 00228 int printStatus_; // to print status reports 00229 // End of parameters: 00230 00231 /* Variants in the TFRC algorithms. */ 00232 // int standard_; // 1 for RFC 3448 algorithms. 00233 // 2 for RFC 4342 algorithms. 00234 // 3 for RFC 3448bis algorithms. 00235 int rate_init_option_; /* 1 for using static rate_init_ */ 00236 /* 2 for using RFC 3390 */ 00237 int slow_increase_; // To use slow increases in the rate during 00238 // slow-start. 00239 int datalimited_; // to send immediately when a new packet 00240 // arrives after a data-limited period 00241 int oldCode_; // set to 1 not to use "datalimited_" 00242 // parameter. 00243 int heavyrounds_; // the number of RTTs so far when the 00244 // sending rate > 2 * receiving rate 00245 int maxHeavyRounds_; // the number of allowed rounds for 00246 // sending rate > 2 * receiving rate 00247 int useHeaders_; /* boolean: Add DCCP/IP header sizes */ 00248 int idleFix_; // 1 for fix for receive rate limits 00249 // when sender has been idle 00250 /* End of variants. */ 00251 00252 /* Responses to heavy congestion. */ 00253 int conservative_; // set to 1 for an experimental, conservative 00254 // response to heavy congestion 00255 double scmult_; // self clocking parameter for conservative_ 00256 /* End of responses to heavy congestion. */ 00257 00258 /* VoIP mode, for using small packets. */ 00259 int voip_; // 1 for voip mode. 00260 int voip_max_pkt_rate_ ; // Max pkt rate in pps, for voip mode. 00261 int fsize_; // Default size for large TCP packets 00262 // (e.g., 1460 bytes). 00263 int headersize_; // Size for packet headers. 00264 /* end of VoIP mode. */ 00265 00266 00267 };