Added in ns-3-tcp (second try)

This commit is contained in:
Raj Bhattacharjea
2008-01-25 13:57:38 -05:00
parent 6292ead1f7
commit 6c3559792c
30 changed files with 4487 additions and 0 deletions

View File

@@ -0,0 +1,240 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
//
// Network topology
//
// 10Mb/s, 10ms 10Mb/s, 10ms
// n0-----------------n1-----------------n2
//
//
// - Tracing of queues and packet receptions to file
// "tcp-large-transfer-errors.tr"
// - pcap traces also generated in the following files
// "tcp-large-transfer-errors.pcap-$n-$i" where n and i represent node and interface numbers respectively
// Usage (e.g.): ./waf --run tcp-large-transfer-errors
#include <ctype.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include "ns3/command-line.h"
#include "ns3/default-value.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
#include "ns3/ascii-trace.h"
#include "ns3/pcap-trace.h"
#include "ns3/internet-node.h"
#include "ns3/point-to-point-channel.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/ipv4-address.h"
#include "ns3/inet-socket-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
#include "ns3/packet-sink.h"
#include "ns3/error-model.h"
#include "ns3/node-list.h"
#include "ns3/tcp.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TcpLargeTransferErrors");
void
ApplicationTraceSink (const TraceContext &context, Ptr<const Packet> packet,
const Address &addr)
{
if (!g_log.IsNoneEnabled ()) {
if (InetSocketAddress::IsMatchingType (addr) )
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (addr);
std::cout << "PacketSink received size " <<
packet->GetSize () << " at time " <<
Simulator::Now ().GetSeconds () << " from address: " <<
address.GetIpv4 () << std::endl;
char buf[2000];
memcpy(buf, packet->PeekData (), packet->GetSize ());
for (uint32_t i=0; i < packet->GetSize (); i++)
{
std::cout << buf[i];
if (i && i % 60 == 0)
std::cout << std::endl;
}
std::cout << std::endl << std::endl;
}
}
}
void CloseConnection (Ptr<Socket> localSocket)
{
//localSocket->Close ();
}
void StartFlow(Ptr<Socket> localSocket, uint32_t nBytes,
uint16_t servPort)
{
// NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ());
localSocket->Connect (InetSocketAddress ("10.1.2.2", servPort));//connect
localSocket->SetConnectCallback (MakeCallback (&CloseConnection),
Callback<void, Ptr<Socket> > (),
Callback<void, Ptr<Socket> > ());
//we want to close as soon as the connection is established
//the tcp state machine and outgoing buffer will assure that
//all of the data is delivered
// Perform series of 1040 byte writes (this is a multiple of 26 since
// we want to detect data splicing in the output stream)
uint32_t writeSize = 1040;
uint8_t data[writeSize];
while (nBytes > 0) {
uint32_t curSize= nBytes > writeSize ? writeSize : nBytes;
for(uint32_t i = 0; i < curSize; ++i)
{
char m = toascii (97 + i % 26);
data[i] = m;
}
localSocket->Send (data, curSize);
nBytes -= curSize;
}
}
int main (int argc, char *argv[])
{
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
// LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
// LogComponentEnable("TcpSocket", LOG_LEVEL_ALL);
// LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
//LogComponentEnable("TcpLargeTransferErrors", LOG_LEVEL_ALL);
// Allow the user to override any of the defaults and the above
// Bind()s at run-time, via command-line arguments
CommandLine::Parse (argc, argv);
// Here, we will explicitly create three nodes. In more sophisticated
// topologies, we could configure a node factory.
Ptr<Node> n0 = Create<InternetNode> ();
Ptr<Node> n1 = Create<InternetNode> ();
Ptr<Node> n2 = Create<InternetNode> ();
// We create the channels first without any IP addressing information
Ptr<PointToPointChannel> channel0 =
PointToPointTopology::AddPointToPointLink (
n0, n1, DataRate(10000000), MilliSeconds(10));
// Later, we add IP addresses.
PointToPointTopology::AddIpv4Addresses (
channel0, n0, Ipv4Address("10.1.3.1"),
n1, Ipv4Address("10.1.3.2"));
Ptr<PointToPointChannel> channel1 =
PointToPointTopology::AddPointToPointLink (
n1, n2, DataRate(10000000), MilliSeconds(10));
PointToPointTopology::AddIpv4Addresses (
channel1, n1, Ipv4Address("10.1.2.1"),
n2, Ipv4Address("10.1.2.2"));
// Finally, we add static routes. These three steps (Channel and
// NetDevice creation, IP Address assignment, and routing) are
// separated because there may be a need to postpone IP Address
// assignment (emulation) or modify to use dynamic routing
PointToPointTopology::AddIpv4Routes(n0, n1, channel0);
PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
Ptr<Ipv4> ipv4;
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.2"), 1);
ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.2.1"), 1);
///////////////////////////////////////////////////////////////////////////
// Simulation 1
//
// Send 2000000 bytes over a connection to server port 50000 at time 0
// Should observe SYN exchange, a lot of data segments, and FIN exchange
//
///////////////////////////////////////////////////////////////////////////
int nBytes = 2000000;
uint16_t servPort = 50000;
Ptr<SocketFactory> socketFactory =
n0->QueryInterface<SocketFactory> (Tcp::iid);
Ptr<Socket> localSocket = socketFactory->CreateSocket ();
localSocket->Bind ();
// Create a packet sink to receive these packets
Ptr<PacketSink> sink = Create<PacketSink> (
n2,
InetSocketAddress (Ipv4Address::GetAny (), servPort),
"Tcp");
sink->Start (Seconds (0.0));
sink->Stop (Seconds (10000.0));
//
// Error models
//
// We want to add an error model to node 2's NetDevice
// We can obtain a handle to the NetDevice via the channel and node
// pointers
Ptr<PointToPointNetDevice> nd2 = PointToPointTopology::GetNetDevice
(n2, channel1);
Ptr<RateErrorModel> rem = Create<RateErrorModel> ();
// The first data segment for this flow is packet uid=4
rem->SetRandomVariable (UniformVariable ());
rem->SetUnit (EU_PKT);
rem->SetRate (0.05);
nd2->AddReceiveErrorModel (rem);
Simulator::Schedule(Seconds(0), &StartFlow, localSocket, nBytes,
servPort);
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-examples.tr file
AsciiTrace asciitrace ("tcp-large-transfer-errors.tr");
asciitrace.TraceAllQueues ();
asciitrace.TraceAllNetDeviceRx ();
// Also configure some tcpdump traces; each interface will be traced
// The output files will be named
// simple-examples.pcap-<nodeId>-<interfaceId>
// and can be read by the "tcpdump -r" command (use "-tt" option to
// display timestamps correctly)
PcapTrace pcaptrace ("tcp-large-transfer-errors.pcap");
pcaptrace.TraceAllIp ();
NodeList::Connect ("/nodes/*/applications/*/rx", MakeCallback (&ApplicationTraceSink));
Simulator::StopAt (Seconds(10000));
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -0,0 +1,225 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
//
// Network topology
//
// 10Mb/s, 10ms 10Mb/s, 10ms
// n0-----------------n1-----------------n2
//
//
// - Tracing of queues and packet receptions to file
// "tcp-large-transfer.tr"
// - pcap traces also generated in the following files
// "tcp-large-transfer.pcap-$n-$i" where n and i represent node and interface numbers respectively
// Usage (e.g.): ./waf --run tcp-large-transfer
#include <ctype.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include "ns3/command-line.h"
#include "ns3/default-value.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
#include "ns3/ascii-trace.h"
#include "ns3/pcap-trace.h"
#include "ns3/internet-node.h"
#include "ns3/point-to-point-channel.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/ipv4-address.h"
#include "ns3/inet-socket-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
#include "ns3/packet-sink.h"
#include "ns3/error-model.h"
#include "ns3/node-list.h"
#include "ns3/tcp.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TcpLargeTransfer");
void
ApplicationTraceSink (const TraceContext &context, Ptr<const Packet> packet,
const Address &addr)
{
if (!g_log.IsNoneEnabled ()) {
if (InetSocketAddress::IsMatchingType (addr) )
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (addr);
std::cout << "PacketSink received size " <<
packet->GetSize () << " at time " <<
Simulator::Now ().GetSeconds () << " from address: " <<
address.GetIpv4 () << std::endl;
char buf[2000];
memcpy(buf, packet->PeekData (), packet->GetSize ());
for (uint32_t i=0; i < packet->GetSize (); i++)
{
std::cout << buf[i];
if (i && i % 60 == 0)
std::cout << std::endl;
}
std::cout << std::endl << std::endl;
}
}
}
void CloseConnection (Ptr<Socket> localSocket)
{
//localSocket->Close ();
}
void StartFlow(Ptr<Socket> localSocket, uint32_t nBytes,
uint16_t servPort)
{
// NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ());
localSocket->Connect (InetSocketAddress ("10.1.2.2", servPort));//connect
localSocket->SetConnectCallback (MakeCallback (&CloseConnection),
Callback<void, Ptr<Socket> > (),
Callback<void, Ptr<Socket> > ());
//we want to close as soon as the connection is established
//the tcp state machine and outgoing buffer will assure that
//all of the data is delivered
// Perform series of 1040 byte writes (this is a multiple of 26 since
// we want to detect data splicing in the output stream)
uint32_t writeSize = 1040;
uint8_t data[writeSize];
while (nBytes > 0) {
uint32_t curSize= nBytes > writeSize ? writeSize : nBytes;
for(uint32_t i = 0; i < curSize; ++i)
{
char m = toascii (97 + i % 26);
data[i] = m;
}
localSocket->Send (data, curSize);
nBytes -= curSize;
}
}
int main (int argc, char *argv[])
{
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
// LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
// LogComponentEnable("TcpSocket", LOG_LEVEL_ALL);
// LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
//LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL);
// Allow the user to override any of the defaults and the above
// Bind()s at run-time, via command-line arguments
CommandLine::Parse (argc, argv);
// Here, we will explicitly create three nodes. In more sophisticated
// topologies, we could configure a node factory.
Ptr<Node> n0 = Create<InternetNode> ();
Ptr<Node> n1 = Create<InternetNode> ();
Ptr<Node> n2 = Create<InternetNode> ();
// We create the channels first without any IP addressing information
Ptr<PointToPointChannel> channel0 =
PointToPointTopology::AddPointToPointLink (
n0, n1, DataRate(10000000), MilliSeconds(10));
// Later, we add IP addresses.
PointToPointTopology::AddIpv4Addresses (
channel0, n0, Ipv4Address("10.1.3.1"),
n1, Ipv4Address("10.1.3.2"));
Ptr<PointToPointChannel> channel1 =
PointToPointTopology::AddPointToPointLink (
n1, n2, DataRate(10000000), MilliSeconds(10));
PointToPointTopology::AddIpv4Addresses (
channel1, n1, Ipv4Address("10.1.2.1"),
n2, Ipv4Address("10.1.2.2"));
// Finally, we add static routes. These three steps (Channel and
// NetDevice creation, IP Address assignment, and routing) are
// separated because there may be a need to postpone IP Address
// assignment (emulation) or modify to use dynamic routing
PointToPointTopology::AddIpv4Routes(n0, n1, channel0);
PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
Ptr<Ipv4> ipv4;
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.2"), 1);
ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.2.1"), 1);
///////////////////////////////////////////////////////////////////////////
// Simulation 1
//
// Send 2000000 bytes over a connection to server port 50000 at time 0
// Should observe SYN exchange, a lot of data segments, and FIN exchange
//
///////////////////////////////////////////////////////////////////////////
int nBytes = 2000000;
uint16_t servPort = 50000;
Ptr<SocketFactory> socketFactory =
n0->QueryInterface<SocketFactory> (Tcp::iid);
Ptr<Socket> localSocket = socketFactory->CreateSocket ();
localSocket->Bind ();
// Create a packet sink to receive these packets
Ptr<PacketSink> sink = Create<PacketSink> (
n2,
InetSocketAddress (Ipv4Address::GetAny (), servPort),
"Tcp");
sink->Start (Seconds (0.0));
sink->Stop (Seconds (100.0));
Simulator::Schedule(Seconds(0), &StartFlow, localSocket, nBytes,
servPort);
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-examples.tr file
AsciiTrace asciitrace ("tcp-large-transfer.tr");
asciitrace.TraceAllQueues ();
asciitrace.TraceAllNetDeviceRx ();
// Also configure some tcpdump traces; each interface will be traced
// The output files will be named
// simple-examples.pcap-<nodeId>-<interfaceId>
// and can be read by the "tcpdump -r" command (use "-tt" option to
// display timestamps correctly)
PcapTrace pcaptrace ("tcp-large-transfer.pcap");
pcaptrace.TraceAllIp ();
NodeList::Connect ("/nodes/*/applications/*/rx", MakeCallback (&ApplicationTraceSink));
Simulator::StopAt (Seconds(1000));
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -0,0 +1,191 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
//
// Network topology
//
// 100Kb/s, 10ms 1Mb/s, 10ms
// n0-----------------n1-----------------n2
//
//
// - Tracing of queues and packet receptions to file
// "tcp-nonlistening-server.tr"
// - pcap traces also generated in the following files
// "tcp-nonlistening-server.pcap-$n-$i" where n and i represent node and interface numbers respectively
// Usage (e.g.): ./waf --run tcp-nonlistening-server
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include "ns3/command-line.h"
#include "ns3/default-value.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
#include "ns3/ascii-trace.h"
#include "ns3/pcap-trace.h"
#include "ns3/internet-node.h"
#include "ns3/point-to-point-channel.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/ipv4-address.h"
#include "ns3/inet-socket-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
#include "ns3/packet-sink.h"
#include "ns3/error-model.h"
#include "ns3/tcp.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TcpNonListeningServer");
void ConnectionSucceededCallback (Ptr<Socket> localSocket)
{
uint32_t nBytes = 2000;
uint8_t data[nBytes];
for(uint32_t i = 0; i < nBytes; ++i)
{
char m = 'A';
data[i] = m;
} //put something interesting in the packets ABCDEF...
localSocket->Send (data, nBytes);
}
void ConnectionFailedCallback (Ptr<Socket> localSocket)
{
NS_LOG_ERROR("Connection failed at time " << Simulator::Now ().GetSeconds ());
}
void StartFlow(Ptr<Socket> localSocket, uint16_t servPort)
{
NS_LOG_LOGIC(std::endl << "Connection attempt at time " <<
Simulator::Now ().GetSeconds () << std::endl);
localSocket->Connect (InetSocketAddress ("10.1.2.2", servPort));
localSocket->SetConnectCallback (
MakeCallback (&ConnectionSucceededCallback),
MakeCallback (&ConnectionFailedCallback),
MakeNullCallback<void, Ptr<Socket> > () );
}
int main (int argc, char *argv[])
{
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
//LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
//LogComponentEnable("TcpSocket", LOG_LEVEL_ALL);
LogComponentEnable("TcpNonListeningServer", LOG_LEVEL_ALL);
// Allow the user to override any of the defaults and the above
// Bind()s at run-time, via command-line arguments
CommandLine::Parse (argc, argv);
// Here, we will explicitly create three nodes. In more sophisticated
// topologies, we could configure a node factory.
Ptr<Node> n0 = Create<InternetNode> ();
Ptr<Node> n1 = Create<InternetNode> ();
Ptr<Node> n2 = Create<InternetNode> ();
// We create the channels first without any IP addressing information
Ptr<PointToPointChannel> channel0 =
PointToPointTopology::AddPointToPointLink (
n0, n1, DataRate(1000000), MilliSeconds(10));
// Later, we add IP addresses.
PointToPointTopology::AddIpv4Addresses (
channel0, n0, Ipv4Address("10.1.3.1"),
n1, Ipv4Address("10.1.3.2"));
Ptr<PointToPointChannel> channel1 =
PointToPointTopology::AddPointToPointLink (
n1, n2, DataRate(100000), MilliSeconds(10));
PointToPointTopology::AddIpv4Addresses (
channel1, n1, Ipv4Address("10.1.2.1"),
n2, Ipv4Address("10.1.2.2"));
// Finally, we add static routes. These three steps (Channel and
// NetDevice creation, IP Address assignment, and routing) are
// separated because there may be a need to postpone IP Address
// assignment (emulation) or modify to use dynamic routing
PointToPointTopology::AddIpv4Routes(n0, n1, channel0);
PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
Ptr<Ipv4> ipv4;
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.2"), 1);
ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.2.1"), 1);
///////////////////////////////////////////////////////////////////////////
// Simulation 1
//
// Send 2000 bytes over a connection to server port 500 at time 0
// Should observe SYN exchange, two data segments, and FIN exchange
//
///////////////////////////////////////////////////////////////////////////
uint16_t servPort = 500;
Ptr<SocketFactory> socketFactory =
n0->QueryInterface<SocketFactory> (Tcp::iid);
Ptr<Socket> localSocket = socketFactory->CreateSocket ();
localSocket->Bind ();
#ifdef NOTFORTHISSCRIPT
// Create an optional packet sink to receive these packets
Ptr<PacketSink> sink = Create<PacketSink> (
n2,
InetSocketAddress (Ipv4Address::GetAny (), servPort),
"Tcp");
// Start the sink
sink->Start (Seconds (0.0));
sink->Stop (Seconds (10.0));
#endif
Simulator::Schedule(Seconds(0), &StartFlow, localSocket, servPort);
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-examples.tr file
AsciiTrace asciitrace ("tcp-nonlistening-server.tr");
asciitrace.TraceAllQueues ();
asciitrace.TraceAllNetDeviceRx ();
// Also configure some tcpdump traces; each interface will be traced
// The output files will be named
// simple-examples.pcap-<nodeId>-<interfaceId>
// and can be read by the "tcpdump -r" command (use "-tt" option to
// display timestamps correctly)
PcapTrace pcaptrace ("tcp-nonlistening-server.pcap");
pcaptrace.TraceAllIp ();
Simulator::StopAt (Seconds(1000));
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -0,0 +1,222 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
//
// Network topology
//
// 100Kb/s, 10ms 1Mb/s, 10ms
// n0-----------------n1-----------------n2
//
//
// - Tracing of queues and packet receptions to file
// "tcp-small-transfer-oneloss.tr"
// - pcap traces also generated in the following files
// "tcp-small-transfer-oneloss.pcap-$n-$i" where n and i represent node and interface numbers respectively
// Usage (e.g.): ./waf --run tcp-small-transfer-oneloss
#include <ctype.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include "ns3/command-line.h"
#include "ns3/default-value.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
#include "ns3/ascii-trace.h"
#include "ns3/pcap-trace.h"
#include "ns3/internet-node.h"
#include "ns3/point-to-point-channel.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/ipv4-address.h"
#include "ns3/inet-socket-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
#include "ns3/packet-sink.h"
#include "ns3/error-model.h"
#include "ns3/node-list.h"
#include "ns3/tcp.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TcpSmallTransferOneloss");
void
ApplicationTraceSink (const TraceContext &context, Ptr<const Packet> packet,
const Address &addr)
{
if (!g_log.IsNoneEnabled ()) {
if (InetSocketAddress::IsMatchingType (addr) )
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (addr);
std::cout << "PacketSink received size " <<
packet->GetSize () << " at time " <<
Simulator::Now ().GetSeconds () << " from address: " <<
address.GetIpv4 () << std::endl;
char buf[2000];
memcpy(buf, packet->PeekData (), packet->GetSize ());
for (uint32_t i=0; i < packet->GetSize (); i++)
{
std::cout << buf[i];
if (i && i % 60 == 0)
std::cout << std::endl;
}
std::cout << std::endl << std::endl;
}
}
}
void StartFlow(Ptr<Socket> localSocket, uint32_t nBytes,
uint16_t servPort)
{
// NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ());
localSocket->Connect (InetSocketAddress ("10.1.2.2", servPort));
uint8_t data[nBytes];
for(uint32_t i = 0; i < nBytes; ++i)
{
char m = toascii (97 + i % 26);
data[i] = m;
}
localSocket->Send (data, nBytes);
}
int main (int argc, char *argv[])
{
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
// LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
// LogComponentEnable("TcpSocket", LOG_LEVEL_ALL);
// LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
LogComponentEnable("TcpSmallTransferOneloss", LOG_LEVEL_ALL);
// Allow the user to override any of the defaults and the above
// Bind()s at run-time, via command-line arguments
CommandLine::Parse (argc, argv);
// Here, we will explicitly create three nodes. In more sophisticated
// topologies, we could configure a node factory.
Ptr<Node> n0 = Create<InternetNode> ();
Ptr<Node> n1 = Create<InternetNode> ();
Ptr<Node> n2 = Create<InternetNode> ();
// We create the channels first without any IP addressing information
Ptr<PointToPointChannel> channel0 =
PointToPointTopology::AddPointToPointLink (
n0, n1, DataRate(1000000), MilliSeconds(10));
// Later, we add IP addresses.
PointToPointTopology::AddIpv4Addresses (
channel0, n0, Ipv4Address("10.1.3.1"),
n1, Ipv4Address("10.1.3.2"));
Ptr<PointToPointChannel> channel1 =
PointToPointTopology::AddPointToPointLink (
n1, n2, DataRate(100000), MilliSeconds(10));
PointToPointTopology::AddIpv4Addresses (
channel1, n1, Ipv4Address("10.1.2.1"),
n2, Ipv4Address("10.1.2.2"));
// Finally, we add static routes. These three steps (Channel and
// NetDevice creation, IP Address assignment, and routing) are
// separated because there may be a need to postpone IP Address
// assignment (emulation) or modify to use dynamic routing
PointToPointTopology::AddIpv4Routes(n0, n1, channel0);
PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
Ptr<Ipv4> ipv4;
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.2"), 1);
ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.2.1"), 1);
///////////////////////////////////////////////////////////////////////////
// Simulation 1
//
// Send 2000 bytes over a connection to server port 500 at time 0
// Should observe SYN exchange, two data segments, and FIN exchange
// Force the loss of the first data segment
//
///////////////////////////////////////////////////////////////////////////
int nBytes = 2000;
uint16_t servPort = 500;
Ptr<SocketFactory> socketFactory =
n0->QueryInterface<SocketFactory> (Tcp::iid);
Ptr<Socket> localSocket = socketFactory->CreateSocket ();
localSocket->Bind ();
// Create a packet sink to receive these packets
Ptr<PacketSink> sink = Create<PacketSink> (
n2,
InetSocketAddress (Ipv4Address::GetAny (), servPort),
"Tcp");
sink->Start (Seconds (0.0));
sink->Stop (Seconds (100.0));
//
// Error models
//
// We want to add an error model to node 2's NetDevice
// We can obtain a handle to the NetDevice via the channel and node
// pointers
Ptr<PointToPointNetDevice> nd2 = PointToPointTopology::GetNetDevice
(n2, channel1);
Ptr<ListErrorModel> pem = Create<ListErrorModel> ();
std::list<uint32_t> sampleList;
// The first data segment for this flow is packet uid=4
sampleList.push_back (4);
pem->SetList (sampleList);
nd2->AddReceiveErrorModel (pem);
Simulator::Schedule(Seconds(0), &StartFlow, localSocket, nBytes,
servPort);
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-examples.tr file
AsciiTrace asciitrace ("tcp-small-transfer-oneloss.tr");
asciitrace.TraceAllQueues ();
asciitrace.TraceAllNetDeviceRx ();
// Also configure some tcpdump traces; each interface will be traced
// The output files will be named
// simple-examples.pcap-<nodeId>-<interfaceId>
// and can be read by the "tcpdump -r" command (use "-tt" option to
// display timestamps correctly)
PcapTrace pcaptrace ("tcp-small-transfer-oneloss.pcap");
pcaptrace.TraceAllIp ();
NodeList::Connect ("/nodes/*/applications/*/rx", MakeCallback (&ApplicationTraceSink));
Simulator::StopAt (Seconds(1000));
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -0,0 +1,217 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
//
// Network topology
//
// 100Kb/s, 10ms 1Mb/s, 10ms
// n0-----------------n1-----------------n2
//
//
// - Tracing of queues and packet receptions to file
// "tcp-small-transfer.tr"
// - pcap traces also generated in the following files
// "tcp-small-transfer.pcap-$n-$i" where n and i represent node and interface numbers respectively
// Usage (e.g.): ./waf --run tcp-small-transfer
#include <ctype.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include "ns3/command-line.h"
#include "ns3/default-value.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
#include "ns3/ascii-trace.h"
#include "ns3/pcap-trace.h"
#include "ns3/internet-node.h"
#include "ns3/point-to-point-channel.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/ipv4-address.h"
#include "ns3/inet-socket-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
#include "ns3/packet-sink.h"
#include "ns3/error-model.h"
#include "ns3/node-list.h"
#include "ns3/tcp.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TcpSmallTransfer");
void
ApplicationTraceSink (const TraceContext &context, Ptr<const Packet> packet,
const Address &addr)
{
if (!g_log.IsNoneEnabled ()) {
if (InetSocketAddress::IsMatchingType (addr) )
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (addr);
std::cout << "PacketSink received size " <<
packet->GetSize () << " at time " <<
Simulator::Now ().GetSeconds () << " from address: " <<
address.GetIpv4 () << std::endl;
char buf[2000];
memcpy(buf, packet->PeekData (), packet->GetSize ());
for (uint32_t i=0; i < packet->GetSize (); i++)
{
std::cout << buf[i];
if (i && i % 60 == 0)
std::cout << std::endl;
}
std::cout << std::endl << std::endl;
}
}
}
void CloseConnection (Ptr<Socket> localSocket)
{
localSocket->Close ();
}
void StartFlow(Ptr<Socket> localSocket, uint32_t nBytes,
uint16_t servPort)
{
// NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ());
localSocket->Connect (InetSocketAddress ("10.1.2.2", servPort));//connect
localSocket->SetConnectCallback (MakeCallback (&CloseConnection),
MakeNullCallback<void, Ptr<Socket> > (),
MakeNullCallback<void, Ptr<Socket> > ());
//we want to close as soon as the connection is established
//the tcp state machine and outgoing buffer will assure that
//all of the data is delivered
uint8_t data[nBytes];
for(uint32_t i = 0; i < nBytes; ++i)
{
char m = toascii (97 + i % 26);
data[i] = m;
}
localSocket->Send (data, nBytes);
}
int main (int argc, char *argv[])
{
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
// LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
// LogComponentEnable("TcpSocket", LOG_LEVEL_ALL);
// LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
LogComponentEnable("TcpSmallTransfer", LOG_LEVEL_ALL);
// Allow the user to override any of the defaults and the above
// Bind()s at run-time, via command-line arguments
CommandLine::Parse (argc, argv);
// Here, we will explicitly create three nodes. In more sophisticated
// topologies, we could configure a node factory.
Ptr<Node> n0 = Create<InternetNode> ();
Ptr<Node> n1 = Create<InternetNode> ();
Ptr<Node> n2 = Create<InternetNode> ();
// We create the channels first without any IP addressing information
Ptr<PointToPointChannel> channel0 =
PointToPointTopology::AddPointToPointLink (
n0, n1, DataRate(1000000), MilliSeconds(10));
// Later, we add IP addresses.
PointToPointTopology::AddIpv4Addresses (
channel0, n0, Ipv4Address("10.1.3.1"),
n1, Ipv4Address("10.1.3.2"));
Ptr<PointToPointChannel> channel1 =
PointToPointTopology::AddPointToPointLink (
n1, n2, DataRate(100000), MilliSeconds(10));
PointToPointTopology::AddIpv4Addresses (
channel1, n1, Ipv4Address("10.1.2.1"),
n2, Ipv4Address("10.1.2.2"));
// Finally, we add static routes. These three steps (Channel and
// NetDevice creation, IP Address assignment, and routing) are
// separated because there may be a need to postpone IP Address
// assignment (emulation) or modify to use dynamic routing
PointToPointTopology::AddIpv4Routes(n0, n1, channel0);
PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
Ptr<Ipv4> ipv4;
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.2"), 1);
ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->SetDefaultRoute (Ipv4Address ("10.1.2.1"), 1);
///////////////////////////////////////////////////////////////////////////
// Simulation 1
//
// Send 2000 bytes over a connection to server port 500 at time 0
// Should observe SYN exchange, two data segments, and FIN exchange
//
///////////////////////////////////////////////////////////////////////////
int nBytes = 2000;
uint16_t servPort = 500;
Ptr<SocketFactory> socketFactory =
n0->QueryInterface<SocketFactory> (Tcp::iid);
Ptr<Socket> localSocket = socketFactory->CreateSocket ();
localSocket->Bind ();
// Create a packet sink to receive these packets
Ptr<PacketSink> sink = Create<PacketSink> (
n2,
InetSocketAddress (Ipv4Address::GetAny (), servPort),
"Tcp");
sink->Start (Seconds (0.0));
sink->Stop (Seconds (100.0));
Simulator::Schedule(Seconds(0), &StartFlow, localSocket, nBytes,
servPort);
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-examples.tr file
AsciiTrace asciitrace ("tcp-small-transfer.tr");
asciitrace.TraceAllQueues ();
asciitrace.TraceAllNetDeviceRx ();
// Also configure some tcpdump traces; each interface will be traced
// The output files will be named
// simple-examples.pcap-<nodeId>-<interfaceId>
// and can be read by the "tcpdump -r" command (use "-tt" option to
// display timestamps correctly)
PcapTrace pcaptrace ("tcp-small-transfer.pcap");
pcaptrace.TraceAllIp ();
NodeList::Connect ("/nodes/*/applications/*/rx", MakeCallback (&ApplicationTraceSink));
Simulator::StopAt (Seconds(1000));
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -45,3 +45,25 @@ def build(bld):
obj = bld.create_ns3_program('simple-point-to-point-olsr',
['point-to-point', 'internet-node', 'olsr'])
obj.source = 'simple-point-to-point-olsr.cc'
obj = bld.create_ns3_program('tcp-large-transfer',
['point-to-point', 'internet-node'])
obj.source = 'tcp-large-transfer.cc'
obj = bld.create_ns3_program('tcp-large-transfer-errors',
['point-to-point', 'internet-node'])
obj.source = 'tcp-large-transfer-errors.cc'
obj = bld.create_ns3_program('tcp-nonlistening-server',
['point-to-point', 'internet-node'])
obj.source = 'tcp-nonlistening-server.cc'
obj = bld.create_ns3_program('tcp-small-transfer',
['point-to-point', 'internet-node'])
obj.source = 'tcp-small-transfer.cc'
obj = bld.create_ns3_program('tcp-small-transfer-oneloss',
['point-to-point', 'internet-node'])
obj.source = 'tcp-small-transfer-oneloss.cc'

View File

@@ -78,9 +78,14 @@ void PacketSink::StartApplication() // Called at time specified by Start
GetNode ()->QueryInterface<SocketFactory> (iid);
m_socket = socketFactory->CreateSocket ();
m_socket->Bind (m_local);
m_socket->Listen (0);
}
m_socket->SetRecvCallback (MakeCallback(&PacketSink::Receive, this));
m_socket->SetAcceptCallback (
MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
MakeNullCallback<void, Ptr<Socket>, const Address&> (),
MakeCallback(&PacketSink::CloseConnection, this) );
}
void PacketSink::StopApplication() // Called at time specified by Stop
@@ -106,6 +111,11 @@ void PacketSink::Receive(Ptr<Socket> socket, Ptr<Packet> packet,
m_rxTrace (packet, from);
}
void PacketSink::CloseConnection (Ptr<Socket> socket)
{
socket->Close ();
}
Ptr<TraceResolver>
PacketSink::GetTraceResolver (void) const
{

View File

@@ -78,6 +78,7 @@ private:
std::string iid);
virtual void Receive (Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
virtual void CloseConnection (Ptr<Socket> socket);
Ptr<Socket> m_socket; // Associated socket
Address m_local; // Local address to bind to

View File

@@ -28,9 +28,11 @@
#include "ipv4-l4-demux.h"
#include "internet-node.h"
#include "udp-l4-protocol.h"
#include "tcp-l4-protocol.h"
#include "ipv4-l3-protocol.h"
#include "arp-l3-protocol.h"
#include "udp-impl.h"
#include "tcp-impl.h"
#include "ipv4-impl.h"
namespace ns3 {
@@ -62,15 +64,20 @@ InternetNode::Construct (void)
Ptr<Ipv4L4Demux> ipv4L4Demux = Create<Ipv4L4Demux> (this);
Ptr<UdpL4Protocol> udp = Create<UdpL4Protocol> (this);
Ptr<TcpL4Protocol> tcp = Create<TcpL4Protocol> (this);
ipv4L4Demux->Insert (udp);
ipv4L4Demux->Insert (tcp);
Ptr<UdpImpl> udpImpl = Create<UdpImpl> (udp);
Ptr<TcpImpl> tcpImpl = Create<TcpImpl> (tcp);
Ptr<Ipv4Impl> ipv4Impl = Create<Ipv4Impl> (ipv4);
Object::AddInterface (ipv4);
Object::AddInterface (arp);
Object::AddInterface (ipv4Impl);
Object::AddInterface (udpImpl);
Object::AddInterface (tcpImpl);
Object::AddInterface (ipv4L4Demux);
}

View File

@@ -0,0 +1,222 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation;
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
//
// This is a port of Data PDU Headers from:
// Georgia Tech Network Simulator
// George F. Riley. Georgia Tech, Spring 2002
#include <iostream>
#include <algorithm>
#include <string.h>
#include "pending-data.h"
#include "ns3/packet.h"
#include "ns3/fatal-error.h"
namespace ns3
{
namespace Serializable
{
uint8_t* GetSize (uint8_t* b, uint32_t& r, uint32_t& s)
{ // Get the size of the next size field
if (sizeof(s) > r)
{
NS_FATAL_ERROR ("Serialization error; remaining " << r
<< " thissize " << sizeof(s) << std::endl);
}
r -= sizeof (s); // Reduce remaining for next time
memcpy (&s, b, sizeof(s));
return b + sizeof (s);
}
}
PendingData::PendingData () : size (0), data (0),
msgSize (0), responseSize (0)
{
}
PendingData::PendingData (uint32_t s, uint8_t* d, uint32_t msg, uint32_t resp)
: size (s), data (0), msgSize (msg), responseSize (resp)
{ // Make a copy of the data
if (d)
{
data = new uint8_t[s];
memcpy (data, d, s);
}
}
PendingData::PendingData(const std::string& s)
: size (s.length () + 1), data ((uint8_t*)strdup(s.c_str ())),
msgSize (0), responseSize (0)
{
}
PendingData::PendingData(const PendingData& c)
: size (c.Size ()), data (0),
msgSize (c.msgSize), responseSize (c.responseSize)
{ // Copy constructor
if (c.Contents())
{ // Has data
data = new uint8_t[Size ()];
memcpy(data, c.Contents (), Size ());
}
}
PendingData::~PendingData()
{ // destructor
if (data)
{
delete [] data;
}
}
PendingData* PendingData::Copy () const
{
return new PendingData (*this);
};
PendingData* PendingData::CopyS (uint32_t s)
{ // Copy, but with new size (assumes no associated data);
return new PendingData (s, 0, msgSize, responseSize);
}
PendingData* PendingData::CopySD (uint32_t s, uint8_t* d)
{ // Copy, but with new size (assumes no associated data);
return new PendingData (s, d, msgSize, responseSize);
}
void PendingData::Clear ()
{ // Remove all pending data
if (data)
{
delete [] data; // Free memory if used
}
data = 0;
size = 0;
}
void PendingData::Add (uint32_t s, const uint8_t* d)
{
if (data)
{ // PendingData exists, realloc and copy
uint8_t* n = new uint8_t[Size () + s];
memcpy(n, data, Size ());
if (d)
{ // New data specified
memcpy(n + Size (), d, s); // Append the new data
}
else
{
memset(n + Size (), 0, s); // Apend zeros
}
delete [] data; // Delete the old data
data = n; // Points to new one
}
else
{ // No existing data, see if new data
if (d)
{
data = new uint8_t[s];
memcpy (data, d, s);
}
}
size += s;
}
void PendingData::Remove(uint32_t s)
{
uint32_t r = s > Size () ? Size () : s;
size -= r; // Reduce size from current
if (data)
{ // data actually exists, realloc and copy
if (size)
{
uint8_t* d = new uint8_t[Size ()];
memcpy(d, data, Size ());
delete [] data;
data = d;
}
else
{ // Zero size, so don't need the data anymore
delete [] data;
data = NULL;
}
}
}
uint32_t PendingData::SizeFromSeq (const SequenceNumber& f, const SequenceNumber& o)
{
uint32_t o1 = OffsetFromSeq (f,o); // Offset to start of unused data
return SizeFromOffset (o1); // Amount of data after offset
}
uint32_t PendingData::SizeFromOffset (uint32_t o)
{ // Find out how much data is available from offset
if (o > size) return 0; // No data at requested offset
return size - o; // Available data after offset
}
uint32_t PendingData::OffsetFromSeq (const SequenceNumber& f, const SequenceNumber& o)
{ // f is the first sequence number in this data, o is offset sequence
if (o < f)
{
return 0; // HuH? Shouldn't happen
}
return o - f;
}
PendingData* PendingData::CopyFromOffset (uint32_t s, uint32_t o)
{ // Make a copy of data from starting position "o" for "s" bytes
// Return NULL if results in zero length data
uint32_t s1 = std::min (s, SizeFromOffset (o)); // Insure not beyond end of data
if (s1 == 0)
{
return NULL; // No data requested
}
if (data)
{ // Actual data exists, make copy and return it
uint8_t* d1 = new uint8_t[s1]; // Allocate memory for the copy
memcpy (d1, &data[o], s1); // Copy the data
PendingData* d = new PendingData (s1, d1, msgSize, responseSize); // Return copy
return d;
}
else
{ // No actual data, just return non-data pdu of correct size
return new PendingData (s1, 0, msgSize, responseSize);
}
}
PendingData* PendingData::CopyFromSeq (uint32_t s, const SequenceNumber& f, const SequenceNumber& o)
{
PendingData* d = CopyFromOffset (s, OffsetFromSeq(f,o));
return d;
}
}//namepsace ns3

View File

@@ -0,0 +1,73 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation;
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
//
// Georgia Tech Network Simulator - Data Descriptors
// George F. Riley. Georgia Tech, Spring 2002
#ifndef __datapdu_h__
#define __datapdu_h__
#include "pending-data.h"
#include "sequence-number.h"
namespace ns3
{
class Packet;
//Doc:ClassXRef
class PendingData {
public:
PendingData ();
PendingData (uint32_t s, uint8_t* d = NULL, uint32_t msg = 0, uint32_t resp = 0);
PendingData (const std::string&); // Construct from string
PendingData (uint8_t*, uint32_t&, Packet*); // Construct from serialized buffer
PendingData (const PendingData&); // Copy constructor
virtual ~PendingData (); // Destructor
uint32_t Size () const { return size;}
// Serialization
uint32_t SSize (); // Size needed for serialization
uint8_t* Serialize (uint8_t*, uint32_t&); // Serialize to a buffer
uint8_t* Construct (uint8_t*, uint32_t&); // Construct from buffer
virtual void Clear ();// Remove all associated data
virtual void Add (uint32_t s, const uint8_t* d = 0);// Add some data to end
virtual void Remove (uint32_t); // Remove data from head
// Inquire available data from (f,o) sequence pair
virtual uint32_t SizeFromSeq (const SequenceNumber&, const SequenceNumber&);
// Inquire available data from offset
virtual uint32_t SizeFromOffset (uint32_t);
// Available size from sequence difference
virtual uint32_t OffsetFromSeq (const SequenceNumber&, const SequenceNumber&);
virtual PendingData* CopyFromOffset (uint32_t, uint32_t); // Size, offset, ret pointer
// Copy data, size, offset specified by sequence difference
virtual PendingData* CopyFromSeq (uint32_t, const SequenceNumber&, const SequenceNumber&);
PendingData* Copy () const; // Create a copy of this header
PendingData* CopyS (uint32_t); // Copy with new size
PendingData* CopySD (uint32_t, uint8_t*); // Copy with new size, new data
virtual uint8_t* Contents() const { return data;}
public:
uint32_t size; // Number of data bytes
uint8_t* data; // Corresponding data (may be null)
// The next two fields allow simulated applications to exchange some info
uint32_t msgSize; // Total size of message
uint32_t responseSize;// Size of response requested
};
}//namepsace ns3
#endif

View File

@@ -0,0 +1,233 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2006 Georgia Tech Research Corporation
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation;
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
//
// Ported from:
// Georgia Tech Network Simulator - Round Trip Time Estimation Class
// George F. Riley. Georgia Tech, Spring 2002
// Implements several variations of round trip time estimators
#include <iostream>
#include "rtt-estimator.h"
#include "ns3/simulator.h"
namespace ns3{
//RttEstimator iid
const InterfaceId RttEstimator::iid = MakeInterfaceId ("RttEstimator",
Object::iid);
//Default values
ClassIdDefaultValue RttEstimator::defaultCid ("RttEstimator",
"Tahoe round trip time estimation",
RttEstimator::iid, "RttMeanDeviation");
NumericDefaultValue<double> RttEstimator::defaultMaxMultiplier ("RttMaxMultiplier","",64.0);
// RttEstimator Static Member variables
Time RttEstimator::initialEstimate = Seconds (1.0); // Default initial estimate
//RttHistory methods
RttHistory::RttHistory (SequenceNumber s, uint32_t c, Time t)
: seq (s), count (c), time (t), retx (false)
{
}
RttHistory::RttHistory (const RttHistory& h)
: seq (h.seq), count (h.count), time (h.time), retx (h.retx)
{
}
// Base class methods
RttEstimator::RttEstimator () : next (1), history (), est (initialEstimate),
nSamples (0), multiplier (1.0)
{
//note next=1 everywhere since first segment will have sequence 1
SetInterfaceId (RttEstimator::iid);
}
RttEstimator::RttEstimator (Time e) : next (1), history (), est (e),
nSamples (0), multiplier (1.0)
{
SetInterfaceId (RttEstimator::iid);
}
RttEstimator::RttEstimator(const RttEstimator& c)
: next(c.next), history(c.history), est(c.est), nSamples(c.nSamples),
multiplier(c.multiplier)
{
SetInterfaceId (RttEstimator::iid);
}
RttEstimator::~RttEstimator ()
{
}
void RttEstimator::SentSeq (SequenceNumber s, uint32_t c)
{ // Note that a particular sequence has been sent
if (s == next)
{ // This is the next expected one, just log at end
history.push_back (RttHistory (s, c, Simulator::Now () ));
next = s + SequenceNumber (c); // Update next expected
}
else
{ // This is a retransmit, find in list and mark as re-tx
for (RttHistory_t::iterator i = history.begin (); i != history.end (); ++i)
{
if ((s >= i->seq) && (s < (i->seq + SequenceNumber (i->count))))
{ // Found it
i->retx = true;
// One final test..be sure this re-tx does not extend "next"
if ((s + SequenceNumber (c)) > next)
{
next = s + SequenceNumber (c);
i->count = ((s + SequenceNumber (c)) - i->seq); // And update count in hist
}
break;
}
}
}
}
Time RttEstimator::AckSeq (SequenceNumber a)
{ // An ack has been received, calculate rtt and log this measurement
// Note we use a linear search (O(n)) for this since for the common
// case the ack'ed packet will be at the head of the list
Time m = Seconds (0.0);
if (history.size () == 0) return (m); // No pending history, just exit
RttHistory& h = history.front ();
if (!h.retx && a >= (h.seq + SequenceNumber (h.count)))
{ // Ok to use this sample
m = Simulator::Now () - h.time; // Elapsed time
Measurement(m); // Log the measurement
ResetMultiplier(); // Reset multiplier on valid measurement
}
// Now delete all ack history with seq <= ack
while(history.size() > 0)
{
RttHistory& h = history.front ();
if ((h.seq + SequenceNumber(h.count)) > a) break; // Done removing
history.pop_front (); // Remove
}
return m;
}
void RttEstimator::ClearSent ()
{ // Clear all history entries
next = 1;
history.clear ();
}
void RttEstimator::IncreaseMultiplier ()
{
multiplier = std::min (multiplier * 2.0, defaultMaxMultiplier.GetValue ());
}
void RttEstimator::ResetMultiplier ()
{
multiplier = 1.0;
}
void RttEstimator::Reset ()
{ // Reset to initial state
next = 1;
est = initialEstimate;
history.clear (); // Remove all info from the history
nSamples = 0;
ResetMultiplier ();
}
// Base class, static methods
void RttEstimator::InitialEstimate (Time e)
{ // Set a new default initial estimate
initialEstimate = e;
}
Ptr<RttEstimator> RttEstimator::CreateDefault ()
{
ClassId classId = defaultCid.GetValue ();
Ptr<RttEstimator> rtte = ComponentManager::Create<RttEstimator> (
classId, RttEstimator::iid, 0.1, initialEstimate
);
return rtte;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Mean-Deviation Estimator
const ClassId RttMeanDeviation::cid =
MakeClassId<RttMeanDeviation, double, Time> ("RttMeanDeviation",
RttEstimator::iid);
RttMeanDeviation::RttMeanDeviation(double g) :
gain (g), variance (ns3::Seconds(0))
{
}
RttMeanDeviation::RttMeanDeviation (const RttMeanDeviation& c)
: RttEstimator (c), gain (c.gain), variance (c.variance)
{
}
RttMeanDeviation::RttMeanDeviation (double g, Time e) :
RttEstimator (e), gain (g), variance (ns3::Seconds(0))
{
}
void RttMeanDeviation::Measurement (Time m)
{
if (nSamples)
{ // Not first
Time err = m - est;
est = est + Scalar (gain) * err; // estimated rtt
err = Abs (err); // absolute value of error
variance = variance + Scalar (gain) * (err - variance); // variance of rtt
}
else
{ // First sample
est = m; // Set estimate to current
//variance = m / 2; // And variance to current / 2
variance = m; // try this
}
nSamples++;
}
Time RttMeanDeviation::RetransmitTimeout ()
{
// If not enough samples, justjust return 2 times estimate
//if (nSamples < 2) return est * 2;
if (variance < est / Scalar (4.0))
return est * Scalar (2 * multiplier); // At least twice current est
return (est + Scalar (4) * variance) * Scalar (multiplier); // As suggested by Jacobson
}
RttEstimator* RttMeanDeviation::Copy () const
{
return new RttMeanDeviation (*this);
}
void RttMeanDeviation::Reset ()
{ // Reset to initial state
variance = Seconds (0.0);
RttEstimator::Reset ();
}
}//namepsace ns3

View File

@@ -0,0 +1,131 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2006 Georgia Tech Research Corporation
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation;
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
//
// Georgia Tech Network Simulator - Round Trip Time Estimation Class
// George F. Riley. Georgia Tech, Spring 2002
// Implements several variations of round trip time estimators
#ifndef __rtt_estimator_h__
#define __rtt_estimator_h__
#include <deque>
#include "sequence-number.h"
#include "ns3/nstime.h"
#include "ns3/object.h"
#include "ns3/component-manager.h"
namespace ns3 {
class RttHistory {
public:
RttHistory (SequenceNumber s, uint32_t c, Time t);
RttHistory (const RttHistory& h); // Copy constructor
public:
SequenceNumber seq; // First sequence number in packet sent
uint32_t count; // Number of bytes sent
Time time; // Time this one was sent
bool retx; // True if this has been retransmitted
};
typedef std::deque<RttHistory> RttHistory_t;
class RttEstimator : public Object { // Base class for all RTT Estimators
public:
static const InterfaceId iid;
RttEstimator();
RttEstimator(Time e);
RttEstimator(const RttEstimator&); // Copy constructor
virtual ~RttEstimator();
virtual void SentSeq(SequenceNumber, uint32_t);
virtual Time AckSeq(SequenceNumber);
virtual void ClearSent();
virtual void Measurement(Time t) = 0;
virtual Time Estimate() = 0;
virtual Time RetransmitTimeout() = 0;
void Init(SequenceNumber s) { next = s;}
virtual RttEstimator* Copy() const = 0;
virtual void IncreaseMultiplier();
virtual void ResetMultiplier();
virtual void Reset();
private:
SequenceNumber next; // Next expected sequence to be sent
RttHistory_t history; // List of sent packet
public:
Time est; // Current estimate
uint32_t nSamples;// Number of samples
double multiplier; // RTO Multiplier
public:
static void InitialEstimate(Time);
static Ptr<RttEstimator> CreateDefault(); // Retrieve current default
static ClassIdDefaultValue defaultCid;
static NumericDefaultValue<double> defaultMaxMultiplier;
private:
static Time initialEstimate; // Default initial estimate
};
// The "Mean-Deviation" estimator, as discussed by Van Jacobson
// "Congestion Avoidance and Control", SIGCOMM 88, Appendix A
//Doc:Class Class {\tt RttMeanDeviation} implements the "Mean--Deviation" estimator
//Doc:Class as described by Van Jacobson
//Doc:Class "Congestion Avoidance and Control", SIGCOMM 88, Appendix A
class RttMeanDeviation : public RttEstimator {
public :
static const ClassId cid;
//Doc:Desc Constructor for {\tt RttMeanDeviation} specifying the gain factor for the
//Doc:Desc estimator.
//Doc:Arg1 Gain factor.
RttMeanDeviation (double g);
//Doc:Desc Constructor for {\tt RttMeanDeviation} specifying the gain factor
//Doc:Desc and the initial estimate.
//Doc:Arg1 Gain factor.
//Doc:Arg2 Initial estimate.
RttMeanDeviation (double g, Time e);
//Doc:Method
RttMeanDeviation (const RttMeanDeviation&); // Copy constructor
//Doc:Desc Copy constructor.
//Doc:Arg1 {\tt RttMeanDeviation} object to copy.
void Measurement (Time);
Time Estimate () { return est;}
Time Variance () { return variance;}
Time RetransmitTimeout ();
RttEstimator* Copy () const;
void Reset ();
void Gain (double g) { gain = g;}
public:
double gain; // Filter gain
Time variance; // Current variance
};
}//namespace ns3
#endif

View File

@@ -0,0 +1,66 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation;
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
//
// Ported from:
// Georgia Tech Network Simulator - Manage 32 bit unsigned sequence numbers
// George F. Riley. Georgia Tech, Spring 2002
// Class to manage arithmetic operations on sequence numbers (mod 2^32)
#include "sequence-number.h"
bool operator< (const SequenceNumber l, const SequenceNumber r)
{ // Account for 32 bit rollover
if (l.seq > 0xc0000000 && r.seq < 0x40000000) return true; // Rollover
return l.seq < r.seq;
}
bool operator<= (const SequenceNumber l, const SequenceNumber r)
{ // Account for 32 bit rollover
if (l.seq > 0xc0000000 && r.seq < 0x40000000) return true; // Rollover
return l.seq <= r.seq;
}
bool operator> (const SequenceNumber l, const SequenceNumber r)
{ // Account for 32 bit rollover
if (l.seq > 0xc0000000 && r.seq < 0x40000000) return false; // Rollover
return l.seq > r.seq;
}
bool operator>= (const SequenceNumber l, const SequenceNumber r)
{ // Account for 32 bit rollover
if (l.seq > 0xc0000000 && r.seq < 0x40000000) return false; // Rollover
return l.seq >= r.seq;
}
// Non-Member Arithmetic operators
SequenceNumber operator+ (const SequenceNumber l, const SequenceNumber r)
{
return SequenceNumber (l.seq + r.seq);
}
SequenceNumber operator- (const SequenceNumber l, const SequenceNumber r)
{ // This assumes l is always bigger than r (allows for rollover)
if (l.seq >= r.seq) return SequenceNumber (l.seq-r.seq);
return SequenceNumber ((MAX_SEQ - r.seq) + l.seq + 1); // Adjust for rollover
}

View File

@@ -0,0 +1,67 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation;
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
//
// Ported from:
// Georgia Tech Network Simulator - Manage 32 bit unsigned sequence numbers
// George F. Riley. Georgia Tech, Spring 2002
// Class to manage arithmetic operations on sequence numbers (mod 2^32)
#ifndef __seq_h__
#define __seq_h__
#include <stdint.h>
#define MAX_SEQ ((uint32_t)0xffffffff)
class SequenceNumber {
public:
SequenceNumber () : seq(0) { }
SequenceNumber (const uint32_t s) : seq (s) { }
operator uint32_t () const { return seq;}
SequenceNumber& operator= (const uint32_t s) { seq = s; return *this;}
SequenceNumber& operator+= (const uint32_t s) { seq += s; return *this;}
SequenceNumber operator++ () { seq++; return *this;}
SequenceNumber operator++ (int) { SequenceNumber ss (seq); seq++; return ss;}
SequenceNumber& operator-= (const uint32_t s) { seq -= s; return *this;}
SequenceNumber operator-- () { seq--; return *this;}
SequenceNumber operator-- (int) { SequenceNumber ss (seq); seq--; return ss;}
public:
uint32_t seq;
};
// Comparison operators
bool operator< (const SequenceNumber l, const SequenceNumber r);
bool operator<= (const SequenceNumber l, const SequenceNumber r);
bool operator> (const SequenceNumber l, const SequenceNumber r);
bool operator>= (const SequenceNumber l, const SequenceNumber r);
// Non-member arithmetic operators
SequenceNumber operator+ (const SequenceNumber l, const SequenceNumber r);
SequenceNumber operator- (const SequenceNumber l, const SequenceNumber r);
#endif

View File

@@ -0,0 +1,187 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#include <stdint.h>
#include <iostream>
#include "tcp-socket.h"
#include "tcp-header.h"
#include "ns3/buffer.h"
namespace ns3 {
NS_HEADER_ENSURE_REGISTERED (TcpHeader);
bool TcpHeader::m_calcChecksum = false;
uint32_t
TcpHeader::GetUid (void)
{
static uint32_t uid = AllocateUid<TcpHeader> ("TcpHeader.ns3");
return uid;
}
TcpHeader::TcpHeader ()
: m_sourcePort (0),
m_destinationPort (0),
m_sequenceNumber (0),
m_ackNumber (0),
m_length (5),
m_flags (0),
m_windowSize (Tcp::defaultAdvWin.GetValue ()),
m_checksum (0),
m_urgentPointer (0)
{
}
TcpHeader::~TcpHeader ()
{}
void
TcpHeader::EnableChecksums (void)
{
m_calcChecksum = true;
}
void TcpHeader::SetSourcePort (uint16_t port)
{
m_sourcePort = port;
}
void TcpHeader::SetDestinationPort (uint16_t port)
{
m_destinationPort = port;
}
void TcpHeader::SetSequenceNumber (SequenceNumber sequenceNumber)
{
m_sequenceNumber = sequenceNumber;
}
void TcpHeader::SetAckNumber (SequenceNumber ackNumber)
{
m_ackNumber = ackNumber;
}
void TcpHeader::SetLength (uint8_t length)
{
m_length = length;
}
void TcpHeader::SetFlags (uint8_t flags)
{
m_flags = flags;
}
void TcpHeader::SetWindowSize (uint16_t windowSize)
{
m_windowSize = windowSize;
}
void TcpHeader::SetChecksum (uint16_t checksum)
{
m_checksum = checksum;
}
void TcpHeader::SetUrgentPointer (uint16_t urgentPointer)
{
m_urgentPointer = urgentPointer;
}
uint16_t TcpHeader::GetSourcePort () const
{
return m_sourcePort;
}
uint16_t TcpHeader::GetDestinationPort () const
{
return m_destinationPort;
}
SequenceNumber TcpHeader::GetSequenceNumber () const
{
return m_sequenceNumber;
}
SequenceNumber TcpHeader::GetAckNumber () const
{
return m_ackNumber;
}
uint8_t TcpHeader::GetLength () const
{
return m_length;
}
uint8_t TcpHeader::GetFlags () const
{
return m_flags;
}
uint16_t TcpHeader::GetWindowSize () const
{
return m_windowSize;
}
uint16_t TcpHeader::GetChecksum () const
{
return m_checksum;
}
uint16_t TcpHeader::GetUrgentPointer () const
{
return m_urgentPointer;
}
void
TcpHeader::InitializeChecksum (Ipv4Address source,
Ipv4Address destination,
uint8_t protocol)
{
m_checksum = 0;
//XXX requires peeking into IP to get length of the TCP segment
}
std::string
TcpHeader::GetName (void) const
{
return "TCP";
}
void TcpHeader::Print (std::ostream &os) const
{
//XXX
}
uint32_t TcpHeader::GetSerializedSize (void) const
{
return 20; //tcp headers are 20 bytes
}
void TcpHeader::Serialize (Buffer::Iterator start) const
{
start.WriteHtonU16 (m_sourcePort);
start.WriteHtonU16 (m_destinationPort);
start.WriteHtonU32 (m_sequenceNumber);
start.WriteHtonU32 (m_ackNumber);
start.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero
start.WriteHtonU16 (m_windowSize);
//XXX calculate checksum here
start.WriteHtonU16 (m_checksum);
start.WriteHtonU16 (m_urgentPointer);
}
uint32_t TcpHeader::Deserialize (Buffer::Iterator start)
{
m_sourcePort = start.ReadNtohU16 ();
m_destinationPort = start.ReadNtohU16 ();
m_sequenceNumber = start.ReadNtohU32 ();
m_ackNumber = start.ReadNtohU32 ();
uint16_t field = start.ReadNtohU16 ();
m_flags = field & 0x3F;
m_length = field>>12;
m_windowSize = start.ReadNtohU16 ();
m_checksum = start.ReadNtohU16 ();
m_urgentPointer = start.ReadNtohU16 ();
return GetSerializedSize ();
}
}; // namespace ns3

View File

@@ -0,0 +1,161 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#ifndef TCP_HEADER_H
#define TCP_HEADER_H
#include <stdint.h>
#include "ns3/header.h"
#include "ns3/buffer.h"
#include "ns3/tcp.h"
#include "ns3/ipv4-address.h"
#include "sequence-number.h"
namespace ns3 {
class TcpHeader : public Header {
public:
static uint32_t GetUid (void);
TcpHeader ();
virtual ~TcpHeader ();
/**
* \brief Enable checksum calculation for TCP (XXX currently has no effect)
*/
static void EnableChecksums (void);
//Setters
/**
* \param port The source port for this TcpHeader
*/
void SetSourcePort (uint16_t port);
/**
* \param port the destination port for this TcpHeader
*/
void SetDestinationPort (uint16_t port);
/**
* \param sequenceNumber the sequence number for this TcpHeader
*/
void SetSequenceNumber (SequenceNumber sequenceNumber);
/**
* \param ackNumber the ACK number for this TcpHeader
*/
void SetAckNumber (SequenceNumber ackNumber);
/**
* \param length the length of this TcpHeader
*/
void SetLength (uint8_t length);
/**
* \param flags the flags for this TcpHeader
*/
void SetFlags (uint8_t flags);
/**
* \param windowSize the window size for this TcpHeader
*/
void SetWindowSize (uint16_t windowSize);
/**
* \param checksum the checksum for this TcpHeader
*/
void SetChecksum (uint16_t checksum);
/**
* \param urgentPointer the urgent pointer for this TcpHeader
*/
void SetUrgentPointer (uint16_t urgentPointer);
//Getters
/**
* \return The source port for this TcpHeader
*/
uint16_t GetSourcePort () const;
/**
* \return the destination port for this TcpHeader
*/
uint16_t GetDestinationPort () const;
/**
* \return the sequence number for this TcpHeader
*/
SequenceNumber GetSequenceNumber () const;
/**
* \return the ACK number for this TcpHeader
*/
SequenceNumber GetAckNumber () const;
/**
* \return the length of this TcpHeader
*/
uint8_t GetLength () const;
/**
* \return the flags for this TcpHeader
*/
uint8_t GetFlags () const;
/**
* \return the window size for this TcpHeader
*/
uint16_t GetWindowSize () const;
/**
* \return the checksum for this TcpHeader
*/
uint16_t GetChecksum () const;
/**
* \return the urgent pointer for this TcpHeader
*/
uint16_t GetUrgentPointer () const;
/**
* \param source the ip source to use in the underlying
* ip packet.
* \param destination the ip destination to use in the
* underlying ip packet.
* \param protocol the protocol number to use in the underlying
* ip packet.
*
* If you want to use tcp checksums, you should call this
* method prior to adding the header to a packet.
*/
void InitializeChecksum (Ipv4Address source,
Ipv4Address destination,
uint8_t protocol);
typedef enum { NONE = 0, FIN = 1, SYN = 2, RST = 4, PSH = 8, ACK = 16,
URG = 32} Flags_t;
std::string GetName (void) const;
void Print (std::ostream &os) const;
uint32_t GetSerializedSize (void) const;
void Serialize (Buffer::Iterator start) const;
uint32_t Deserialize (Buffer::Iterator start);
private:
uint16_t m_sourcePort;
uint16_t m_destinationPort;
uint32_t m_sequenceNumber;
uint32_t m_ackNumber;
uint8_t m_length; // really a uint4_t
uint8_t m_flags; // really a uint6_t
uint16_t m_windowSize;
uint16_t m_checksum;
uint16_t m_urgentPointer;
static bool m_calcChecksum;
};
}; // namespace ns3
#endif /* TCP_HEADER */

View File

@@ -0,0 +1,48 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#include "tcp-impl.h"
#include "tcp-l4-protocol.h"
#include "ns3/socket.h"
#include "ns3/assert.h"
namespace ns3 {
TcpImpl::TcpImpl (Ptr<TcpL4Protocol> tcp)
: m_tcp (tcp)
{}
TcpImpl::~TcpImpl ()
{
NS_ASSERT (m_tcp == 0);
}
Ptr<Socket>
TcpImpl::CreateSocket (void)
{
return m_tcp->CreateSocket ();
}
void
TcpImpl::DoDispose (void)
{
m_tcp = 0;
Tcp::DoDispose ();
}
} // namespace ns3

View File

@@ -0,0 +1,58 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#ifndef TCP_IMPL_H
#define TCP_IMPL_H
#include "ns3/tcp.h"
#include "ns3/ptr.h"
namespace ns3 {
class TcpL4Protocol;
/**
* \ingroup InternetNode
* \defgroup Tcp Tcp
*
* \section Tcp Overview
*
* The TCP code in ns3::InternetNode is ported from the
* <a href="http://www.ece.gatech.edu/research/labs/MANIACS/GTNetS/">
* Georgia Tech Network Simulator (GTNetS)</a>.
*
* Most of the logic is in class ns3::TcpSocket.
*/
class TcpImpl : public Tcp
{
public:
TcpImpl (Ptr<TcpL4Protocol> tcp);
virtual ~TcpImpl ();
virtual Ptr<Socket> CreateSocket (void);
protected:
virtual void DoDispose (void);
private:
Ptr<TcpL4Protocol> m_tcp;
};
} // namespace ns3
#endif /* TCP_IMPL_H */

View File

@@ -0,0 +1,485 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#include "ns3/assert.h"
#include "ns3/log.h"
#include "ns3/nstime.h"
#include "ns3/packet.h"
#include "ns3/node.h"
#include "tcp-l4-protocol.h"
#include "tcp-header.h"
#include "ipv4-end-point-demux.h"
#include "ipv4-end-point.h"
#include "ipv4-l3-protocol.h"
#include "tcp-socket.h"
#include "tcp-typedefs.h"
#include <vector>
#include <sstream>
NS_LOG_COMPONENT_DEFINE ("TcpL4Protocol");
namespace ns3 {
//State Machine things --------------------------------------------------------
TcpStateMachine::TcpStateMachine()
: aT (LAST_STATE, StateActionVec_t(LAST_EVENT)),
eV (MAX_FLAGS)
{
NS_LOG_FUNCTION;
// Create the state table
// Closed state
aT[CLOSED][APP_LISTEN] = SA (LISTEN, NO_ACT);
aT[CLOSED][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
aT[CLOSED][APP_SEND] = SA (CLOSED, RST_TX);
aT[CLOSED][SEQ_RECV] = SA (CLOSED, NO_ACT);
aT[CLOSED][APP_CLOSE] = SA (CLOSED, NO_ACT);
aT[CLOSED][TIMEOUT] = SA (CLOSED, RST_TX);
aT[CLOSED][ACK_RX] = SA (CLOSED, RST_TX);
aT[CLOSED][SYN_RX] = SA (CLOSED, RST_TX);
aT[CLOSED][SYN_ACK_RX] = SA (CLOSED, RST_TX);
aT[CLOSED][FIN_RX] = SA (CLOSED, RST_TX);
aT[CLOSED][FIN_ACK_RX] = SA (CLOSED, RST_TX);
aT[CLOSED][RST_RX] = SA (CLOSED, CANCEL_TM);
aT[CLOSED][BAD_FLAGS] = SA (CLOSED, RST_TX);
// Listen State
// For the listen state, anything other than CONNECT or SEND
// is simply ignored....this likely indicates the child TCP
// has finished and issued unbind call, but the remote end
// has not yet closed.
aT[LISTEN][APP_LISTEN] = SA (LISTEN, NO_ACT);
aT[LISTEN][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
aT[LISTEN][APP_SEND] = SA (SYN_SENT, SYN_TX);
aT[LISTEN][SEQ_RECV] = SA (LISTEN, NO_ACT);
aT[LISTEN][APP_CLOSE] = SA (CLOSED, NO_ACT);
aT[LISTEN][TIMEOUT] = SA (LISTEN, NO_ACT);
aT[LISTEN][ACK_RX] = SA (LISTEN, NO_ACT);
aT[LISTEN][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX); //XXX hacked for now, should stay in listen and replicate
aT[LISTEN][SYN_ACK_RX] = SA (LISTEN, NO_ACT);
aT[LISTEN][FIN_RX] = SA (LISTEN, NO_ACT);
aT[LISTEN][FIN_ACK_RX] = SA (LISTEN, NO_ACT);
aT[LISTEN][RST_RX] = SA (LISTEN, NO_ACT);
aT[LISTEN][BAD_FLAGS] = SA (LISTEN, NO_ACT);
// Syn Sent State
aT[SYN_SENT][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[SYN_SENT][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
aT[SYN_SENT][APP_SEND] = SA (SYN_SENT, NO_ACT);
aT[SYN_SENT][SEQ_RECV] = SA (ESTABLISHED, NEW_SEQ_RX);
aT[SYN_SENT][APP_CLOSE] = SA (CLOSED, RST_TX);
aT[SYN_SENT][TIMEOUT] = SA (CLOSED, NO_ACT);
aT[SYN_SENT][ACK_RX] = SA (SYN_SENT, NO_ACT);
aT[SYN_SENT][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX);
aT[SYN_SENT][SYN_ACK_RX] = SA (ESTABLISHED, ACK_TX_1);
aT[SYN_SENT][FIN_RX] = SA (CLOSED, RST_TX);
aT[SYN_SENT][FIN_ACK_RX] = SA (CLOSED, RST_TX);
aT[SYN_SENT][RST_RX] = SA (CLOSED, APP_NOTIFY);
aT[SYN_SENT][BAD_FLAGS] = SA (CLOSED, RST_TX);
// Syn Recvd State
aT[SYN_RCVD][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[SYN_RCVD][APP_CONNECT] = SA (CLOSED, RST_TX);
aT[SYN_RCVD][APP_SEND] = SA (CLOSED, RST_TX);
aT[SYN_RCVD][SEQ_RECV] = SA (ESTABLISHED, NEW_SEQ_RX);
aT[SYN_RCVD][APP_CLOSE] = SA (FIN_WAIT_1, FIN_TX);
aT[SYN_RCVD][TIMEOUT] = SA (CLOSED, RST_TX);
aT[SYN_RCVD][ACK_RX] = SA (ESTABLISHED, SERV_NOTIFY);
aT[SYN_RCVD][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX);
aT[SYN_RCVD][SYN_ACK_RX] = SA (CLOSED, RST_TX);
aT[SYN_RCVD][FIN_RX] = SA (CLOSED, RST_TX);
aT[SYN_RCVD][FIN_ACK_RX] = SA (CLOSE_WAIT, PEER_CLOSE);
aT[SYN_RCVD][RST_RX] = SA (CLOSED, CANCEL_TM);
aT[SYN_RCVD][BAD_FLAGS] = SA (CLOSED, RST_TX);
// Established State
aT[ESTABLISHED][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[ESTABLISHED][APP_CONNECT]= SA (CLOSED, RST_TX);
aT[ESTABLISHED][APP_SEND] = SA (ESTABLISHED,TX_DATA);
aT[ESTABLISHED][SEQ_RECV] = SA (ESTABLISHED,NEW_SEQ_RX);
aT[ESTABLISHED][APP_CLOSE] = SA (FIN_WAIT_1, FIN_TX);
aT[ESTABLISHED][TIMEOUT] = SA (ESTABLISHED,RETX);
aT[ESTABLISHED][ACK_RX] = SA (ESTABLISHED,NEW_ACK);
aT[ESTABLISHED][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX);
aT[ESTABLISHED][SYN_ACK_RX] = SA (ESTABLISHED,NO_ACT);
aT[ESTABLISHED][FIN_RX] = SA (CLOSE_WAIT, PEER_CLOSE);
aT[ESTABLISHED][FIN_ACK_RX] = SA (CLOSE_WAIT, PEER_CLOSE);
aT[ESTABLISHED][RST_RX] = SA (CLOSED, CANCEL_TM);
aT[ESTABLISHED][BAD_FLAGS] = SA (CLOSED, RST_TX);
// Close Wait State
aT[CLOSE_WAIT][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[CLOSE_WAIT][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
aT[CLOSE_WAIT][APP_SEND] = SA (CLOSE_WAIT, TX_DATA);
aT[CLOSE_WAIT][SEQ_RECV] = SA (CLOSE_WAIT, NEW_SEQ_RX);
aT[CLOSE_WAIT][APP_CLOSE] = SA (LAST_ACK, FIN_ACK_TX);
aT[CLOSE_WAIT][TIMEOUT] = SA (CLOSE_WAIT, NO_ACT);
aT[CLOSE_WAIT][ACK_RX] = SA (CLOSE_WAIT, NO_ACT);
aT[CLOSE_WAIT][SYN_RX] = SA (CLOSED, RST_TX);
aT[CLOSE_WAIT][SYN_ACK_RX] = SA (CLOSED, RST_TX);
aT[CLOSE_WAIT][FIN_RX] = SA (CLOSE_WAIT, ACK_TX);
aT[CLOSE_WAIT][FIN_ACK_RX] = SA (CLOSE_WAIT, ACK_TX);
aT[CLOSE_WAIT][RST_RX] = SA (CLOSED, CANCEL_TM);
aT[CLOSE_WAIT][BAD_FLAGS] = SA (CLOSED, RST_TX);
// Close Last Ack State
aT[LAST_ACK][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[LAST_ACK][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
aT[LAST_ACK][APP_SEND] = SA (CLOSED, RST_TX);
aT[LAST_ACK][SEQ_RECV] = SA (LAST_ACK, NEW_SEQ_RX);
aT[LAST_ACK][APP_CLOSE] = SA (CLOSED, NO_ACT);
aT[LAST_ACK][TIMEOUT] = SA (CLOSED, NO_ACT);
aT[LAST_ACK][ACK_RX] = SA (CLOSED, APP_CLOSED);
aT[LAST_ACK][SYN_RX] = SA (CLOSED, RST_TX);
aT[LAST_ACK][SYN_ACK_RX] = SA (CLOSED, RST_TX);
aT[LAST_ACK][FIN_RX] = SA (LAST_ACK, FIN_ACK_TX);
aT[LAST_ACK][FIN_ACK_RX] = SA (CLOSED, NO_ACT);
aT[LAST_ACK][RST_RX] = SA (CLOSED, CANCEL_TM);
aT[LAST_ACK][BAD_FLAGS] = SA (CLOSED, RST_TX);
// FIN_WAIT_1 state
aT[FIN_WAIT_1][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_1][APP_CONNECT] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_1][APP_SEND] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_1][SEQ_RECV] = SA (FIN_WAIT_1, NEW_SEQ_RX);
aT[FIN_WAIT_1][APP_CLOSE] = SA (FIN_WAIT_1, NO_ACT);
aT[FIN_WAIT_1][TIMEOUT] = SA (FIN_WAIT_1, NO_ACT);
aT[FIN_WAIT_1][ACK_RX] = SA (FIN_WAIT_2, NEW_ACK);
aT[FIN_WAIT_1][SYN_RX] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_1][SYN_ACK_RX] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_1][FIN_RX] = SA (CLOSING, ACK_TX);
aT[FIN_WAIT_1][FIN_ACK_RX] = SA (TIMED_WAIT, ACK_TX);
aT[FIN_WAIT_1][RST_RX] = SA (CLOSED, CANCEL_TM);
aT[FIN_WAIT_1][BAD_FLAGS] = SA (CLOSED, RST_TX);
// FIN_WAIT_2 state
aT[FIN_WAIT_2][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_2][APP_CONNECT] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_2][APP_SEND] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_2][SEQ_RECV] = SA (FIN_WAIT_2, NO_ACT);
aT[FIN_WAIT_2][APP_CLOSE] = SA (FIN_WAIT_2, NO_ACT);
aT[FIN_WAIT_2][TIMEOUT] = SA (FIN_WAIT_2, NO_ACT);
aT[FIN_WAIT_2][ACK_RX] = SA (FIN_WAIT_2, NEW_ACK);
aT[FIN_WAIT_2][SYN_RX] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_2][SYN_ACK_RX] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_2][FIN_RX] = SA (TIMED_WAIT, ACK_TX);
aT[FIN_WAIT_2][FIN_ACK_RX] = SA (TIMED_WAIT, ACK_TX);
aT[FIN_WAIT_2][RST_RX] = SA (CLOSED, CANCEL_TM);
aT[FIN_WAIT_2][BAD_FLAGS] = SA (CLOSED, RST_TX);
// CLOSING state
aT[CLOSING][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[CLOSING][APP_CONNECT] = SA (CLOSED, RST_TX);
aT[CLOSING][APP_SEND] = SA (CLOSED, RST_TX);
aT[CLOSING][SEQ_RECV] = SA (CLOSED, RST_TX);
aT[CLOSING][APP_CLOSE] = SA (CLOSED, RST_TX);
aT[CLOSING][TIMEOUT] = SA (CLOSING, NO_ACT);
aT[CLOSING][ACK_RX] = SA (TIMED_WAIT, NO_ACT);
aT[CLOSING][SYN_RX] = SA (CLOSED, RST_TX);
aT[CLOSING][SYN_ACK_RX] = SA (CLOSED, RST_TX);
aT[CLOSING][FIN_RX] = SA (CLOSED, ACK_TX);
aT[CLOSING][FIN_ACK_RX] = SA (CLOSED, ACK_TX);
aT[CLOSING][RST_RX] = SA (CLOSED, CANCEL_TM);
aT[CLOSING][BAD_FLAGS] = SA (CLOSED, RST_TX);
// TIMED_WAIT state
aT[TIMED_WAIT][APP_LISTEN] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][APP_CONNECT] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][APP_SEND] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][SEQ_RECV] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][APP_CLOSE] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][TIMEOUT] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][ACK_RX] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][SYN_RX] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][SYN_ACK_RX] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][FIN_RX] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][FIN_ACK_RX] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][RST_RX] = SA (TIMED_WAIT, NO_ACT);
aT[TIMED_WAIT][BAD_FLAGS] = SA (TIMED_WAIT, NO_ACT);
// Create the flags lookup table
eV[ 0x00] = SEQ_RECV; // No flags
eV[ 0x01] = FIN_RX; // Fin
eV[ 0x02] = SYN_RX; // Syn
eV[ 0x03] = BAD_FLAGS; // Illegal
eV[ 0x04] = RST_RX; // Rst
eV[ 0x05] = BAD_FLAGS; // Illegal
eV[ 0x06] = BAD_FLAGS; // Illegal
eV[ 0x07] = BAD_FLAGS; // Illegal
eV[ 0x08] = SEQ_RECV; // Psh flag is not used
eV[ 0x09] = FIN_RX; // Fin
eV[ 0x0a] = SYN_RX; // Syn
eV[ 0x0b] = BAD_FLAGS; // Illegal
eV[ 0x0c] = RST_RX; // Rst
eV[ 0x0d] = BAD_FLAGS; // Illegal
eV[ 0x0e] = BAD_FLAGS; // Illegal
eV[ 0x0f] = BAD_FLAGS; // Illegal
eV[ 0x10] = ACK_RX; // Ack
eV[ 0x11] = FIN_ACK_RX;// Fin/Ack
eV[ 0x12] = SYN_ACK_RX;// Syn/Ack
eV[ 0x13] = BAD_FLAGS; // Illegal
eV[ 0x14] = RST_RX; // Rst
eV[ 0x15] = BAD_FLAGS; // Illegal
eV[ 0x16] = BAD_FLAGS; // Illegal
eV[ 0x17] = BAD_FLAGS; // Illegal
eV[ 0x18] = ACK_RX; // Ack
eV[ 0x19] = FIN_ACK_RX;// Fin/Ack
eV[ 0x1a] = SYN_ACK_RX;// Syn/Ack
eV[ 0x1b] = BAD_FLAGS; // Illegal
eV[ 0x1c] = RST_RX; // Rst
eV[ 0x1d] = BAD_FLAGS; // Illegal
eV[ 0x1e] = BAD_FLAGS; // Illegal
eV[ 0x1f] = BAD_FLAGS; // Illegal
eV[ 0x20] = SEQ_RECV; // No flags (Urgent not presently used)
eV[ 0x21] = FIN_RX; // Fin
eV[ 0x22] = SYN_RX; // Syn
eV[ 0x23] = BAD_FLAGS; // Illegal
eV[ 0x24] = RST_RX; // Rst
eV[ 0x25] = BAD_FLAGS; // Illegal
eV[ 0x26] = BAD_FLAGS; // Illegal
eV[ 0x27] = BAD_FLAGS; // Illegal
eV[ 0x28] = SEQ_RECV; // Psh flag is not used
eV[ 0x29] = FIN_RX; // Fin
eV[ 0x2a] = SYN_RX; // Syn
eV[ 0x2b] = BAD_FLAGS; // Illegal
eV[ 0x2c] = RST_RX; // Rst
eV[ 0x2d] = BAD_FLAGS; // Illegal
eV[ 0x2e] = BAD_FLAGS; // Illegal
eV[ 0x2f] = BAD_FLAGS; // Illegal
eV[ 0x30] = ACK_RX; // Ack (Urgent not used)
eV[ 0x31] = FIN_ACK_RX;// Fin/Ack
eV[ 0x32] = SYN_ACK_RX;// Syn/Ack
eV[ 0x33] = BAD_FLAGS; // Illegal
eV[ 0x34] = RST_RX; // Rst
eV[ 0x35] = BAD_FLAGS; // Illegal
eV[ 0x36] = BAD_FLAGS; // Illegal
eV[ 0x37] = BAD_FLAGS; // Illegal
eV[ 0x38] = ACK_RX; // Ack
eV[ 0x39] = FIN_ACK_RX;// Fin/Ack
eV[ 0x3a] = SYN_ACK_RX;// Syn/Ack
eV[ 0x3b] = BAD_FLAGS; // Illegal
eV[ 0x3c] = RST_RX; // Rst
eV[ 0x3d] = BAD_FLAGS; // Illegal
eV[ 0x3e] = BAD_FLAGS; // Illegal
eV[ 0x3f] = BAD_FLAGS; // Illegal
}
SA TcpStateMachine::Lookup (States_t s, Events_t e)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << s << e);
return aT[s][e];
}
Events_t TcpStateMachine::FlagsEvent (uint8_t f)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << f);
// Lookup event from flags
if (f >= MAX_FLAGS) return BAD_FLAGS;
return eV[f]; // Look up flags event
}
static TcpStateMachine tcpStateMachine; //only instance of a TcpStateMachine
//TcpL4Protocol stuff----------------------------------------------------------
/* see http://www.iana.org/assignments/protocol-numbers */
const uint8_t TcpL4Protocol::PROT_NUMBER = 6;
TcpL4Protocol::TcpL4Protocol (Ptr<Node> node)
: Ipv4L4Protocol (PROT_NUMBER, 2),
m_node (node),
m_endPoints (new Ipv4EndPointDemux ())
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << node);
NS_LOG_LOGIC("Made a TcpL4Protocol "<<this);
}
TcpL4Protocol::~TcpL4Protocol ()
{
NS_LOG_FUNCTION;
}
void
TcpL4Protocol::DoDispose (void)
{
NS_LOG_FUNCTION;
if (m_endPoints != 0)
{
delete m_endPoints;
m_endPoints = 0;
}
m_node = 0;
Ipv4L4Protocol::DoDispose ();
}
Ptr<Socket>
TcpL4Protocol::CreateSocket (void)
{
NS_LOG_FUNCTION;
Ptr<Socket> socket = Create<TcpSocket> (m_node, this);
return socket;
}
Ipv4EndPoint *
TcpL4Protocol::Allocate (void)
{
NS_LOG_FUNCTION;
return m_endPoints->Allocate ();
}
Ipv4EndPoint *
TcpL4Protocol::Allocate (Ipv4Address address)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address);
return m_endPoints->Allocate (address);
}
Ipv4EndPoint *
TcpL4Protocol::Allocate (uint16_t port)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << port);
return m_endPoints->Allocate (port);
}
Ipv4EndPoint *
TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address << port);
return m_endPoints->Allocate (address, port);
}
Ipv4EndPoint *
TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
return m_endPoints->Allocate (localAddress, localPort,
peerAddress, peerPort);
}
void
TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << endPoint);
m_endPoints->DeAllocate (endPoint);
}
void
TcpL4Protocol::Receive (Ptr<Packet> packet,
Ipv4Address const &source,
Ipv4Address const &destination,
Ptr<Ipv4Interface> incomingInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << packet << source << destination << incomingInterface);
TcpHeader tcpHeader;
//these two do a peek, so that the packet can be forwarded up
packet->RemoveHeader (tcpHeader);
packet->AddHeader (tcpHeader);
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
Ipv4EndPointDemux::EndPoints endPoints =
m_endPoints->Lookup (destination, tcpHeader.GetDestinationPort (),
source, tcpHeader.GetSourcePort (),incomingInterface);
if (endPoints.empty ())
{
NS_LOG_LOGIC (" No endpoints matched on TcpL4Protocol "<<this);
std::ostringstream oss;
oss<<" destination IP: ";
destination.Print (oss);
oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
source.Print (oss);
oss<<" source port: "<<tcpHeader.GetSourcePort ();
NS_LOG_LOGIC (oss.str ());
}
for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
endPoint != endPoints.end (); endPoint++)
{
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
(*endPoint)->ForwardUp (packet, source, tcpHeader.GetSourcePort ());
}
}
void
TcpL4Protocol::Send (Ptr<Packet> packet,
Ipv4Address saddr, Ipv4Address daddr,
uint16_t sport, uint16_t dport)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << packet << saddr << daddr << sport << dport);
TcpHeader tcpHeader;
tcpHeader.SetDestinationPort (dport);
tcpHeader.SetSourcePort (sport);
tcpHeader.InitializeChecksum (saddr,
daddr,
PROT_NUMBER);
tcpHeader.SetFlags (TcpHeader::ACK);
tcpHeader.SetAckNumber (0);
packet->AddHeader (tcpHeader);
Ptr<Ipv4L3Protocol> ipv4 =
m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
if (ipv4 != 0)
{
ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
}
}
void
TcpL4Protocol::SendPacket (Ptr<Packet> packet, TcpHeader outgoingHeader,
Ipv4Address saddr, Ipv4Address daddr)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << packet << saddr << daddr);
// XXX outgoingHeader cannot be logged
outgoingHeader.SetLength (5); //header length in units of 32bit words
outgoingHeader.SetChecksum (0); //XXX
outgoingHeader.SetUrgentPointer (0); //XXX
packet->AddHeader (outgoingHeader);
Ptr<Ipv4L3Protocol> ipv4 =
m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
if (ipv4 != 0)
{
ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
}
else
NS_FATAL_ERROR("Trying to use Tcp on a node without an Ipv4 interface");
}
}; // namespace ns3

