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 #include "tfrc.h" 00042 00043 #define LARGE_DOUBLE 9999999999.99 00044 #define SAMLLFLOAT 0.0000001 00045 00046 /* packet status */ 00047 #define UNKNOWN 0 00048 #define RCVD 1 00049 #define LOST 2 // Lost, and beginning of a new loss event 00050 #define NOT_RCVD 3 // Lost, but not the beginning of a new loss event 00051 #define ECNLOST 4 // ECN, and beginning of a new loss event 00052 #define ECN_RCVD 5 // Received with ECN. 00053 00054 #define DEFAULT_NUMSAMPLES 8 00055 00056 #define WALI 1 00057 #define EWMA 2 00058 #define RBPH 3 00059 #define EBPH 4 00060 00061 class TfrcSinkAgent; 00062 00063 class TfrcNackTimer : public TimerHandler { 00064 public: 00065 TfrcNackTimer(TfrcSinkAgent *a) : TimerHandler() { 00066 a_ = a; 00067 } 00068 virtual void expire(Event *e); 00069 protected: 00070 TfrcSinkAgent *a_; 00071 }; 00072 00073 class TfrcSinkAgent : public Agent { 00074 friend class TfrcNackTimer; 00075 public: 00076 TfrcSinkAgent(); 00077 void recv(Packet*, Handler*); 00078 protected: 00079 void sendpkt(double); 00080 void nextpkt(double); 00081 double adjust_history(double); 00082 double est_loss(); 00083 double est_thput(); 00084 int command(int argc, const char*const* argv); 00085 void print_loss(int sample, double ave_interval); 00086 void print_loss_all(int *sample); 00087 void print_losses_all(int *losses); 00088 void print_count_losses_all(int *count_losses); 00089 void print_num_rtts_all(int *num_rtts); 00090 int new_loss(int i, double tstamp); 00091 double estimate_tstamp(int before, int after, int i); 00092 00093 // algo specific 00094 double est_loss_WALI(); 00095 void shift_array(int *a, int sz, int defval) ; 00096 void shift_array(double *a, int sz, double defval) ; 00097 void multiply_array(double *a, int sz, double multiplier); 00098 void init_WALI(); 00099 double weighted_average(int start, int end, double factor, double *m, double *w, int *sample); 00100 int get_sample(int oldSample, int numLosses); 00101 int get_sample_rtts(int oldSample, int numLosses, int rtts); 00102 double weighted_average1(int start, int end, double factor, double *m, double *w, int *sample, int ShortIntervals, int *losses, int *count_losses, int *num_rtts); 00103 00104 double est_loss_EWMA () ; 00105 00106 double est_loss_RBPH () ; 00107 00108 double est_loss_EBPH() ; 00109 00110 //comman variables 00111 00112 TfrcNackTimer nack_timer_; 00113 00114 int psize_; // size of received packet 00115 int fsize_; // size of large TCP packet, for VoIP mode. 00116 double rtt_; // rtt value reported by sender 00117 double tzero_; // timeout value reported by sender 00118 int smooth_; // for the smoother method for incorporating 00119 // incorporating new loss intervals 00120 int total_received_; // total # of pkts rcvd by rcvr, 00121 // for statistics only 00122 int total_losses_; // total # of losses, for statistics only 00123 int total_dropped_; // total # of drops, for statistics 00124 int bval_; // value of B used in the formula 00125 double last_report_sent; // when was last feedback sent 00126 double NumFeedback_; // how many feedbacks per rtt 00127 int rcvd_since_last_report; // # of packets rcvd since last report 00128 int losses_since_last_report; // # of losses since last report 00129 int printLoss_; // to print estimated loss rates 00130 int maxseq; // max seq number seen 00131 int maxseqList; // max seq number checked for dropped packets 00132 int numPkts_; // Num non-sequential packets before 00133 // inferring loss 00134 double minDiscountRatio_; // Minimum for history discounting. 00135 int numPktsSoFar_; // Num non-sequential packets so far 00136 int PreciseLoss_; // to estimate loss events more precisely 00137 00138 // an option for single-RTT loss intervals 00139 int ShortIntervals_ ; // For calculating loss event rates for short 00140 // loss intervals: "0" for counting a 00141 // single loss; "1" for counting the actual 00142 // number of losses; "2" for counting at 00143 // most a large packet of losses (not done); 00144 // "3" for decreasing fraction of losses 00145 // counted for longer loss intervals; 00146 // >10 for old methods that don't ignore the 00147 // current short loss interval. 00148 int ShortRtts_ ; // Max num of RTTs in a short interval. 00149 00150 // these assist in keep track of incoming packets and calculate flost_ 00151 double last_timestamp_; // timestamp of last new, in-order pkt arrival. 00152 double last_arrival_; // time of last new, in-order pkt arrival. 00153 int hsz; // InitHistorySize_, number of pkts in history 00154 char *lossvec_; // array with packet history 00155 double *rtvec_; // array with time of packet arrival 00156 double *tsvec_; // array with timestamp of packet 00157 int lastloss_round_id ; // round_id for start of loss event 00158 int round_id ; // round_id of last new, in-order packet 00159 double lastloss; // when last loss occured 00160 00161 // WALI specific 00162 int numsamples ; 00163 int *sample; // array with size of loss interval 00164 double *weights ; // weight for loss interval 00165 double *mult ; // discount factor for loss interval 00166 int *losses ; // array with number of losses per loss 00167 // interval 00168 int *count_losses ; // "1" to count losses in the loss interval 00169 int *num_rtts ; // number of rtts per loss interval 00170 double mult_factor_; // most recent multiple of mult array 00171 int sample_count ; // number of loss intervals 00172 int last_sample ; // loss event rate estimated to here 00173 int init_WALI_flag; // sample arrays initialized 00174 00175 // these are for "faking" history after slow start 00176 int loss_seen_yet; // have we seen the first loss yet? 00177 int adjust_history_after_ss; // fake history after slow start? (0/1) 00178 int false_sample; // by how much? 00179 00180 int algo; // algo for loss estimation 00181 int discount ; // emphasize most recent loss interval 00182 // when it is very large 00183 int bytes_ ; // For reporting on received bytes. 00184 00185 // EWMA: optional variants 00186 double history ; 00187 double avg_loss_int ; 00188 int loss_int ; 00189 00190 // RBPH, EBPH: optional variants 00191 double sendrate ; 00192 int minlc ; 00193 00194 };