|
Lines 285-292
TcpSocketBase::TcpSocketBase (void)
|
Link Here
|
|---|
|
| 285 |
m_highRxAckMark (0), |
285 |
m_highRxAckMark (0), |
| 286 |
m_bytesAckedNotProcessed (0), |
286 |
m_bytesAckedNotProcessed (0), |
| 287 |
m_winScalingEnabled (false), |
287 |
m_winScalingEnabled (false), |
| 288 |
m_sndScaleFactor (0), |
288 |
m_rcvWindShift (0), |
| 289 |
m_rcvScaleFactor (0), |
289 |
m_sndWindShift (0), |
| 290 |
m_timestampEnabled (true), |
290 |
m_timestampEnabled (true), |
| 291 |
m_timestampToEcho (0), |
291 |
m_timestampToEcho (0), |
| 292 |
m_sendPendingDataEvent (), |
292 |
m_sendPendingDataEvent (), |
|
Lines 354-361
TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
|
Link Here
|
|---|
|
| 354 |
m_highRxAckMark (sock.m_highRxAckMark), |
354 |
m_highRxAckMark (sock.m_highRxAckMark), |
| 355 |
m_bytesAckedNotProcessed (sock.m_bytesAckedNotProcessed), |
355 |
m_bytesAckedNotProcessed (sock.m_bytesAckedNotProcessed), |
| 356 |
m_winScalingEnabled (sock.m_winScalingEnabled), |
356 |
m_winScalingEnabled (sock.m_winScalingEnabled), |
| 357 |
m_sndScaleFactor (sock.m_sndScaleFactor), |
357 |
m_rcvWindShift (sock.m_rcvWindShift), |
| 358 |
m_rcvScaleFactor (sock.m_rcvScaleFactor), |
358 |
m_sndWindShift (sock.m_sndWindShift), |
| 359 |
m_timestampEnabled (sock.m_timestampEnabled), |
359 |
m_timestampEnabled (sock.m_timestampEnabled), |
| 360 |
m_timestampToEcho (sock.m_timestampToEcho), |
360 |
m_timestampToEcho (sock.m_timestampToEcho), |
| 361 |
m_recover (sock.m_recover), |
361 |
m_recover (sock.m_recover), |
|
Lines 581-593
TcpSocketBase::Bind (const Address &address)
|
Link Here
|
|---|
|
| 581 |
} |
581 |
} |
| 582 |
|
582 |
|
| 583 |
void |
583 |
void |
| 584 |
TcpSocketBase::InitializeCwnd (void) |
|
|
| 585 |
{ |
| 586 |
m_tcb->m_cWnd = GetInitialCwnd () * GetSegSize (); |
| 587 |
m_tcb->m_ssThresh = GetInitialSSThresh (); |
| 588 |
} |
| 589 |
|
| 590 |
void |
| 591 |
TcpSocketBase::SetInitialSSThresh (uint32_t threshold) |
584 |
TcpSocketBase::SetInitialSSThresh (uint32_t threshold) |
| 592 |
{ |
585 |
{ |
| 593 |
NS_ABORT_MSG_UNLESS ( (m_state == CLOSED) || threshold == m_tcb->m_initialSsThresh, |
586 |
NS_ABORT_MSG_UNLESS ( (m_state == CLOSED) || threshold == m_tcb->m_initialSsThresh, |
|
Lines 617-636
TcpSocketBase::GetInitialCwnd (void) const
|
Link Here
|
|---|
|
| 617 |
return m_tcb->m_initialCWnd; |
610 |
return m_tcb->m_initialCWnd; |
| 618 |
} |
611 |
} |
| 619 |
|
612 |
|
| 620 |
void |
|
|
| 621 |
TcpSocketBase::ScaleSsThresh (uint8_t scaleFactor) |
| 622 |
{ |
| 623 |
m_tcb->m_ssThresh <<= scaleFactor; |
| 624 |
} |
| 625 |
|
| 626 |
/* Inherit from Socket class: Initiate connection to a remote address:port */ |
613 |
/* Inherit from Socket class: Initiate connection to a remote address:port */ |
| 627 |
int |
614 |
int |
| 628 |
TcpSocketBase::Connect (const Address & address) |
615 |
TcpSocketBase::Connect (const Address & address) |
| 629 |
{ |
616 |
{ |
| 630 |
NS_LOG_FUNCTION (this << address); |
617 |
NS_LOG_FUNCTION (this << address); |
| 631 |
|
618 |
|
| 632 |
InitializeCwnd (); |
|
|
| 633 |
|
| 634 |
// If haven't do so, Bind() this socket first |
619 |
// If haven't do so, Bind() this socket first |
| 635 |
if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0) |
620 |
if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0) |
| 636 |
{ |
621 |
{ |
|
Lines 705-712
TcpSocketBase::Listen (void)
|
Link Here
|
|---|
|
| 705 |
{ |
690 |
{ |
| 706 |
NS_LOG_FUNCTION (this); |
691 |
NS_LOG_FUNCTION (this); |
| 707 |
|
692 |
|
| 708 |
InitializeCwnd (); |
|
|
| 709 |
|
| 710 |
// Linux quits EINVAL if we're not in CLOSED state, so match what they do |
693 |
// Linux quits EINVAL if we're not in CLOSED state, so match what they do |
| 711 |
if (m_state != CLOSED) |
694 |
if (m_state != CLOSED) |
| 712 |
{ |
695 |
{ |
|
Lines 1183-1206
TcpSocketBase::DoForwardUp (Ptr<Packet> packet, const Address &fromAddress,
|
Link Here
|
|---|
|
| 1183 |
|
1166 |
|
| 1184 |
ReadOptions (tcpHeader); |
1167 |
ReadOptions (tcpHeader); |
| 1185 |
|
1168 |
|
| 1186 |
if (tcpHeader.GetFlags () & TcpHeader::ACK) |
1169 |
if (tcpHeader.GetFlags () & TcpHeader::SYN) |
| 1187 |
{ |
|
|
| 1188 |
EstimateRtt (tcpHeader); |
| 1189 |
} |
| 1190 |
|
| 1191 |
// Update Rx window size, i.e. the flow control window |
| 1192 |
if (tcpHeader.GetFlags () & TcpHeader::ACK) |
| 1193 |
{ |
| 1194 |
UpdateWindowSize (tcpHeader); |
| 1195 |
} |
| 1196 |
else if (tcpHeader.GetFlags () & TcpHeader::SYN) |
| 1197 |
{ |
1170 |
{ |
| 1198 |
/* The window field in a segment where the SYN bit is set (i.e., a <SYN> |
1171 |
/* The window field in a segment where the SYN bit is set (i.e., a <SYN> |
| 1199 |
* or <SYN,ACK>) MUST NOT be scaled (from RFC 7323 page 9). But should be |
1172 |
* or <SYN,ACK>) MUST NOT be scaled (from RFC 7323 page 9). But should be |
| 1200 |
* saved anyway.. |
1173 |
* saved anyway.. |
| 1201 |
*/ |
1174 |
*/ |
| 1202 |
m_rWnd = tcpHeader.GetWindowSize (); |
1175 |
m_rWnd = tcpHeader.GetWindowSize (); |
|
|
1176 |
|
| 1177 |
if (m_tcb->m_initialSsThresh == UINT32_MAX) |
| 1178 |
{ |
| 1179 |
m_tcb->m_initialSsThresh = m_rWnd << m_sndWindShift; |
| 1180 |
} |
| 1181 |
|
| 1182 |
m_tcb->m_cWnd = GetInitialCwnd () * GetSegSize (); |
| 1183 |
m_tcb->m_ssThresh = GetInitialSSThresh (); |
| 1203 |
} |
1184 |
} |
|
|
1185 |
else if (tcpHeader.GetFlags () & TcpHeader::ACK) |
| 1186 |
{ |
| 1187 |
EstimateRtt (tcpHeader); |
| 1188 |
UpdateWindowSize (tcpHeader); |
| 1189 |
} |
| 1190 |
|
| 1204 |
|
1191 |
|
| 1205 |
if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ()) |
1192 |
if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ()) |
| 1206 |
{ // Zero window: Enter persist state to send 1 byte to probe |
1193 |
{ // Zero window: Enter persist state to send 1 byte to probe |
|
Lines 2548-2554
TcpSocketBase::AdvertisedWindowSize () const
|
Link Here
|
|---|
|
| 2548 |
{ |
2535 |
{ |
| 2549 |
uint32_t w = m_rxBuffer->MaxBufferSize (); |
2536 |
uint32_t w = m_rxBuffer->MaxBufferSize (); |
| 2550 |
|
2537 |
|
| 2551 |
w >>= m_sndScaleFactor; |
2538 |
w >>= m_rcvWindShift; |
| 2552 |
|
2539 |
|
| 2553 |
if (w > m_maxWinSize) |
2540 |
if (w > m_maxWinSize) |
| 2554 |
{ |
2541 |
{ |
|
Lines 3106-3112
TcpSocketBase::ReadOptions (const TcpHeader& header)
|
Link Here
|
|---|
|
| 3106 |
{ |
3093 |
{ |
| 3107 |
m_winScalingEnabled = true; |
3094 |
m_winScalingEnabled = true; |
| 3108 |
ProcessOptionWScale (header.GetOption (TcpOption::WINSCALE)); |
3095 |
ProcessOptionWScale (header.GetOption (TcpOption::WINSCALE)); |
| 3109 |
ScaleSsThresh (m_sndScaleFactor); |
|
|
| 3110 |
} |
3096 |
} |
| 3111 |
} |
3097 |
} |
| 3112 |
} |
3098 |
} |
|
Lines 3147-3162
TcpSocketBase::ProcessOptionWScale (const Ptr<const TcpOption> option)
|
Link Here
|
|---|
|
| 3147 |
|
3133 |
|
| 3148 |
// In naming, we do the contrary of RFC 1323. The received scaling factor |
3134 |
// In naming, we do the contrary of RFC 1323. The received scaling factor |
| 3149 |
// is Rcv.Wind.Scale (and not Snd.Wind.Scale) |
3135 |
// is Rcv.Wind.Scale (and not Snd.Wind.Scale) |
| 3150 |
m_rcvScaleFactor = ws->GetScale (); |
3136 |
m_sndWindShift = ws->GetScale (); |
| 3151 |
|
3137 |
|
| 3152 |
if (m_rcvScaleFactor > 14) |
3138 |
if (m_sndWindShift > 14) |
| 3153 |
{ |
3139 |
{ |
| 3154 |
NS_LOG_WARN ("Possible error; m_rcvScaleFactor exceeds 14: " << m_rcvScaleFactor); |
3140 |
NS_LOG_WARN ("Possible error; m_sndWindShift exceeds 14: " << m_sndWindShift); |
| 3155 |
m_rcvScaleFactor = 14; |
3141 |
m_sndWindShift = 14; |
| 3156 |
} |
3142 |
} |
| 3157 |
|
3143 |
|
| 3158 |
NS_LOG_INFO (m_node->GetId () << " Received a scale factor of " << |
3144 |
NS_LOG_INFO (m_node->GetId () << " Received a scale factor of " << |
| 3159 |
static_cast<int> (m_rcvScaleFactor)); |
3145 |
static_cast<int> (m_sndWindShift)); |
| 3160 |
} |
3146 |
} |
| 3161 |
|
3147 |
|
| 3162 |
uint8_t |
3148 |
uint8_t |
|
Lines 3194-3206
TcpSocketBase::AddOptionWScale (TcpHeader &header)
|
Link Here
|
|---|
|
| 3194 |
// In naming, we do the contrary of RFC 1323. The sended scaling factor |
3180 |
// In naming, we do the contrary of RFC 1323. The sended scaling factor |
| 3195 |
// is Snd.Wind.Scale (and not Rcv.Wind.Scale) |
3181 |
// is Snd.Wind.Scale (and not Rcv.Wind.Scale) |
| 3196 |
|
3182 |
|
| 3197 |
m_sndScaleFactor = CalculateWScale (); |
3183 |
m_rcvWindShift = CalculateWScale (); |
| 3198 |
option->SetScale (m_sndScaleFactor); |
3184 |
option->SetScale (m_rcvWindShift); |
| 3199 |
|
3185 |
|
| 3200 |
header.AppendOption (option); |
3186 |
header.AppendOption (option); |
| 3201 |
|
3187 |
|
| 3202 |
NS_LOG_INFO (m_node->GetId () << " Send a scaling factor of " << |
3188 |
NS_LOG_INFO (m_node->GetId () << " Send a scaling factor of " << |
| 3203 |
static_cast<int> (m_sndScaleFactor)); |
3189 |
static_cast<int> (m_rcvWindShift)); |
| 3204 |
} |
3190 |
} |
| 3205 |
|
3191 |
|
| 3206 |
void |
3192 |
void |
|
Lines 3236-3242
void TcpSocketBase::UpdateWindowSize (const TcpHeader &header)
|
Link Here
|
|---|
|
| 3236 |
// If the connection is not established, the window size is always |
3222 |
// If the connection is not established, the window size is always |
| 3237 |
// updated |
3223 |
// updated |
| 3238 |
uint32_t receivedWindow = header.GetWindowSize (); |
3224 |
uint32_t receivedWindow = header.GetWindowSize (); |
| 3239 |
receivedWindow <<= m_rcvScaleFactor; |
3225 |
receivedWindow <<= m_sndWindShift; |
| 3240 |
NS_LOG_INFO ("Received (scaled) window is " << receivedWindow << " bytes"); |
3226 |
NS_LOG_INFO ("Received (scaled) window is " << receivedWindow << " bytes"); |
| 3241 |
if (m_state < ESTABLISHED) |
3227 |
if (m_state < ESTABLISHED) |
| 3242 |
{ |
3228 |
{ |