View File

@@ -0,0 +1,111 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#ifndef TCP_L4_PROTOCOL_H
#define TCP_L4_PROTOCOL_H
#include <stdint.h>
#include "ns3/packet.h"
#include "ns3/ipv4-address.h"
#include "ns3/ptr.h"
#include "ipv4-end-point-demux.h"
#include "ipv4-l4-protocol.h"
#include "ipv4-interface.h"
#include "tcp-header.h"
#include "tcp-typedefs.h"
namespace ns3 {
class Node;
class TraceResolver;
class TraceContext;
class Socket;
class TcpHeader;
/**
* \brief Implementation of the TCP protocol
*/
class TcpL4Protocol : public Ipv4L4Protocol {
public:
static const uint8_t PROT_NUMBER;
/**
* \brief Constructor
* \param node The node this protocol is associated with
*/
TcpL4Protocol (Ptr<Node> node);
virtual ~TcpL4Protocol ();
/**
* \return A smart Socket pointer to a TcpSocket, allocated by this instance
* of the TCP protocol
*/
Ptr<Socket> CreateSocket (void);
Ipv4EndPoint *Allocate (void);
Ipv4EndPoint *Allocate (Ipv4Address address);
Ipv4EndPoint *Allocate (uint16_t port);
Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort);
void DeAllocate (Ipv4EndPoint *endPoint);
// // called by TcpSocket.
// bool Connect (const Ipv4Address& saddr, const Ipv4Address& daddr,
// uint16_t sport, uint16_t dport);
/**
* \brief Send a packet via TCP
* \param packet The packet to send
* \param saddr The source Ipv4Address
* \param daddr The destination Ipv4Address
* \param sport The source port number
* \param dport The destination port number
*/
void Send (Ptr<Packet> packet,
Ipv4Address saddr, Ipv4Address daddr,
uint16_t sport, uint16_t dport);
/**
* \brief Recieve a packet up the protocol stack
* \param p The Packet to dump the contents into
* \param source The source's Ipv4Address
* \param destination The destinations Ipv4Address
* \param incomingInterface The Ipv4Interface it was received on
*/
virtual void Receive (Ptr<Packet> p,
Ipv4Address const &source,
Ipv4Address const &destination,
Ptr<Ipv4Interface> incomingInterface);
protected:
virtual void DoDispose (void);
private:
Ptr<Node> m_node;
Ipv4EndPointDemux *m_endPoints;
private:
friend class TcpSocket;
void SendPacket (Ptr<Packet>, TcpHeader,
Ipv4Address, Ipv4Address);
};
}; // namespace ns3
#endif /* TCP_L4_PROTOCOL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,161 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#ifndef TCP_SOCKET_H
#define TCP_SOCKET_H
#include <stdint.h>
#include "ns3/callback.h"
#include "ns3/socket.h"
#include "ns3/ptr.h"
#include "ns3/ipv4-address.h"
#include "ns3/event-id.h"
#include "tcp-typedefs.h"
#include "pending-data.h"
#include "sequence-number.h"
#include "rtt-estimator.h"
namespace ns3 {
class Ipv4EndPoint;
class Node;
class Packet;
class TcpL4Protocol;
class TcpHeader;
class TcpSocket : public Socket
{
public:
/**
* Create an unbound tcp socket.
*/
TcpSocket (Ptr<Node> node, Ptr<TcpL4Protocol> tcp);
virtual ~TcpSocket ();
virtual enum SocketErrno GetErrno (void) const;
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
virtual int Bind (const Address &address);
virtual int Close (void);
virtual int ShutdownSend (void);
virtual int ShutdownRecv (void);
virtual int Connect(const Address &address);
virtual int Send (Ptr<Packet> p);
virtual int Send (const uint8_t* buf, uint32_t size);
virtual int SendTo(const Address &address, Ptr<Packet> p);
virtual int Listen(uint32_t queueLimit);
private:
friend class Tcp;
// invoked by Tcp class
int FinishBind (void);
void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
void Destroy (void);
int DoSendTo (Ptr<Packet> p, const Address &daddr);
int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
void SendEmptyPacket(uint8_t flags);
//methods for state
bool ProcessAction (Actions_t a);
bool ProcessAction (Actions_t a, const TcpHeader& tcpHeader,
Ipv4Address saddr, Ipv4Address daddr);
bool ProcessPacketAction (Actions_t a, Ptr<Packet> p,
const TcpHeader& tcpHeader,
const Address& fromAddress);
Actions_t ProcessEvent (Events_t e);
bool SendPendingData(bool withAck = false);
//methods for window management
virtual uint32_t UnAckDataCount(); // Return count of number of unacked bytes
virtual uint32_t BytesInFlight(); // Return total bytes in flight
virtual uint32_t Window(); // Return window size (integer)
virtual uint32_t AvailableWindow();// Return unfilled portion of window
// Manage data tx/rx
void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
// XXX This should be virtual and overridden
void NewAck (SequenceNumber seq);
// XXX This should be virtual and overridden
void DupAck (const TcpHeader& t, uint32_t count);
void ReTxTimeout ();
void LastAckTimeout ();
void Retransmit ();
void CommonNewAck (SequenceNumber seq, bool skipTimer = false);
bool m_skipRetxResched;
uint32_t m_dupAckCount;
EventId m_retxEvent;
EventId m_lastAckEvent;
Ipv4EndPoint *m_endPoint;
Ptr<Node> m_node;
Ptr<TcpL4Protocol> m_tcp;
Ipv4Address m_defaultAddress;
uint16_t m_defaultPort;
Callback<void, Ptr<Socket>, uint32_t, const Address &> m_dummyRxCallback;
Callback<void, Ptr<Socket>, uint8_t const*, uint32_t, const Address &>
m_rxCallback;
enum SocketErrno m_errno;
bool m_shutdownSend;
bool m_shutdownRecv;
bool m_connected;
//manage the state infomation
States_t m_state;
bool m_closeNotified;
bool m_closeRequestNotified;
bool m_closeOnEmpty;
bool m_pendingClose;
//sequence info, sender side
SequenceNumber m_nextTxSequence;
SequenceNumber m_highTxMark;
SequenceNumber m_highestRxAck;
SequenceNumber m_lastRxAck;
//sequence info, reciever side
SequenceNumber m_nextRxSequence;
SequenceNumber m_nextAckSequence;
//history data
UnAckData_t m_bufferedData;
PendingData* m_pendingData;
SequenceNumber m_firstPendingSequence;
// Window management
uint32_t m_segmentSize; // SegmentSize
uint32_t m_rxWindowSize;
uint32_t m_advertisedWindowSize; // Window to advertise to peer
uint32_t m_cWnd; // Congestion window
uint32_t m_ssThresh; // Slow Start Threshold
uint32_t m_initialCWnd; // Initial (and reset) value for cWnd
// Round trip time estimation
Ptr<RttEstimator> m_rtt;
Time m_lastMeasuredRtt;
// Timer-related members
Time m_cnTimeout;
uint32_t m_cnCount;
};
}//namespace ns3
#endif /* UDP_SOCKET_H */

