/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/*
* Copyright (c) 1991-1997 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/tcp/tcp.h,v 1.113 2003/08/14 04:26:42 sfloyd Exp $ (LBL)
*/
#ifndef ns_tcp_h
#define ns_tcp_h
#include "agent.h"
#include "packet.h"
//class EventTrace;
struct hdr_tcp {
#define NSA 3
double ts_; /* time packet generated (at source) */
double ts_echo_; /* the echoed timestamp (originally sent by
the peer) */
int seqno_; /* sequence number */
int reason_; /* reason for a retransmit */
int sack_area_[NSA+1][2]; /* sack blocks: start, end of block */
int sa_length_; /* Indicate the number of SACKs in this *
* packet. Adds 2+sack_length*8 bytes */
int ackno_; /* ACK number for FullTcp */
int hlen_; /* header len (bytes) for FullTcp */
int tcp_flags_; /* TCP flags for FullTcp */
int last_rtt_; /* more recent RTT measurement in ms, */
/* for statistics only */
static int offset_; // offset for this header
inline static int& offset() { return offset_; }
inline static hdr_tcp* access(Packet* p) {
return (hdr_tcp*) p->access(offset_);
}
/* per-field member functions */
double& ts() { return (ts_); }
double& ts_echo() { return (ts_echo_); }
int& seqno() { return (seqno_); }
int& reason() { return (reason_); }
int& sa_left(int n) { return (sack_area_[n][0]); }
int& sa_right(int n) { return (sack_area_[n][1]); }
int& sa_length() { return (sa_length_); }
int& hlen() { return (hlen_); }
int& ackno() { return (ackno_); }
int& flags() { return (tcp_flags_); }
int& last_rtt() { return (last_rtt_); }
};
/* these are used to mark packets as to why we xmitted them */
#define TCP_REASON_TIMEOUT 0x01
#define TCP_REASON_DUPACK 0x02
#define TCP_REASON_RBP 0x03 // used only in tcp-rbp.cc
#define TCP_REASON_PARTIALACK 0x04
/* these are reasons we adjusted our congestion window */
#define CWND_ACTION_DUPACK 1 // dup acks/fast retransmit
#define CWND_ACTION_TIMEOUT 2 // retransmission timeout
#define CWND_ACTION_ECN 3 // ECN bit [src quench if supported]
#define CWND_ACTION_EXITED 4 // congestion recovery has ended
// (when previously CWND_ACTION_DUPACK)
/* these are bits for how to change the cwnd and ssthresh values */
#define CLOSE_SSTHRESH_HALF 0x00000001
#define CLOSE_CWND_HALF 0x00000002
#define CLOSE_CWND_RESTART 0x00000004
#define CLOSE_CWND_INIT 0x00000008
#define CLOSE_CWND_ONE 0x00000010
#define CLOSE_SSTHRESH_HALVE 0x00000020
#define CLOSE_CWND_HALVE 0x00000040
#define THREE_QUARTER_SSTHRESH 0x00000080
#define CLOSE_CWND_HALF_WAY 0x00000100
#define CWND_HALF_WITH_MIN 0x00000200
/*
* tcp_tick_:
* default 0.1,
* 0.3 for 4.3 BSD,
* 0.01 for new window algorithms,
*/
#define NUMDUPACKS 3 /* This is no longer used. The variable */
/* numdupacks_ is used instead. */
#define TCP_MAXSEQ 1073741824 /* Number that curseq_ is set to for */
/* "infinite send" (2^30) */
#define TCP_TIMER_RTX 0
#define TCP_TIMER_DELSND 1
#define TCP_TIMER_BURSTSND 2
#define TCP_TIMER_DELACK 3
#define TCP_TIMER_Q 4
#define TCP_TIMER_RESET 5
class TcpAgent;
class RtxTimer : public TimerHandler {
public:
RtxTimer(TcpAgent *a) : TimerHandler() { a_ = a; }
protected:
virtual void expire(Event *e);
TcpAgent *a_;
};
class DelSndTimer : public TimerHandler {
public:
DelSndTimer(TcpAgent *a) : TimerHandler() { a_ = a; }
protected:
virtual void expire(Event *e);
TcpAgent *a_;
};
class BurstSndTimer : public TimerHandler {
public:
BurstSndTimer(TcpAgent *a) : TimerHandler() { a_ = a; }
protected:
virtual void expire(Event *e);
TcpAgent *a_;
};
class TcpAgent : public Agent {
public:
TcpAgent();
~TcpAgent() {free(tss);}
virtual void recv(Packet*, Handler*);
virtual void timeout(int tno);
virtual void timeout_nonrtx(int tno);
int command(int argc, const char*const* argv);
virtual void sendmsg(int nbytes, const char *flags = 0);
void trace(TracedVar* v);
virtual void advanceby(int delta);
protected:
virtual int window();
virtual double windowd();
void print_if_needed(double memb_time);
void traceAll();
virtual void traceVar(TracedVar* v);
virtual int headersize(); // a tcp header
virtual void delay_bind_init_all();
virtual int delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer);
/*
* State encompassing the round-trip-time estimate.
* srtt and rttvar are stored as fixed point;
* srtt has 3 bits to the right of the binary point, rttvar has 2.
*/
TracedInt t_seqno_; /* sequence number */
#define T_RTT_BITS 0
TracedInt t_rtt_; /* round trip time */
int T_SRTT_BITS; /* exponent of weight for updating t_srtt_ */
TracedInt t_srtt_; /* smoothed round-trip time */
int srtt_init_; /* initial value for computing t_srtt_ */
int T_RTTVAR_BITS; /* exponent of weight for updating t_rttvar_ */
int rttvar_exp_; /* exponent of multiple for t_rtxcur_ */
TracedInt t_rttvar_; /* variance in round-trip time */
int rttvar_init_; /* initial value for computing t_rttvar_ */
double t_rtxcur_; /* current retransmit value */
double rtxcur_init_; /* initial value for t_rtxcur_ */
TracedInt t_backoff_; /* current multiplier, 1 if not backed off */
virtual void rtt_init();
virtual double rtt_timeout(); /* provide RTO based on RTT estimates */
virtual void rtt_update(double tao); /* update RTT estimate */
virtual void rtt_backoff(); /* double multiplier */
double ts_peer_; /* the most recent timestamp the peer sent */
double ts_echo_; /* the most recent timestamp the peer echoed */
/* connection and packet dynamics */
virtual void output(int seqno, int reason = 0);
virtual void send_much(int force, int reason, int maxburst = 0);
virtual void newtimer(Packet*);
virtual void dupack_action(); /* do this on dupacks */
virtual void send_one(); /* do this on 1-2 dupacks */
double linear(double x, double x_1, double y_1, double x_2, double y_2);
/* the "linear" function is for experimental highspeed TCP */
vo