122 m_initialCWnd (sock.m_initialCWnd), |
123 m_initialCWnd (sock.m_initialCWnd), |
123 m_rtt (0), |
124 m_rtt (0), |
124 m_lastMeasuredRtt (Seconds(0.0)), |
125 m_lastMeasuredRtt (Seconds(0.0)), |
125 m_cnTimeout (sock.m_cnTimeout), |
126 m_cnTimeout (sock.m_cnTimeout), |
126 m_cnCount (sock.m_cnCount), |
127 m_cnCount (sock.m_cnCount), |
127 m_rxAvailable (0) |
128 m_rxAvailable (0), |
|
129 m_maxTxBuffer (0) //interpret 0 as no limit, //XXX hook into default values |
128 { |
130 { |
129 NS_LOG_FUNCTION_NOARGS (); |
131 NS_LOG_FUNCTION_NOARGS (); |
130 NS_LOG_LOGIC("Invoked the copy constructor"); |
132 NS_LOG_LOGIC("Invoked the copy constructor"); |
131 //copy the pending data if necessary |
133 //copy the pending data if necessary |
132 if(sock.m_pendingData) |
134 if(sock.m_pendingData) |
359 int TcpSocket::Send (const uint8_t* buf, uint32_t size) |
361 int TcpSocket::Send (const uint8_t* buf, uint32_t size) |
360 { |
362 { |
361 NS_LOG_FUNCTION (this << buf << size); |
363 NS_LOG_FUNCTION (this << buf << size); |
362 if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT) |
364 if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT) |
363 { // Ok to buffer some data to send |
365 { // Ok to buffer some data to send |
|
366 size = std::min(size, GetTxAvailable() ); //only buffer what can fit |
364 if (!m_pendingData) |
367 if (!m_pendingData) |
365 { |
368 { |
366 m_pendingData = new PendingData (); // Create if non-existent |
369 m_pendingData = new PendingData (); // Create if non-existent |
367 m_firstPendingSequence = m_nextTxSequence; // Note seq of first |
370 m_firstPendingSequence = m_nextTxSequence; // Note seq of first |
368 } |
371 } |
369 //PendingData::Add always copies the data buffer, never modifies |
372 //PendingData::Add always copies the data buffer, never modifies |
370 m_pendingData->Add (size,buf); |
373 m_pendingData->Add (size,buf); |
371 NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() << |
374 NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() << |
372 " state " << m_state); |
375 " state " << m_state); |
373 Actions_t action = ProcessEvent (APP_SEND); |
376 Actions_t action = ProcessEvent (APP_SEND); |
374 NS_LOG_DEBUG(" action " << action); |
377 NS_LOG_DEBUG(" action " << action); |
375 // We do not model any limit to the buffer, so report that the |
378 NotifySend (GetTxAvailable ()); |
376 // maximum is available |
|
377 NotifySend (std::numeric_limits<uint32_t>::max ()); |
|
378 if (!ProcessAction (action)) |
379 if (!ProcessAction (action)) |
379 { |
380 { |
380 return -1; // Failed, return zero |
381 return -1; // Failed, return zero |
381 } |
382 } |
382 return size; |
383 return size; |
437 |
438 |
438 // XXX Raj to make this functional |
439 // XXX Raj to make this functional |
439 uint32_t |
440 uint32_t |
440 TcpSocket::GetTxAvailable (void) const |
441 TcpSocket::GetTxAvailable (void) const |
441 { |
442 { |
442 // No finite send buffer is modelled |
443 if (m_maxTxBuffer == 0) //interpret this as infinite buffer |
443 return 0xffffffff; |
444 { |
|
445 return std::numeric_limits<uint32_t>::max (); |
|
446 } |
|
447 if (m_pendingData != 0) |
|
448 { |
|
449 NS_ASSERT (m_maxTxBuffer >= m_pendingData->Size()); //else a logical error |
|
450 return m_maxTxBuffer-m_pendingData->Size(); |
|
451 } |
|
452 else |
|
453 { |
|
454 return m_maxTxBuffer; |
|
455 } |
444 } |
456 } |
445 |
457 |
446 int |
458 int |
447 TcpSocket::Listen (uint32_t q) |
459 TcpSocket::Listen (uint32_t q) |
448 { |
460 { |