View File

@@ -0,0 +1,111 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
* typedefs for tcp state machine
*/
#include <vector>
#include <map>
#include "sequence-number.h"
#ifndef TCP_TYPEDEFS_H
#define TCP_TYPEDEFS_H
namespace ns3 {
typedef enum { MAX_FLAGS = 0x40 } TCPMaxFlags_t; // Flags are 6 bits
typedef enum {
CLOSED, // 0
LISTEN, // 1
SYN_SENT, // 2
SYN_RCVD, // 3
ESTABLISHED, // 4
CLOSE_WAIT, // 5
LAST_ACK, // 6
FIN_WAIT_1, // 7
FIN_WAIT_2, // 8
CLOSING, // 9
TIMED_WAIT, // 10
LAST_STATE } States_t;
typedef enum {
APP_LISTEN, // 0
APP_CONNECT, // 1
APP_SEND, // 2
SEQ_RECV, // 3
APP_CLOSE, // 4
TIMEOUT, // 5
ACK_RX, // 6
SYN_RX, // 7
SYN_ACK_RX, // 8
FIN_RX, // 9
FIN_ACK_RX, // 10
RST_RX, // 11
BAD_FLAGS, // 12
LAST_EVENT } Events_t;
typedef enum {
NO_ACT, // 0
ACK_TX, // 1
ACK_TX_1, // ACK response to syn
RST_TX, // 2
SYN_TX, // 3
SYN_ACK_TX, // 4
FIN_TX, // 5
FIN_ACK_TX, // 6
NEW_ACK, // 7
NEW_SEQ_RX, // 8
RETX, // 9
TX_DATA, // 10
PEER_CLOSE, // 11
APP_CLOSED, // 12
CANCEL_TM, // 13
APP_NOTIFY, // 14 - Notify app that connection failed
SERV_NOTIFY, // 15 - Notify server tcp that connection completed
LAST_ACTION } Actions_t;
class SA // State/Action pair
{
public:
SA () : state (LAST_STATE), action (LAST_ACTION) { }
SA (States_t s, Actions_t a) : state (s), action (a) { }
public:
States_t state;
Actions_t action;
};
typedef std::vector<SA> StateActionVec_t;
typedef std::vector<StateActionVec_t> StateActions_t; // One per current state
typedef std::vector<Events_t> EventVec_t; // For flag events lookup
//type for managing buffered out of sequence data
typedef std::map<SequenceNumber, Ptr<Packet> > UnAckData_t;
class TcpStateMachine {
public:
TcpStateMachine ();
SA Lookup (States_t, Events_t);
Events_t FlagsEvent (uint8_t); // Lookup event from flags
public:
StateActions_t aT; // Action table
EventVec_t eV; // Flags event lookup
};
}//namespace ns3
#endif //TCP_TYPEDEFS_H

