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 #ifndef ns_xcp_end_sys_h
00041 #define ns_xcp_end_sys_h
00042
00043 #include <stdio.h>
00044 #include <stdlib.h>
00045 #include <sys/types.h>
00046
00047 #include "ip.h"
00048 #include "tcp.h"
00049 #include "flags.h"
00050
00051 #include "agent.h"
00052 #include "packet.h"
00053
00054 #include "flags.h"
00055 #include "tcp-sink.h"
00056 #include "tcp-full.h"
00057
00058 #define XCP_HDR_LEN 20 // to match the internet draft
00059
00060 struct hdr_xcp {
00061 double x_;
00062 double rtt_;
00063 enum {
00064 XCP_DISABLED = 0,
00065 XCP_ENABLED,
00066 XCP_ACK,
00067 } xcp_enabled_;
00068 int xcpId_;
00069 double cwnd_;
00070 double reverse_feedback_;
00071
00072
00073 double delta_throughput_;
00074 unsigned int controlling_hop_;
00075
00076 static int offset_;
00077 inline static int& offset() { return offset_; }
00078 inline static hdr_xcp* access(Packet* p) {
00079 return (hdr_xcp*) p->access(offset_);
00080 }
00081
00082
00083 double& cwnd() { return (cwnd_); }
00084 double& rtt() { return (rtt_); }
00085 };
00086
00087
00088 #define MAX(a,b) ((a) > (b) ? (a) : (b))
00089 #define TP_TO_TICKS MAX(1, (t_srtt_ >> T_SRTT_BITS))
00090
00091 #define TP_AVG_EXP 4 // used for xcp_metered_output_ == true
00092
00093
00094 class XcpEndsys {
00095 protected:
00096 XcpEndsys(TcpAgent* tcp);
00097 void trace_var(const char *var_name, double var) const;
00098 void opencwnd() { }
00099 void rtt_update(double tao);
00100 void init_rtt_vars() { srtt_estimate_ = 0.0; }
00101 void rtt_init();
00102 void recv(Packet *);
00103 void send(Packet *, int datalen);
00104
00105 TcpAgent *tcp_;
00106
00107 double xcp_rev_fb_;
00108 double current_positive_feedback_ ;
00109 int tcpId_;
00110 double srtt_estimate_;
00111 long xcp_srtt_;
00112
00113
00114 #define XCP_DELTA_SHIFT 5
00115 #define XCP_EXPO_SHIFT 3
00116 #define XCP_RTT_SHIFT (XCP_DELTA_SHIFT + XCP_EXPO_SHIFT)
00117
00118 #define XCP_INIT_SRTT(rtt) \
00119 ((rtt) << XCP_RTT_SHIFT)
00120
00121 #define XCP_UPDATE_SRTT(srtt, rtt) \
00122 ((srtt) + (((rtt) << XCP_DELTA_SHIFT) \
00123 - (((srtt) + (1 << (XCP_EXPO_SHIFT - 1))) \
00124 >> XCP_EXPO_SHIFT)))
00125 static unsigned int next_xcp_;
00126 };
00127
00128 class XcpNewRenoFullTcpAgent : public NewRenoFullTcpAgent,
00129 public XcpEndsys {
00130 public:
00131 XcpNewRenoFullTcpAgent();
00132
00133 protected:
00134
00135 virtual void delay_bind_init_all();
00136 virtual int delay_bind_dispatch(const char *varName,
00137 const char *localName,
00138 TclObject *tracer);
00139
00140 virtual void opencwnd() { XcpEndsys::opencwnd(); }
00141 virtual void recv(Packet *, Handler *);
00142 virtual void sendpacket(int seq, int ack, int flags, int dlen, int why, Packet *p=0);
00143
00144 virtual void rtt_init();
00145 virtual void rtt_update(double);
00146 };
00147
00148 class XcpRenoTcpAgent : public RenoTcpAgent,
00149 public XcpEndsys {
00150 public:
00151 XcpRenoTcpAgent();
00152 protected:
00153 virtual void delay_bind_init_all();
00154 virtual int delay_bind_dispatch(const char *varName,
00155 const char *localName,
00156 TclObject *tracer);
00157 virtual void output_helper(Packet *);
00158 virtual void recv_newack_helper(Packet *);
00159 virtual void opencwnd() { XcpEndsys::opencwnd(); }
00160 virtual void rtt_init();
00161 virtual void rtt_update(double);
00162 };
00163
00164 class XcpTcpSink : public TcpSink,
00165 public XcpEndsys {
00166 public:
00167 XcpTcpSink(Acker *);
00168 virtual void recv(Packet* pkt, Handler*);
00169 protected:
00170 virtual void add_to_ack(Packet*);
00171 virtual void delay_bind_init_all();
00172 virtual int delay_bind_dispatch(const char *varName,
00173 const char *localName,
00174 TclObject *tracer);
00175 };
00176
00177 #endif