|
Lines 1170-1180
TcpSocketBase::DoForwardUp (Ptr<Packet> packet, const Address &fromAddress,
|
Link Here
|
|---|
|
| 1170 |
} |
1170 |
} |
| 1171 |
|
1171 |
|
| 1172 |
// Update Rx window size, i.e. the flow control window |
1172 |
// Update Rx window size, i.e. the flow control window |
| 1173 |
if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0 && m_persistEvent.IsRunning ()) |
|
|
| 1174 |
{ // persist probes end |
| 1175 |
NS_LOG_LOGIC (this << " Leaving zerowindow persist state"); |
| 1176 |
m_persistEvent.Cancel (); |
| 1177 |
} |
| 1178 |
if (tcpHeader.GetFlags () & TcpHeader::ACK) |
1173 |
if (tcpHeader.GetFlags () & TcpHeader::ACK) |
| 1179 |
{ |
1174 |
{ |
| 1180 |
UpdateWindowSize (tcpHeader); |
1175 |
UpdateWindowSize (tcpHeader); |
|
Lines 1188-1193
TcpSocketBase::DoForwardUp (Ptr<Packet> packet, const Address &fromAddress,
|
Link Here
|
|---|
|
| 1188 |
m_rWnd = tcpHeader.GetWindowSize (); |
1183 |
m_rWnd = tcpHeader.GetWindowSize (); |
| 1189 |
} |
1184 |
} |
| 1190 |
|
1185 |
|
|
|
1186 |
if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ()) |
| 1187 |
{ // Zero window: Enter persist state to send 1 byte to probe |
| 1188 |
NS_LOG_LOGIC (this << " Enter zerowindow persist state"); |
| 1189 |
NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " << |
| 1190 |
(Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ()); |
| 1191 |
m_retxEvent.Cancel (); |
| 1192 |
NS_LOG_LOGIC ("Schedule persist timeout at time " << |
| 1193 |
Simulator::Now ().GetSeconds () << " to expire at time " << |
| 1194 |
(Simulator::Now () + m_persistTimeout).GetSeconds ()); |
| 1195 |
m_persistEvent = Simulator::Schedule (m_persistTimeout, &TcpSocketBase::PersistTimeout, this); |
| 1196 |
NS_ASSERT (m_persistTimeout == Simulator::GetDelayLeft (m_persistEvent)); |
| 1197 |
} |
| 1198 |
|
| 1191 |
// TCP state machine code in different process functions |
1199 |
// TCP state machine code in different process functions |
| 1192 |
// C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel |
1200 |
// C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel |
| 1193 |
switch (m_state) |
1201 |
switch (m_state) |
|
Lines 1238-1243
TcpSocketBase::DoForwardUp (Ptr<Packet> packet, const Address &fromAddress,
|
Link Here
|
|---|
|
| 1238 |
default: // mute compiler |
1246 |
default: // mute compiler |
| 1239 |
break; |
1247 |
break; |
| 1240 |
} |
1248 |
} |
|
|
1249 |
|
| 1250 |
if (m_rWnd.Get () != 0 && m_persistEvent.IsRunning ()) |
| 1251 |
{ // persist probes end, the other end has increased the window |
| 1252 |
NS_ASSERT (m_connected); |
| 1253 |
NS_LOG_LOGIC (this << " Leaving zerowindow persist state"); |
| 1254 |
m_persistEvent.Cancel (); |
| 1255 |
|
| 1256 |
// Try to send more data, since window has been updated |
| 1257 |
if (!m_sendPendingDataEvent.IsRunning ()) |
| 1258 |
{ |
| 1259 |
m_sendPendingDataEvent = Simulator::Schedule (TimeStep (1), |
| 1260 |
&TcpSocketBase::SendPendingData, |
| 1261 |
this, m_connected); |
| 1262 |
} |
| 1263 |
} |
| 1241 |
} |
1264 |
} |
| 1242 |
|
1265 |
|
| 1243 |
/* Received a packet upon ESTABLISHED state. This function is mimicking the |
1266 |
/* Received a packet upon ESTABLISHED state. This function is mimicking the |
|
Lines 2711-2728
TcpSocketBase::NewAck (SequenceNumber32 const& ack)
|
Link Here
|
|---|
|
| 2711 |
(Simulator::Now () + m_rto.Get ()).GetSeconds ()); |
2734 |
(Simulator::Now () + m_rto.Get ()).GetSeconds ()); |
| 2712 |
m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this); |
2735 |
m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this); |
| 2713 |
} |
2736 |
} |
| 2714 |
if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ()) |
2737 |
|
| 2715 |
{ // Zero window: Enter persist state to send 1 byte to probe |
|
|
| 2716 |
NS_LOG_LOGIC (this << "Enter zerowindow persist state"); |
| 2717 |
NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " << |
| 2718 |
(Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ()); |
| 2719 |
m_retxEvent.Cancel (); |
| 2720 |
NS_LOG_LOGIC ("Schedule persist timeout at time " << |
| 2721 |
Simulator::Now ().GetSeconds () << " to expire at time " << |
| 2722 |
(Simulator::Now () + m_persistTimeout).GetSeconds ()); |
| 2723 |
m_persistEvent = Simulator::Schedule (m_persistTimeout, &TcpSocketBase::PersistTimeout, this); |
| 2724 |
NS_ASSERT (m_persistTimeout == Simulator::GetDelayLeft (m_persistEvent)); |
| 2725 |
} |
| 2726 |
// Note the highest ACK and tell app to send more |
2738 |
// Note the highest ACK and tell app to send more |
| 2727 |
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
2739 |
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
| 2728 |
" numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed |
2740 |
" numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed |