|
|
| 142 |
"Remote side's flow control window", |
142 |
"Remote side's flow control window", |
| 143 |
MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd), |
143 |
MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd), |
| 144 |
"ns3::TracedValue::Uint32Callback") |
144 |
"ns3::TracedValue::Uint32Callback") |
|
|
145 |
.AddTraceSource ("HighestRxSequence", |
| 146 |
"Highest sequence number received from peer", |
| 147 |
MakeTraceSourceAccessor (&TcpSocketBase::m_highRxMark), |
| 148 |
"ns3::SequenceNumber32TracedValueCallback") |
| 149 |
.AddTraceSource ("HighestRxAck", |
| 150 |
"Highest ack received from peer", |
| 151 |
MakeTraceSourceAccessor (&TcpSocketBase::m_highRxAckMark), |
| 152 |
"ns3::SequenceNumber32TracedValueCallback") |
| 145 |
; |
153 |
; |
| 146 |
return tid; |
154 |
return tid; |
| 147 |
} |
155 |
} |
|
|
| 169 |
m_segmentSize (0), |
177 |
m_segmentSize (0), |
| 170 |
// For attribute initialization consistency (quiet valgrind) |
178 |
// For attribute initialization consistency (quiet valgrind) |
| 171 |
m_rWnd (0), |
179 |
m_rWnd (0), |
|
|
180 |
m_highRxMark (0), |
| 181 |
m_highRxAckMark (0), |
| 172 |
m_sndScaleFactor (0), |
182 |
m_sndScaleFactor (0), |
| 173 |
m_rcvScaleFactor (0), |
183 |
m_rcvScaleFactor (0), |
| 174 |
m_timestampEnabled (true), |
184 |
m_timestampEnabled (true), |
|
|
| 209 |
m_segmentSize (sock.m_segmentSize), |
219 |
m_segmentSize (sock.m_segmentSize), |
| 210 |
m_maxWinSize (sock.m_maxWinSize), |
220 |
m_maxWinSize (sock.m_maxWinSize), |
| 211 |
m_rWnd (sock.m_rWnd), |
221 |
m_rWnd (sock.m_rWnd), |
|
|
222 |
m_highRxMark (sock.m_highRxMark), |
| 223 |
m_highRxAckMark (sock.m_highRxAckMark), |
| 212 |
m_winScalingEnabled (sock.m_winScalingEnabled), |
224 |
m_winScalingEnabled (sock.m_winScalingEnabled), |
| 213 |
m_sndScaleFactor (sock.m_sndScaleFactor), |
225 |
m_sndScaleFactor (sock.m_sndScaleFactor), |
| 214 |
m_rcvScaleFactor (sock.m_rcvScaleFactor), |
226 |
m_rcvScaleFactor (sock.m_rcvScaleFactor), |
|
|
| 942 |
EstimateRtt (tcpHeader); |
954 |
EstimateRtt (tcpHeader); |
| 943 |
} |
955 |
} |
| 944 |
|
956 |
|
| 945 |
// Update Rx window size, i.e. the flow control window |
|
|
| 946 |
if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0) |
| 947 |
{ // persist probes end |
| 948 |
NS_LOG_LOGIC (this << " Leaving zerowindow persist state"); |
| 949 |
m_persistEvent.Cancel (); |
| 950 |
} |
| 951 |
m_rWnd = tcpHeader.GetWindowSize (); |
| 952 |
m_rWnd <<= m_rcvScaleFactor; |
| 953 |
|
| 954 |
// Discard fully out of range data packets |
957 |
// Discard fully out of range data packets |
| 955 |
if (packet->GetSize () |
958 |
if (packet->GetSize () |
| 956 |
&& OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ())) |
959 |
&& OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ())) |
|
|
| 968 |
return; |
971 |
return; |
| 969 |
} |
972 |
} |
| 970 |
|
973 |
|
|
|
974 |
// Update Rx window size, i.e. the flow control window |
| 975 |
if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0 && m_persistEvent.IsRunning ()) |
| 976 |
{ // persist probes end |
| 977 |
NS_LOG_LOGIC (this << " Leaving zerowindow persist state"); |
| 978 |
m_persistEvent.Cancel (); |
| 979 |
} |
| 980 |
if (tcpHeader.GetFlags () & TcpHeader::ACK) |
| 981 |
{ |
| 982 |
UpdateWindowSize (tcpHeader); |
| 983 |
} |
| 984 |
|
| 971 |
// TCP state machine code in different process functions |
985 |
// TCP state machine code in different process functions |
| 972 |
// C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel |
986 |
// C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel |
| 973 |
switch (m_state) |
987 |
switch (m_state) |
|
|
| 1046 |
EstimateRtt (tcpHeader); |
1060 |
EstimateRtt (tcpHeader); |
| 1047 |
} |
1061 |
} |
| 1048 |
|
1062 |
|
| 1049 |
// Update Rx window size, i.e. the flow control window |
|
|
| 1050 |
if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0) |
| 1051 |
{ // persist probes end |
| 1052 |
NS_LOG_LOGIC (this << " Leaving zerowindow persist state"); |
| 1053 |
m_persistEvent.Cancel (); |
| 1054 |
} |
| 1055 |
m_rWnd = tcpHeader.GetWindowSize (); |
| 1056 |
m_rWnd <<= m_rcvScaleFactor; |
| 1057 |
|
| 1058 |
// Discard fully out of range packets |
1063 |
// Discard fully out of range packets |
| 1059 |
if (packet->GetSize () |
1064 |
if (packet->GetSize () |
| 1060 |
&& OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ())) |
1065 |
&& OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ())) |
|
|
| 1072 |
return; |
1077 |
return; |
| 1073 |
} |
1078 |
} |
| 1074 |
|
1079 |
|
|
|
1080 |
// Update Rx window size, i.e. the flow control window |
| 1081 |
if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0 && m_persistEvent.IsRunning ()) |
| 1082 |
{ // persist probes end |
| 1083 |
NS_LOG_LOGIC (this << " Leaving zerowindow persist state"); |
| 1084 |
m_persistEvent.Cancel (); |
| 1085 |
} |
| 1086 |
|
| 1087 |
if (tcpHeader.GetFlags () & TcpHeader::ACK) |
| 1088 |
{ |
| 1089 |
UpdateWindowSize (tcpHeader); |
| 1090 |
} |
| 1091 |
|
| 1075 |
// TCP state machine code in different process functions |
1092 |
// TCP state machine code in different process functions |
| 1076 |
// C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel |
1093 |
// C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel |
| 1077 |
switch (m_state) |
1094 |
switch (m_state) |
|
|
| 2727 |
option->GetTimestamp () << " echo=" << m_timestampToEcho); |
2744 |
option->GetTimestamp () << " echo=" << m_timestampToEcho); |
| 2728 |
} |
2745 |
} |
| 2729 |
|
2746 |
|
|
|
2747 |
void TcpSocketBase::UpdateWindowSize (const TcpHeader &header) |
| 2748 |
{ |
| 2749 |
NS_LOG_FUNCTION (this << header); |
| 2750 |
// If the connection is not established, the window size is always |
| 2751 |
// updated |
| 2752 |
uint32_t receivedWindow = header.GetWindowSize (); |
| 2753 |
receivedWindow <<= m_rcvScaleFactor; |
| 2754 |
NS_LOG_DEBUG ("Received (scaled) window is " << receivedWindow << " bytes"); |
| 2755 |
if (m_state < ESTABLISHED) |
| 2756 |
{ |
| 2757 |
m_rWnd = receivedWindow; |
| 2758 |
NS_LOG_DEBUG ("State less than ESTABLISHED; updating rWnd to " << m_rWnd); |
| 2759 |
return; |
| 2760 |
} |
| 2761 |
|
| 2762 |
// Test for conditions that allow updating of the window |
| 2763 |
// 1) segment contains new data (advancing the right edge of the receive |
| 2764 |
// buffer), |
| 2765 |
// 2) segment does not contain new data but the segment acks new data |
| 2766 |
// (highest sequence number acked advances), or |
| 2767 |
// 3) the advertised window is larger than the current send window |
| 2768 |
bool update = false; |
| 2769 |
if (header.GetAckNumber () == m_highRxAckMark && receivedWindow > m_rWnd) |
| 2770 |
{ |
| 2771 |
// right edge of the send window is increased (window update) |
| 2772 |
update = true; |
| 2773 |
} |
| 2774 |
if (header.GetAckNumber () > m_highRxAckMark) |
| 2775 |
{ |
| 2776 |
m_highRxAckMark = header.GetAckNumber (); |
| 2777 |
update = true; |
| 2778 |
} |
| 2779 |
if (header.GetSequenceNumber () > m_highRxMark) |
| 2780 |
{ |
| 2781 |
m_highRxMark = header.GetSequenceNumber (); |
| 2782 |
update = true; |
| 2783 |
} |
| 2784 |
if (update == true) |
| 2785 |
{ |
| 2786 |
m_rWnd = receivedWindow; |
| 2787 |
NS_LOG_DEBUG ("updating rWnd to " << m_rWnd); |
| 2788 |
} |
| 2789 |
} |
| 2790 |
|
| 2730 |
void |
2791 |
void |
| 2731 |
TcpSocketBase::SetMinRto (Time minRto) |
2792 |
TcpSocketBase::SetMinRto (Time minRto) |
| 2732 |
{ |
2793 |
{ |