www.pudn.com > UDP-based_Reliable_Data_Transfer_Library.zip > udt.h
//
// Author: Yunhong Gu, gu@lac.uic.edu
//
// Descrition: the program is used to simulate UDT on NS-2
//
// Last Update: 03/20/2006
//
#ifndef __NS_UDT_H__
#define __NS_UDT_H__
#include "agent.h"
#include "packet.h"
const int MAX_LOSS_LEN = 300;
struct hdr_udt
{
int flag_;
int seqno_;
int type_;
int losslen_;
int ackseq_;
int ack_;
int recv_;
int rtt_;
int bandwidth_;
int loss_[MAX_LOSS_LEN];
static int off_udt_;
inline static int& offset() { return off_udt_; }
inline static hdr_udt* access(Packet* p) {return (hdr_udt*) p->access(off_udt_);}
int& flag() {return flag_;}
int& seqno() {return seqno_;}
int& type() {return type_;}
int& losslen() {return losslen_;}
int& ackseq() {return ackseq_;}
int& ack() {return ack_;}
int& lrecv() {return recv_;}
int& rtt() {return rtt_;}
int& bandwidth() {return bandwidth_;};
int* loss() {return loss_;}
};
class UdtAgent;
class SndTimer: public TimerHandler
{
public:
SndTimer(UdtAgent *a) : TimerHandler() { a_ = a; }
protected:
virtual void expire(Event *e);
UdtAgent *a_;
};
class SynTimer: public TimerHandler
{
public:
SynTimer(UdtAgent *a) : TimerHandler() { a_ = a; }
protected:
virtual void expire(Event *e);
UdtAgent *a_;
};
class AckTimer: public TimerHandler
{
public:
AckTimer(UdtAgent *a) : TimerHandler() { a_ = a; }
protected:
virtual void expire(Event *e);
UdtAgent *a_;
};
class NakTimer: public TimerHandler
{
public:
NakTimer(UdtAgent *a) : TimerHandler() { a_ = a; }
protected:
virtual void expire(Event *e);
UdtAgent *a_;
};
class ExpTimer: public TimerHandler
{
public:
ExpTimer(UdtAgent *a) : TimerHandler() { a_ = a; }
protected:
virtual void expire(Event *e);
UdtAgent *a_;
};
class LossList
{
protected:
const bool greaterthan(const int& seqno1, const int& seqno2) const;
const bool lessthan(const int& seqno1, const int& seqno2) const;
const bool notlessthan(const int& seqno1, const int& seqno2) const;
const bool notgreaterthan(const int& seqno1, const int& seqno2) const;
const int getLength(const int& seqno1, const int& seqno2) const;
const int incSeqNo(const int& seqno) const;
const int decSeqNo(const int& seqno) const;
protected:
int seq_no_th_; // threshold for comparing seq. no.
int max_seq_no_; // maximum permitted seq. no.
};
////////////////////////////////////////////////////////////////////////////////
class SndLossList: public LossList
{
public:
SndLossList(const int& size, const int& th, const int& max);
~SndLossList();
int insert(const int& seqno1, const int& seqno2);
void remove(const int& seqno);
int getLossLength();
int getLostSeq();
private:
int* data1_; // sequence number starts
int* data2_; // seqnence number ends
int* next_; // next node in the list
int head_; // first node
int length_; // loss length
int size_; // size of the static array
int last_insert_pos_; // position of last insert node
};
////////////////////////////////////////////////////////////////////////////////
class RcvLossList: public LossList
{
public:
RcvLossList(const int& size, const int& th, const int& max);
~RcvLossList();
void insert(const int& seqno1, const int& seqno2);
bool remove(const int& seqno);
int getLossLength() const;
int getFirstLostSeq() const;
void getLossArray(int* array, int* len, const int& limit, const double& interval);
private:
int* data1_; // sequence number starts
int* data2_; // sequence number ends
double* last_feedback_time_; // last feedback time of the node
int* count_; // report counter
int* next_; // next node in the list
int* prior_; // prior node in the list;
int head_; // first node in the list
int tail_; // last node in the list;
int length_; // loss length
int size_; // size of the static array
};
class AckWindow
{
public:
AckWindow();
~AckWindow();
void store(const int& seq, const int& ack);
double acknowledge(const int& seq, int& ack);
private:
int* ack_seqno_;
int* ack_;
double* ts_;
const int size_;
int head_;
int tail_;
};
class TimeWindow
{
public:
TimeWindow();
~TimeWindow();
int getbandwidth() const;
int getpktspeed() const;
bool getdelaytrend() const;
void pktarrival();
void ack2arrival(const double& rtt);
void probe1arrival();
void probe2arrival();
private:
const int size_;
double* pkt_window_;
int pkt_window_ptr_;
double* rtt_window_;
double* pct_window_;
double* pdt_window_;
int rtt_window_ptr_;
double* probe_window_;
int probe_window_ptr_;
double last_arr_time_;
double probe_time_;
double curr_arr_time_;
bool first_round_;
};
class UdtAgent: public Agent
{
friend SndTimer;
friend SynTimer;
friend AckTimer;
friend NakTimer;
friend ExpTimer;
public:
UdtAgent();
~UdtAgent();
int command(int argc, const char*const* argv);
virtual void recv(Packet*, Handler*);
virtual void sendmsg(int nbytes, const char *flags = 0);
protected:
SndTimer snd_timer_;
SynTimer syn_timer_;
AckTimer ack_timer_;
NakTimer nak_timer_;
ExpTimer exp_timer_;
double syn_interval_;
double ack_interval_;
double nak_interval_;
double exp_interval_;
int mtu_;
int max_flow_window_;
int flow_window_size_;
SndLossList* snd_loss_list_;
RcvLossList* rcv_loss_list_;
double snd_interval_;
int bandwidth_;
int nak_count_;
int dec_count_;
volatile int snd_last_ack_;
int local_send_;
int local_loss_;
int local_ack_;
volatile int snd_curr_seqno_;
int curr_max_seqno_;
int dec_random_;
int avg_nak_num_;
double loss_rate_limit_;
double loss_rate_;
AckWindow ack_window_;
TimeWindow time_window_;
double rtt_;
double rcv_interval_;
int rcv_last_ack_;
double rcv_last_ack_time_;
int rcv_last_ack2_;
int ack_seqno_;
volatile int rcv_curr_seqno_;
int local_recv_;
int last_dec_seq_;
double last_delay_time_;
double last_dec_int_;
bool slow_start_;
bool freeze_;
bool firstloss_;
protected:
void rateControl();
void flowControl();
void sendCtrl(int pkttype, int lparam = 0, int* rparam = NULL);
void sendData();
void timeOut();
};
#endif