View File

@@ -9,23 +9,30 @@ def build(bld):
'ipv4-l4-protocol.cc',
'ipv4-header.cc',
'udp-header.cc',
'tcp-header.cc',
'ipv4-checksum.cc',
'ipv4-interface.cc',
'ipv4-l3-protocol.cc',
'ipv4-static-routing.cc',
'ipv4-end-point.cc',
'udp-l4-protocol.cc',
'tcp-l4-protocol.cc',
'arp-header.cc',
'arp-cache.cc',
'arp-ipv4-interface.cc',
'arp-l3-protocol.cc',
'ipv4-loopback-interface.cc',
'udp-socket.cc',
'tcp-socket.cc',
'ipv4-end-point-demux.cc',
'ipv4-impl.cc',
'ascii-trace.cc',
'pcap-trace.cc',
'udp-impl.cc',
'tcp-impl.cc',
'pending-data.cc',
'sequence-number.cc',
'rtt-estimator.cc',
]
headers = bld.create_obj('ns3header')
@@ -35,4 +42,5 @@ def build(bld):
'pcap-trace.h',
'ipv4-header.h',
'udp-header.h',
'tcp-header.h',
]

View File

@@ -108,6 +108,12 @@ int Socket::SendTo (const Address &address, const uint8_t* buf, uint32_t size)
return SendTo (address,p);
}
int Socket::Listen(uint32_t queueLimit)
{
return 0; //XXX the base class version does nothing
}
void
Socket::NotifyCloseCompleted (void)
{

View File

@@ -196,6 +196,13 @@ public:
*/
virtual int SendTo(const Address &address,Ptr<Packet> p) = 0;
/**
* \brief Listen for incoming connections.
* \param queueLimit maximum number of incoming request to queue
* \returns XXX an error code
*/
virtual int Listen(uint32_t queueLimit);
/**
* \brief Send data to a specified peer.
* \param address IP Address of remote host

71
src/node/tcp.cc Normal file
View File

@@ -0,0 +1,71 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#include "tcp.h"
namespace ns3 {
NumericDefaultValue<uint32_t> Tcp::defaultSegSize
("TcpDefaultSegmentSize",
"Default TCP maximum segment size in bytes (may be adjusted based on MTU discovery)",
536);
NumericDefaultValue<uint32_t> Tcp::defaultAdvWin
("TcpDefaultAdvertisedWindowSize",
"Default TCP advertised window size (bytes)",
0xffff);
NumericDefaultValue<uint32_t> Tcp::defaultSSThresh
("TcpDefaultSlowStartThreshold",
"Default TCP slow start threshold (bytes)",
0xffff);
NumericDefaultValue<uint32_t> Tcp::defaultTxBuffer
("TcpDefaultTxBufferSize",
"Default TCP maximum transmit buffer size (bytes)",
0xffffffffl);
NumericDefaultValue<uint32_t> Tcp::defaultRxBuffer
("TcpDefaultRxBufferSize",
"Default TCP maximum receive buffer size (bytes)",
0xffffffffl);
NumericDefaultValue<uint32_t> Tcp::defaultInitialCWnd
("TcpDefaultInitialCongestionWindowSize",
"Default TCP initial congestion window size (segments)",
1);
NumericDefaultValue<uint32_t> Tcp::defaultConnTimeout
("TcpDefaultConnTimeout",
"Default TCP retransmission timeout when opening connection (seconds)",
6);
NumericDefaultValue<uint32_t> Tcp::defaultConnCount
("TcpDefaultConnCount",
"Default number of connection attempts (SYN retransmissions) before returning failure",
3);
const InterfaceId Tcp::iid = MakeInterfaceId ("Tcp", SocketFactory::iid);
Tcp::Tcp ()
{
SetInterfaceId (Tcp::iid);
}
} // namespace ns3

67
src/node/tcp.h Normal file
View File

@@ -0,0 +1,67 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Georgia Tech Research Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#ifndef TCP_H
#define TCP_H
#include "ns3/default-value.h"
#include "socket-factory.h"
namespace ns3 {
class Socket;
/**
* \brief API to create TCP socket instances
*
* This abstract class defines the API for TCP sockets.
* This class also holds the global default variables used to
* initialize newly created sockets, such as values that are
* set through the sysctl or proc interfaces in Linux.
* All TCP implementations must provide an implementation of CreateSocket
* below, and should make use of the default values configured below.
*
* \see TcpImpl
*
*/
class Tcp : public SocketFactory
{
public:
static const InterfaceId iid;
Tcp ();
virtual Ptr<Socket> CreateSocket (void) = 0;
public:
static NumericDefaultValue<uint32_t> defaultSegSize;
static NumericDefaultValue<uint32_t> defaultAdvWin;
static NumericDefaultValue<uint32_t> defaultSSThresh;
static NumericDefaultValue<uint32_t> defaultTxBuffer;
static NumericDefaultValue<uint32_t> defaultRxBuffer;
static NumericDefaultValue<uint32_t> defaultInitialCWnd;
static NumericDefaultValue<uint32_t> defaultConnTimeout;
static NumericDefaultValue<uint32_t> defaultConnCount;
};
} // namespace ns3
#endif /* UDP_H */

View File

@@ -25,6 +25,7 @@ def build(bld):
'packet-socket-factory.cc',
'packet-socket.cc',
'udp.cc',
'tcp.cc',
'ipv4.cc',
'application.cc',
]
@@ -52,6 +53,7 @@ def build(bld):
'socket-factory.h',
'packet-socket-factory.h',
'udp.h',
'tcp.h',
'ipv4.h',
'application.h',
]