A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
tcp-tahoe.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2010 Adrian Sai-wah Tam
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation;
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
*
18
* Author: Adrian Sai-wah Tam <adrian.sw.tam@gmail.com>
19
*/
20
21
#define NS_LOG_APPEND_CONTEXT \
22
if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
23
24
#include "
tcp-tahoe.h
"
25
#include "ns3/log.h"
26
#include "ns3/trace-source-accessor.h"
27
#include "ns3/simulator.h"
28
#include "ns3/abort.h"
29
#include "ns3/node.h"
30
31
NS_LOG_COMPONENT_DEFINE
(
"TcpTahoe"
);
32
33
namespace
ns3 {
34
35
NS_OBJECT_ENSURE_REGISTERED
(TcpTahoe);
36
37
TypeId
38
TcpTahoe::GetTypeId
(
void
)
39
{
40
static
TypeId
tid =
TypeId
(
"ns3::TcpTahoe"
)
41
.
SetParent
<
TcpSocketBase
> ()
42
.AddConstructor<TcpTahoe> ()
43
.AddAttribute (
"ReTxThreshold"
,
"Threshold for fast retransmit"
,
44
UintegerValue
(3),
45
MakeUintegerAccessor (&
TcpTahoe::m_retxThresh
),
46
MakeUintegerChecker<uint32_t> ())
47
.AddTraceSource (
"CongestionWindow"
,
48
"The TCP connection's congestion window"
,
49
MakeTraceSourceAccessor
(&
TcpTahoe::m_cWnd
))
50
;
51
return
tid;
52
}
53
54
TcpTahoe::TcpTahoe
(
void
) : m_initialCWnd (1), m_retxThresh (3)
55
{
56
NS_LOG_FUNCTION
(
this
);
57
}
58
59
TcpTahoe::TcpTahoe
(
const
TcpTahoe
& sock)
60
:
TcpSocketBase
(sock),
61
m_cWnd (sock.m_cWnd),
62
m_ssThresh (sock.m_ssThresh),
63
m_initialCWnd (sock.m_initialCWnd),
64
m_retxThresh (sock.m_retxThresh)
65
{
66
NS_LOG_FUNCTION
(
this
);
67
NS_LOG_LOGIC
(
"Invoked the copy constructor"
);
68
}
69
70
TcpTahoe::~TcpTahoe
(
void
)
71
{
72
}
73
75
int
76
TcpTahoe::Listen
(
void
)
77
{
78
NS_LOG_FUNCTION
(
this
);
79
InitializeCwnd
();
80
return
TcpSocketBase::Listen
();
81
}
82
84
int
85
TcpTahoe::Connect
(
const
Address
& address)
86
{
87
NS_LOG_FUNCTION
(
this
<< address);
88
InitializeCwnd
();
89
return
TcpSocketBase::Connect
(address);
90
}
91
93
uint32_t
94
TcpTahoe::Window
(
void
)
95
{
96
NS_LOG_FUNCTION
(
this
);
97
return
std::min (
m_rWnd
.
Get
(),
m_cWnd
.
Get
());
98
}
99
100
Ptr<TcpSocketBase>
101
TcpTahoe::Fork
(
void
)
102
{
103
return
CopyObject<TcpTahoe> (
this
);
104
}
105
107
void
108
TcpTahoe::NewAck
(
SequenceNumber32
const
& seq)
109
{
110
NS_LOG_FUNCTION
(
this
<< seq);
111
NS_LOG_LOGIC
(
"TcpTahoe receieved ACK for seq "
<< seq <<
112
" cwnd "
<<
m_cWnd
<<
113
" ssthresh "
<<
m_ssThresh
);
114
if
(
m_cWnd
<
m_ssThresh
)
115
{
// Slow start mode, add one segSize to cWnd. Default m_ssThresh is 65535. (RFC2001, sec.1)
116
m_cWnd
+=
m_segmentSize
;
117
NS_LOG_INFO
(
"In SlowStart, updated to cwnd "
<<
m_cWnd
<<
" ssthresh "
<<
m_ssThresh
);
118
}
119
else
120
{
// Congestion avoidance mode, increase by (segSize*segSize)/cwnd. (RFC2581, sec.3.1)
121
// To increase cwnd for one segSize per RTT, it should be (ackBytes*segSize)/cwnd
122
double
adder =
static_cast<
double
>
(
m_segmentSize
*
m_segmentSize
) /
m_cWnd
.
Get
();
123
adder = std::max (1.0, adder);
124
m_cWnd
+=
static_cast<
uint32_t
>
(adder);
125
NS_LOG_INFO
(
"In CongAvoid, updated to cwnd "
<<
m_cWnd
<<
" ssthresh "
<<
m_ssThresh
);
126
}
127
TcpSocketBase::NewAck
(seq);
// Complete newAck processing
128
}
129
131
void
132
TcpTahoe::DupAck
(
const
TcpHeader
& t, uint32_t count)
133
{
134
NS_LOG_FUNCTION
(
this
<<
"t "
<< count);
135
if
(count ==
m_retxThresh
)
136
{
// triple duplicate ack triggers fast retransmit (RFC2001, sec.3)
137
NS_LOG_INFO
(
"Triple Dup Ack: old ssthresh "
<<
m_ssThresh
<<
" cwnd "
<<
m_cWnd
);
138
// fast retransmit in Tahoe means triggering RTO earlier. Tx is restarted
139
// from the highest ack and run slow start again.
140
// (Fall & Floyd 1996, sec.1)
141
m_ssThresh
= std::max (static_cast<unsigned> (
m_cWnd
/ 2),
m_segmentSize
* 2);
// Half ssthresh
142
m_cWnd
=
m_segmentSize
;
// Run slow start again
143
m_nextTxSequence
=
m_txBuffer
.
HeadSequence
();
// Restart from highest Ack
144
NS_LOG_INFO
(
"Triple Dup Ack: new ssthresh "
<<
m_ssThresh
<<
" cwnd "
<<
m_cWnd
);
145
NS_LOG_LOGIC
(
"Triple Dup Ack: retransmit missing segment at "
<<
Simulator::Now
().GetSeconds ());
146
DoRetransmit
();
147
}
148
}
149
151
void
TcpTahoe::Retransmit
(
void
)
152
{
153
NS_LOG_FUNCTION
(
this
);
154
NS_LOG_LOGIC
(
this
<<
" ReTxTimeout Expired at time "
<<
Simulator::Now
().GetSeconds ());
155
// If erroneous timeout in closed/timed-wait state, just return
156
if
(
m_state
==
CLOSED
||
m_state
==
TIME_WAIT
)
return
;
157
// If all data are received (non-closing socket and nothing to send), just return
158
if
(
m_state
<=
ESTABLISHED
&&
m_txBuffer
.
HeadSequence
() >=
m_highTxMark
)
return
;
159
160
m_ssThresh
= std::max (static_cast<unsigned> (
m_cWnd
/ 2),
m_segmentSize
* 2);
// Half ssthresh
161
m_cWnd
=
m_segmentSize
;
// Set cwnd to 1 segSize (RFC2001, sec.2)
162
m_nextTxSequence
=
m_txBuffer
.
HeadSequence
();
// Restart from highest Ack
163
m_rtt
->
IncreaseMultiplier
();
// Double the next RTO
164
DoRetransmit
();
// Retransmit the packet
165
}
166
167
void
168
TcpTahoe::SetSegSize
(uint32_t size)
169
{
170
NS_ABORT_MSG_UNLESS
(
m_state
==
CLOSED
,
"TcpTahoe::SetSegSize() cannot change segment size after connection started."
);
171
m_segmentSize
= size;
172
}
173
174
void
175
TcpTahoe::SetSSThresh
(uint32_t threshold)
176
{
177
m_ssThresh
= threshold;
178
}
179
180
uint32_t
181
TcpTahoe::GetSSThresh
(
void
)
const
182
{
183
return
m_ssThresh
;
184
}
185
186
void
187
TcpTahoe::SetInitialCwnd
(uint32_t cwnd)
188
{
189
NS_ABORT_MSG_UNLESS
(
m_state
==
CLOSED
,
"TcpTahoe::SetInitialCwnd() cannot change initial cwnd after connection started."
);
190
m_initialCWnd
= cwnd;
191
}
192
193
uint32_t
194
TcpTahoe::GetInitialCwnd
(
void
)
const
195
{
196
return
m_initialCWnd
;
197
}
198
199
void
200
TcpTahoe::InitializeCwnd
(
void
)
201
{
202
/*
203
* Initialize congestion window, default to 1 MSS (RFC2001, sec.1) and must
204
* not be larger than 2 MSS (RFC2581, sec.3.1). Both m_initiaCWnd and
205
* m_segmentSize are set by the attribute system in ns3::TcpSocket.
206
*/
207
m_cWnd
=
m_initialCWnd
*
m_segmentSize
;
208
}
209
210
}
// namespace ns3
src
internet
model
tcp-tahoe.cc
Generated on Tue Oct 9 2012 16:45:39 for ns-3 by
1.8.1.2