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 int new_loss(int i, double tstamp); 00090 double estimate_tstamp(int before, int after, int i); 00091 00092 // algo specific 00093 double est_loss_WALI(); 00094 void shift_array(int *a, int sz, int defval) ; 00095 void shift_array(double *a, int sz, double defval) ; 00096 void multiply_array(double *a, int sz, double multiplier); 00097 void init_WALI(); 00098 double weighted_average(int start, int end, double factor, double *m, double *w, int *sample); 00099 int get_sample(int oldSample, int numLosses); 00100 double weighted_average1(int start, int end, double factor, double *m, double *w, int *sample, int ShortIntervals, int *losses, int *count_losses); 00101 00102 double est_loss_EWMA () ; 00103 00104 double est_loss_RBPH () ; 00105 00106 double est_loss_EBPH() ; 00107 00108 //comman variables 00109 00110 TfrcNackTimer nack_timer_; 00111 00112 int psize_; // size of received packet 00113 int fsize_; // size of large TCP packet, for VoIP mode. 00114 double rtt_; // rtt value reported by sender 00115 double tzero_; // timeout value reported by sender 00116 int smooth_; // for the smoother method for incorporating 00117 // incorporating new loss intervals 00118 int total_received_; // total # of pkts rcvd by rcvr, 00119 // for statistics only 00120 int total_losses_; // total # of losses, for statistics only 00121 int total_dropped_; // total # of drops, for statistics 00122 int bval_; // value of B used in the formula 00123 double last_report_sent; // when was last feedback sent 00124 double NumFeedback_; // how many feedbacks per rtt 00125 int rcvd_since_last_report; // # of packets rcvd since last report 00126 int losses_since_last_report; // # of losses since last report 00127 int printLoss_; // to print estimated loss rates 00128 int maxseq; // max seq number seen 00129 int maxseqList; // max seq number checked for dropped packets 00130 int numPkts_; // Num non-sequential packets before 00131 // inferring loss 00132 int numPktsSoFar_; // Num non-sequential packets so far 00133 int PreciseLoss_; // to estimate loss events more precisely 00134 // an option for single-RTT loss intervals 00135 int ShortIntervals_ ; // For calculating loss event rates for short 00136 // loss intervals: "0" for counting a 00137 // single loss; "1" for counting the actual 00138 // number of losses; "2" for counting at 00139 // most a large packet of losses. 00140 00141 // these assist in keep track of incming packets and calculate flost_ 00142 double last_timestamp_; // timestamp of last new, in-order pkt arrival. 00143 double last_arrival_; // time of last new, in-order pkt arrival. 00144 int hsz; // InitHistorySize_, number of pkts in history 00145 char *lossvec_; // array with packet history 00146 double *rtvec_; // array with time of packet arrival 00147 double *tsvec_; // array with timestamp of packet 00148 int lastloss_round_id ; // round_id for start of loss event 00149 int round_id ; // round_id of last new, in-order packet 00150 double lastloss; // when last loss occured 00151 00152 // WALI specific 00153 int numsamples ; 00154 int *sample; // array with size of loss interval 00155 double *weights ; // weight for loss interval 00156 double *mult ; // discount factor for loss interval 00157 int *losses ; // array with number of losses per loss 00158 // interval 00159 int *count_losses ; // "1" to count losses in the loss interval 00160 double mult_factor_; // most recent multiple of mult array 00161 int sample_count ; // number of loss intervals 00162 int last_sample ; // loss event rate estimated to here 00163 int init_WALI_flag; // sample arrays initialized 00164 00165 // these are for "faking" history after slow start 00166 int loss_seen_yet; // have we seen the first loss yet? 00167 int adjust_history_after_ss; // fake history after slow start? (0/1) 00168 int false_sample; // by how much? 00169 00170 int algo; // algo for loss estimation 00171 int discount ; // emphasize most recent loss interval 00172 // when it is very large 00173 int bytes_ ; // For reporting on received bytes. 00174 00175 // EWMA: optional variants 00176 double history ; 00177 double avg_loss_int ; 00178 int loss_int ; 00179 00180 // RBPH, EBPH: optional variants 00181 double sendrate ; 00182 int minlc ; 00183 00184 };
1.4.6