00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef ns_xcp_end_sys_h
00054 #define ns_xcp_end_sys_h
00055
00056 #include <stdio.h>
00057 #include <stdlib.h>
00058 #include <sys/types.h>
00059
00060 #include "ip.h"
00061 #include "tcp.h"
00062 #include "flags.h"
00063
00064 #include "agent.h"
00065 #include "packet.h"
00066
00067 #include "flags.h"
00068 #include "tcp-sink.h"
00069
00070 #define XCP_HDR_LEN 20
00071
00072
00073 struct hdr_xcp {
00074 double throughput_;
00075 double rtt_;
00076 enum {
00077 XCP_DISABLED = 0,
00078 XCP_ENABLED,
00079 XCP_ACK,
00080 } xcp_enabled_;
00081 bool xcp_sparse_;
00082 int xcpId_;
00083 double cwnd_;
00084 double reverse_feedback_;
00085
00086
00087 double delta_throughput_;
00088 unsigned int controlling_hop_;
00089
00090 static int offset_;
00091 inline static int& offset() { return offset_; }
00092 inline static hdr_xcp* access(Packet* p) {
00093 return (hdr_xcp*) p->access(offset_);
00094 }
00095
00096
00097 double& cwnd() { return (cwnd_); }
00098 double& rtt() { return (rtt_); }
00099 };
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 #define MAX(a,b) ((a) > (b) ? (a) : (b))
00110 #define TP_TO_TICKS MAX(1, (t_srtt_ >> T_SRTT_BITS))
00111
00112 #define TP_AVG_EXP 4 // used for xcp_metered_output_ == true
00113
00114 class XcpAgent;
00115
00116 class cwndShrinkingTimer : public TimerHandler {
00117 public:
00118 cwndShrinkingTimer(XcpAgent *a) : TimerHandler() { a_ = a; }
00119 protected:
00120 virtual void expire(Event *e);
00121 XcpAgent *a_;
00122 };
00123
00124 class XcpAgent : public RenoTcpAgent {
00125 public:
00126 XcpAgent();
00127
00128 protected:
00129
00130 double time_now() { return Scheduler::instance().clock(); };
00131 void trace_var(char * var_name, double var);
00132
00133 void init_rtt_vars(){
00134 srtt_estimate_ = 0.0;
00135 }
00136 virtual void delay_bind_init_all();
00137 virtual int delay_bind_dispatch(const char *varName,
00138 const char *localName,
00139 TclObject *tracer);
00140
00141 virtual void output(int seqno, int reason = 0);
00142 virtual void recv_newack_helper(Packet *);
00143 virtual void opencwnd();
00144 virtual void rtt_init();
00145 virtual void rtt_update(double tao);
00146
00147
00148 double current_positive_feedback_ ;
00149 int tcpId_;
00150 double srtt_estimate_;
00151
00152 #define XCP_DELTA_SHIFT 5
00153 #define XCP_EXPO_SHIFT 3
00154 #define XCP_RTT_SHIFT (XCP_DELTA_SHIFT + XCP_EXPO_SHIFT)
00155
00156 #define XCP_INIT_SRTT(rtt) \
00157 ((rtt) << XCP_RTT_SHIFT)
00158
00159 #define XCP_UPDATE_SRTT(srtt, rtt) \
00160 ((srtt) + (((rtt) << XCP_DELTA_SHIFT) \
00161 - (((srtt) + (1 << (XCP_EXPO_SHIFT - 1))) \
00162 >> XCP_EXPO_SHIFT)))
00163 long xcp_srtt_;
00164
00165 int xcp_sparse_;
00166 int xcp_sparse_seqno_;
00167
00168 cwndShrinkingTimer shrink_cwnd_timer_;
00169 };
00170
00171 class XcpSink : public Agent {
00172 public:
00173 XcpSink(Acker*);
00174 void recv(Packet* pkt, Handler*);
00175 void reset();
00176 int command(int argc, const char*const* argv);
00177
00178 protected:
00179 void ack(Packet*);
00180 virtual void add_to_ack(Packet* pkt);
00181
00182 virtual void delay_bind_init_all();
00183 virtual int delay_bind_dispatch(const char *varName,
00184 const char *localName,
00185 TclObject *tracer);
00186 Acker* acker_;
00187 int ts_echo_bugfix_;
00188 int ts_echo_rfc1323_;
00189
00190 friend void Sacker::configure(TcpSink*);
00191
00192 Packet* save_;
00193
00194 int RFC2581_immediate_ack_;
00195 int bytes_;
00196
00197 double lastreset_;
00198
00199 };
00200
00201 #endif