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 #ifndef ns_tcpsink_h
00037 #define ns_tcpsink_h
00038
00039 #include <math.h>
00040 #include "agent.h"
00041 #include "tcp.h"
00042
00043
00044
00045 #define MWS 64
00046 #define MWM (MWS-1)
00047 #define HS_MWS 65536
00048 #define HS_MWM (MWS-1)
00049
00050
00051
00052
00053
00054 class TcpSink;
00055 class Acker {
00056 public:
00057 Acker();
00058 virtual ~Acker() { delete[] seen_; }
00059 void update_ts(int seqno, double ts, int rfc1323 = 0);
00060 int update(int seqno, int numBytes);
00061 void update_ecn_unacked(int value);
00062 inline int Seqno() const { return (next_ - 1); }
00063 virtual void append_ack(hdr_cmn*, hdr_tcp*, int oldSeqno) const;
00064 void reset();
00065 double ts_to_echo() { return ts_to_echo_;}
00066 int ecn_unacked() { return ecn_unacked_;}
00067 inline int Maxseen() const { return (maxseen_); }
00068 void resize_buffers(int sz);
00069
00070 protected:
00071 int next_;
00072 int maxseen_;
00073 int wndmask_;
00074 int ecn_unacked_;
00075
00076 int *seen_;
00077 double ts_to_echo_;
00078 int is_dup_;
00079 public:
00080 int last_ack_sent_;
00081 };
00082
00083
00084 class SackStack;
00085 class Sacker : public Acker, public TclObject {
00086 public:
00087 Sacker() : base_nblocks_(-1), sf_(0) { };
00088 ~Sacker();
00089 void append_ack(hdr_cmn*, hdr_tcp*, int oldSeqno) const;
00090 void reset();
00091 void configure(TcpSink*);
00092 protected:
00093 int base_nblocks_;
00094 int* dsacks_;
00095 SackStack *sf_;
00096 void trace(TracedVar*);
00097 };
00098
00099 class TcpSink : public Agent {
00100 public:
00101 TcpSink(Acker*);
00102 void recv(Packet* pkt, Handler*);
00103 void reset();
00104 int command(int argc, const char*const* argv);
00105 TracedInt& maxsackblocks() { return max_sack_blocks_; }
00106 protected:
00107 void ack(Packet*);
00108 virtual void add_to_ack(Packet* pkt);
00109
00110 virtual void delay_bind_init_all();
00111 virtual int delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer);
00112
00113 Acker* acker_;
00114 int ts_echo_bugfix_;
00115 int ts_echo_rfc1323_;
00116
00117
00118 friend void Sacker::configure(TcpSink*);
00119 TracedInt max_sack_blocks_;
00120 Packet* save_;
00121
00122 int generate_dsacks_;
00123 int qs_enabled_;
00124 int RFC2581_immediate_ack_;
00125 int bytes_;
00126
00127 double lastreset_;
00128
00129 };
00130
00131 class DelAckSink;
00132
00133 class DelayTimer : public TimerHandler {
00134 public:
00135 DelayTimer(DelAckSink *a) : TimerHandler() { a_ = a; }
00136 protected:
00137 virtual void expire(Event *e);
00138 DelAckSink *a_;
00139 };
00140
00141 class DelAckSink : public TcpSink {
00142 public:
00143 DelAckSink(Acker* acker);
00144 void recv(Packet* pkt, Handler*);
00145 virtual void timeout(int tno);
00146 void reset();
00147 protected:
00148 double interval_;
00149 DelayTimer delay_timer_;
00150 };
00151
00152 #endif