View | Details | Raw Unified | Return to bug 2141
Collapse All | Expand All

(-)a/src/internet/model/tcp-socket-base.cc (-2 / +2 lines)
 Lines 2430-2438   TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool with Link Here 
2430
    }
2430
    }
2431
2431
2432
  // Notify the application of the data being sent unless this is a retransmit
2432
  // Notify the application of the data being sent unless this is a retransmit
2433
  if (seq == m_highTxMark)
2433
  if (seq + sz > m_highTxMark)
2434
    {
2434
    {
2435
      Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, sz);
2435
      Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, (seq + sz - m_highTxMark.Get ()));
2436
    }
2436
    }
2437
  // Update highTxMark
2437
  // Update highTxMark
2438
  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
2438
  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
(-)a/src/internet/test/tcp-datasentcb-test.cc (+151 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com>
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
 */
19
20
#include "tcp-general-test.h"
21
#include "ns3/node.h"
22
#include "ns3/log.h"
23
24
namespace ns3 {
25
26
NS_LOG_COMPONENT_DEFINE ("TcpDatSentCbTest");
27
28
/**
29
 * \brief Socket that the 50% of the times saves the entire packet in the buffer,
30
 * while in the other 50% saves only half the packet.
31
 */
32
class TcpSocketHalfAck : public TcpSocketMsgBase
33
{
34
public:
35
  static TypeId GetTypeId (void);
36
37
  TcpSocketHalfAck () : TcpSocketMsgBase ()
38
  {
39
  }
40
41
  TcpSocketHalfAck (const TcpSocketHalfAck &other) : TcpSocketMsgBase (other)
42
  {
43
  }
44
protected:
45
  virtual Ptr<TcpSocketBase> Fork ();
46
  virtual void ReceivedData (Ptr<Packet> packet, const TcpHeader& tcpHeader);
47
};
48
49
NS_OBJECT_ENSURE_REGISTERED (TcpSocketHalfAck);
50
51
TypeId
52
TcpSocketHalfAck::GetTypeId (void)
53
{
54
  static TypeId tid = TypeId ("ns3::TcpSocketHalfAck")
55
    .SetParent<TcpSocketMsgBase> ()
56
    .SetGroupName ("Internet")
57
    .AddConstructor<TcpSocketHalfAck> ()
58
  ;
59
  return tid;
60
}
61
62
Ptr<TcpSocketBase>
63
TcpSocketHalfAck::Fork (void)
64
{
65
  return CopyObject<TcpSocketHalfAck> (this);
66
}
67
68
void
69
TcpSocketHalfAck::ReceivedData(Ptr<Packet> packet, const TcpHeader &tcpHeader)
70
{
71
  NS_LOG_FUNCTION (this << packet << tcpHeader);
72
  static uint32_t times = 1;
73
74
  Ptr<Packet> halved = packet->Copy ();
75
76
  if (times % 2 == 0)
77
    halved->RemoveAtEnd (packet->GetSize() / 2);
78
79
  times++;
80
81
  TcpSocketMsgBase::ReceivedData (halved, tcpHeader);
82
}
83
84
85
/**
86
 * \brief Data Sent callback test
87
 *
88
 * The rationale of this test is to check if the dataSent callback advertises
89
 * to the application all the transmitted bytes. We know in advance how many
90
 * bytes are being transmitted, and we check if the amount of data notified
91
 * equals this value.
92
 *
93
 */
94
class TcpDataSentCbTestCase : public TcpGeneralTest
95
{
96
public:
97
  TcpDataSentCbTestCase (const std::string &desc, uint32_t size, uint32_t packets) :
98
    TcpGeneralTest (desc, size, packets),
99
    m_notifiedData (0)
100
  { }
101
102
protected:
103
  virtual Ptr<TcpSocketMsgBase> CreateReceiverSocket (Ptr<Node> node);
104
105
  virtual void DataSent (uint32_t size, SocketWho who);
106
107
  virtual void FinalChecks ();
108
109
private:
110
  uint32_t m_notifiedData;
111
};
112
113
void
114
TcpDataSentCbTestCase::DataSent (uint32_t size, SocketWho who)
115
{
116
  NS_LOG_FUNCTION (this << who << size);
117
118
  m_notifiedData += size;
119
}
120
121
void
122
TcpDataSentCbTestCase::FinalChecks()
123
{
124
  NS_TEST_ASSERT_MSG_EQ (m_notifiedData, GetPktSize () * GetPktCount () ,
125
                         "Notified more data than application sent");
126
}
127
128
Ptr<TcpSocketMsgBase>
129
TcpDataSentCbTestCase::CreateReceiverSocket (Ptr<Node> node)
130
{
131
  NS_LOG_FUNCTION (this);
132
133
  return CreateSocket (node, TcpSocketHalfAck::GetTypeId (), m_congControlTypeId);
134
}
135
136
static class TcpDataSentCbTestSuite : public TestSuite
137
{
138
public:
139
  TcpDataSentCbTestSuite ()
140
    : TestSuite ("tcp-datasentcb", UNIT)
141
  {
142
    AddTestCase (new TcpDataSentCbTestCase ("Check the data sent callback", 500, 10), TestCase::QUICK);
143
    AddTestCase (new TcpDataSentCbTestCase ("Check the data sent callback", 100, 100), TestCase::QUICK);
144
    AddTestCase (new TcpDataSentCbTestCase ("Check the data sent callback", 1000, 50), TestCase::QUICK);
145
    AddTestCase (new TcpDataSentCbTestCase ("Check the data sent callback", 855, 18), TestCase::QUICK);
146
    AddTestCase (new TcpDataSentCbTestCase ("Check the data sent callback", 1243, 59), TestCase::QUICK);
147
  }
148
149
} g_tcpDataSentCbTestSuite;
150
151
} // namespace ns3
(-)a/src/internet/test/tcp-general-test.cc (-1 / +19 lines)
 Lines 180-185   TcpGeneralTest::DoRun (void) Link Here 
180
  m_senderSocket->SetRcvAckCb (MakeCallback (&TcpGeneralTest::RcvAckCb, this));
180
  m_senderSocket->SetRcvAckCb (MakeCallback (&TcpGeneralTest::RcvAckCb, this));
181
  m_senderSocket->SetProcessedAckCb (MakeCallback (&TcpGeneralTest::ProcessedAckCb, this));
181
  m_senderSocket->SetProcessedAckCb (MakeCallback (&TcpGeneralTest::ProcessedAckCb, this));
182
  m_senderSocket->SetRetransmitCb (MakeCallback (&TcpGeneralTest::RtoExpiredCb, this));
182
  m_senderSocket->SetRetransmitCb (MakeCallback (&TcpGeneralTest::RtoExpiredCb, this));
183
  m_senderSocket->SetDataSentCallback(MakeCallback (&TcpGeneralTest::DataSentCb, this));
183
  m_senderSocket->TraceConnectWithoutContext ("CongestionWindow",
184
  m_senderSocket->TraceConnectWithoutContext ("CongestionWindow",
184
                                              MakeCallback (&TcpGeneralTest::CWndTrace, this));
185
                                              MakeCallback (&TcpGeneralTest::CWndTrace, this));
185
  m_senderSocket->TraceConnectWithoutContext ("CongState",
186
  m_senderSocket->TraceConnectWithoutContext ("CongState",
 Lines 241-247   TcpGeneralTest::CreateSocket (Ptr<Node> node, TypeId socketType, Link Here 
241
  socketFactory.SetTypeId (socketType);
242
  socketFactory.SetTypeId (socketType);
242
243
243
  Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator> ();
244
  Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator> ();
244
  Ptr<TcpSocketMsgBase> socket = socketFactory.Create <TcpSocketMsgBase> ();
245
  Ptr<TcpSocketMsgBase> socket = DynamicCast<TcpSocketMsgBase> (socketFactory.Create ());
245
  Ptr<TcpCongestionOps> algo = congestionAlgorithmFactory.Create<TcpCongestionOps> ();
246
  Ptr<TcpCongestionOps> algo = congestionAlgorithmFactory.Create<TcpCongestionOps> ();
246
247
247
  socket->SetNode (node);
248
  socket->SetNode (node);
 Lines 350-355   TcpGeneralTest::RtoExpiredCb (const Ptr<const TcpSocketState> tcb, Link Here 
350
}
351
}
351
352
352
void
353
void
354
TcpGeneralTest::DataSentCb (Ptr<Socket> socket, uint32_t size)
355
{
356
  if (socket->GetNode () == m_receiverSocket->GetNode ())
357
    {
358
      DataSent (size, RECEIVER);
359
    }
360
  else if (socket->GetNode () == m_senderSocket->GetNode ())
361
    {
362
      DataSent (size, SENDER);
363
    }
364
  else
365
    {
366
      NS_FATAL_ERROR ("Closed socket, but not recognized");
367
    }
368
}
369
370
void
353
TcpGeneralTest::ErrorCloseCb (Ptr<Socket> socket)
371
TcpGeneralTest::ErrorCloseCb (Ptr<Socket> socket)
354
{
372
{
355
  if (socket->GetNode () == m_receiverSocket->GetNode ())
373
  if (socket->GetNode () == m_receiverSocket->GetNode ())
(-)a/src/internet/test/tcp-general-test.h (+11 lines)
 Lines 569-574   protected: Link Here 
569
  }
569
  }
570
570
571
  /**
571
  /**
572
   * \brief Notifying application for sent data
573
   *
574
   * \param size the amount of bytes transmitted
575
   * \param who where the RTO has expired (SENDER or RECEIVER)
576
   */
577
  virtual void DataSent (uint32_t size, SocketWho who)
578
  {
579
  }
580
581
  /**
572
   * \brief Performs the (eventual) final checks through test asserts
582
   * \brief Performs the (eventual) final checks through test asserts
573
   *
583
   *
574
   */
584
   */
 Lines 687-692   private: Link Here 
687
                       const Ptr<const TcpSocketBase> tcp);
697
                       const Ptr<const TcpSocketBase> tcp);
688
  void RtoExpiredCb   (const Ptr<const TcpSocketState> tcb,
698
  void RtoExpiredCb   (const Ptr<const TcpSocketState> tcb,
689
                       const Ptr<const TcpSocketBase> tcp);
699
                       const Ptr<const TcpSocketBase> tcp);
700
  void DataSentCb     (Ptr<Socket> socket, uint32_t size);
690
  void ForkCb         (Ptr<TcpSocketMsgBase> tcp);
701
  void ForkCb         (Ptr<TcpSocketMsgBase> tcp);
691
  void HandleAccept (Ptr<Socket> socket, const Address& from);
702
  void HandleAccept (Ptr<Socket> socket, const Address& from);
692
703
(-)a/src/internet/wscript (-1 / +2 lines)
 Lines 248-257   def build(bld): Link Here 
248
        'test/ipv6-fragmentation-test.cc',
248
        'test/ipv6-fragmentation-test.cc',
249
        'test/ipv6-forwarding-test.cc',
249
        'test/ipv6-forwarding-test.cc',
250
        'test/ipv6-ripng-test.cc',
250
        'test/ipv6-ripng-test.cc',
251
     	'test/ipv6-address-helper-test-suite.cc',
251
        'test/ipv6-address-helper-test-suite.cc',
252
        'test/rtt-test.cc',
252
        'test/rtt-test.cc',
253
        'test/codel-queue-test-suite.cc',
253
        'test/codel-queue-test-suite.cc',
254
        'test/tcp-endpoint-bug2211.cc',
254
        'test/tcp-endpoint-bug2211.cc',
255
        'test/tcp-datasentcb-test.cc',
255
        ]
256
        ]
256
    privateheaders = bld(features='ns3privateheader')
257
    privateheaders = bld(features='ns3privateheader')
257
    privateheaders.module = 'internet'
258
    privateheaders.module = 'internet'

Return to bug 2141