merge with HEAD

This commit is contained in:
Mathieu Lacage
2008-05-27 15:01:11 -07:00
76 changed files with 2099 additions and 665 deletions

View File

@@ -7,7 +7,7 @@ CONVERT = convert
CSS = --css-include=tutorial.css
SPLIT = --split section
DIA_SOURCES = buffer.dia pp.dia dumbbell.dia star.dia
DIA_SOURCES = buffer.dia pp.dia dumbbell.dia star.dia sockets-overview.dia
TGIF_SOURCES = packet.obj helpers.obj
DIA_EPS = ${DIA_SOURCES:.dia=.eps}

Binary file not shown.

243
doc/tutorial/sockets.texi Normal file
View File

@@ -0,0 +1,243 @@
@node Sockets APIs
@chapter Sockets APIs
The @uref{http://en.wikipedia.org/wiki/Berkeley_sockets,,sockets API}
is a long-standing API used by user-space applications to access
network services in the kernel. A ``socket'' is an abstraction, like
a Unix file handle, that allows applications to connect to other
Internet hosts and exchange reliable byte streams and unreliable
datagrams, among other services.
ns-3 provides two types of sockets APIs, and it is important to
understand the differences between them. The first is a @emph{native}
ns-3 API, while the second uses the services of the native API to
provide a @uref{http://en.wikipedia.org/wiki/POSIX,,POSIX-like}
API as part of an overall application process. Both APIs strive
to be close to the typical sockets API that application writers
on Unix systems are accustomed to, but the POSIX variant is much
closer to a real system's sockets API.
@section ns-3 sockets API
The native sockets API for ns-3 provides an interface to various
types of transport protocols (TCP, UDP) as well as to packet sockets
and, in the future, Netlink-like sockets. However, users are cautioned
to understand that the semantics are @strong{not} the exact same as
one finds in a real system (for an API which is very much aligned
to real systems, see the next section).
@code{class ns3::Socket} is defined in @code{src/node/socket.cc,h}.
Readers will note that many public member functions are aligned
with real sockets function calls, and all other things being equal,
we have tried to align with a Posix sockets API. However, note that:
@itemize @bullet
@item ns-3 applications handle a smart pointer to a Socket object, not
a file descriptor;
@item there is no notion of synchronous API or a ``blocking'' API;
in fact, the model for interaction between application and socket is
one of asynchronous I/O, which is not typically found in real systems
(more on this below);
@item the C-style socket address structures are not used;
@item the API is not a complete sockets API, such as supporting
all socket options or all function variants;
@item many calls use @code{ns3::Packet} class to transfer data
between application and socket. This may seem a little funny to
people to pass ``Packets'' across a stream socket API, but think
of these packets as just fancy byte buffers at this level (more
on this also below).
@end itemize
@subsection Basic operation and calls
@float Figure,fig:sockets-overview
@caption{Implementation overview of native sockets API}
@image{figures/sockets-overview, 10cm}
@end float
@subsubsection Creating sockets
An application that wants to use sockets must first create one.
On real systems, this is accomplished by calling socket():
@verbatim
int
socket(int domain, int type, int protocol);
@end verbatim
which creates a socket in the system and returns an integer descriptor.
In ns-3, we have no equivalent of a system call at the lower layers,
so we adopt the following model. There are certain @emph{factory}
objects that can create sockets. Each factory is capable of creating
one type of socket, and if sockets of a particular type are able to
be created on a given node, then a factory that can create such sockets
must be aggregated to the Node.
@verbatim
static Ptr<Socket> CreateSocket (Ptr<Node> node, TypeId tid);
@end verbatim
Examples of TypeIds to pass to this method are @code{TcpSocketFactory},
@code{PacketSocketFactory}, and @code{UdpSocketFactory}.
This method returns a smart pointer to a Socket object. Here is an
example:
@verbatim
Ptr<Node> n0;
// Do some stuff to build up the Node's internet stack
Ptr<Socket> localSocket = Socket::CreateSocket (n0, TcpSocketFactory::GetTypeId ());
@end verbatim
In some ns-3 code, sockets will not be explicitly created by user's
main programs, if an ns-3 application does it. For instance, for
@code{class ns3::OnOffApplication}, the function @code{StartApplication()}
performs the socket creation, and the application holds the socket
pointer.
@subsubsection Using sockets
Below is a typical sequence of socket calls for a TCP client in a
real implementation:
@itemize @bullet
@item @code{sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);}
@item @code{bind(sock, ...);}
@item @code{connect(sock, ...);}
@item @code{send(sock, ...);}
@item @code{recv(sock, ...);}
@item @code{close(sock);}
@end itemize
There are analogs to all of these calls in ns-3, but we will focus on
two aspects here. First, most usage of sockets in real systems
requires a way to manage I/O between the application and kernel.
These models include @emph{blocking sockets}, @emph{signal-based I/O},
and @emph{non-blocking sockets} with polling. In ns-3, we make use
of the callback mechanisms to support a fourth mode, which is
analogous to POSIX @emph{asynchronous I/O}.
In this model, on the sending side, if the @code{send()} call were to
fail because of insufficient buffers, the application suspends the
sending of more data until a function registered at the
@code{SetSendCallback()} callback is invoked. An application can
also ask the socket how much space is available by calling
@code{GetTxAvailable ()}. A typical sequence of events for
sending data (ignoring connection setup) might be:
@itemize @bullet
@item @code{SetSendCallback (MakeCallback(&HandleSendCallback));}
@item @code{Send ();}
@item @code{Send ();}
@item ...
@item @code{// Send fails because buffer is full}
@item (wait until HandleSendCallback() is called)
@item (HandleSendCallback() is called by socket, since space now available)
@item @code{Send (); // Start sending again}
@end itemize
Similarly, on the receive side, the socket user does not block on
a call to @code{recv()}. Instead, the application sets a callback
with @code{SetRecvCallback ()} in which the socket will notify the
application when (and how much) there is data to be read, and
the application then calls @code{Recv()} to read the data until
no more can be read.
@subsection Packet vs. buffer variants
There are two basic variants of @code{Send()} and @code{Recv()} supported:
@verbatim
virtual int Send (Ptr<Packet> p) = 0;
int Send (const uint8_t* buf, uint32_t size);
Ptr<Packet> Recv (void);
int Recv (uint8_t* buf, uint32_t size);
@end verbatim
The non-Packet variants are left for legacy API reasons. When calling
the raw buffer variant of @code{Send()}, the buffer is immediately
written into a Packet and the @code{Send (Ptr<Packet> p)} is invoked.
Users may find it semantically odd to pass a Packet to a stream socket
such as TCP. However, do not let the name bother you; think of
@code{ns3::Packet} to be a fancy byte buffer. There are a few reasons why
the Packet variants are more likely to be preferred in ns-3:
@itemize @bullet
@item Users can use the Tags facility of packets to, for example, encode
a flow ID or other helper data.
@item Users can exploit the copy-on-write implementation to avoid
memory copies (on the receive side, the conversion back to a
@code{uint8_t* buf} may sometimes incur an additional copy).
@item Use of Packet is more aligned with the rest of the ns-3 API
@end itemize
@subsection Sending dummy data
Sometimes, users want the simulator to just pretend that there is an
actual data payload in the packet (e.g. to calculate transmission delay)
but do not want to actually produce or consume the data. This is
straightforward to support in ns-3; have applications call
@code{Create<Packet> (size);} instead of @code{Create<Packet> (buffer, size);}.
Similarly, passing in a zero to the pointer argument in the raw buffer
variants has the same effect. Note that, if some subsequent code tries
to read the Packet data buffer, the fake buffer will be converted to
a real (zero'ed) buffer on the spot, and the efficiency will be lost there.
@subsection Socket options
@emph{to be completed}
@subsection Socket errno
@emph{to be completed}
@subsection Example programs
@emph{to be completed}
@section POSIX-like sockets API
@emph{this capability is under development and is scheduled for
inclusion in August 2008 timeframe; see the repository
http://code.nsnam.org/mathieu/ns-3-simu for details}
The below is excerpted from Mathieu's post to ns-developers list
on April 4, 2008.
"To summarize, the goal is that the full posix/socket API is defined in
src/process/simu.h: each posix type and function is re-defined there
with a simu_ or SIMU_ prefix to avoid ugly name clashes and collisions
(feel free to come up with a better prefix).
Each process is created with a call to ProcessManager::Create and is
attached to that ProcessManager instance. So, if the ProcessManager
(which is aggregated to a Node in src/helper/process-helper.cc) is
killed when the simulation ends, the system will automatically reclaim
all the resources of each process associated to each manager. The same
happens when an application "exits" from its main function.
The example application defines two posix "processes": the function
ClientProgram creates a udp socket on the localhost port 2000 and the
function ServerProgram creates a udp socket on the localhost port 2000.
The code does not work right now because I did not get the details of
simu_read right yet but, I do plan to make this work at some point.
I really think that this approach is worthwhile for many reasons, a few
of which are outlined below:
@itemize @bullet
@item makes porting real world application code _much_ easier
@item makes write applications for new users much easier because they can
read the bsd socket api reference and documentation and write code
directly.
@item can be used to write applications which work in both simulation and
in the real world at the same time. To do this, all you have to do is
write your application to use the simu_ API, and, then, you can chose at
compile-time which implementation of that API you want to use: you can
pick one implementation which forwards all calls to the system BSD
socket API or another one which forwards all calls to the attached
ProcessManager. Arguably, I did not implement the version which forwards
to system BSD sockets but, that should be pretty trivial.
@end itemize
So, anyway, comments about the overall API would be welcome. Students
interested in the gsoc project for real-world code integration should
consider looking at this also."

View File

@@ -95,9 +95,10 @@ Part 4: Creating New or Revised Topologies
* Other-network-topologies::
Part 5: Key ns-3 objects and systems
* ns-3 Packets::
Part 6: Extending ns-3
* ns-3 Callbacks::
* Sockets APIs::
* ns-3 routing overview::
Part 6: Extending ns-3
* Nonlinear-Thinking::
* Summary::
* Object-Model::
@@ -115,6 +116,7 @@ Part 6: Extending ns-3
@include helpers.texi
@include packets.texi
@include callbacks.texi
@include sockets.texi
@c @include output.texi
@include routing.texi
@c @include other.texi

View File

@@ -49,6 +49,7 @@ main (int argc, char *argv[])
#if 0
LogComponentEnable ("CsmaBroadcastExample", LOG_LEVEL_INFO);
#endif
LogComponentEnable ("CsmaBroadcastExample", LOG_PREFIX_TIME);
//
// Make the random number generators generate reproducible results.
@@ -93,7 +94,7 @@ main (int argc, char *argv[])
// Create the OnOff application to send UDP datagrams of size
// 512 bytes (default) at a rate of 500 Kb/s (default) from n0
NS_LOG_INFO ("Create Applications.");
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address ("255.255.255.255"), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
@@ -104,7 +105,7 @@ main (int argc, char *argv[])
app.Stop (Seconds (10.0));
// Create an optional packet sink to receive these packets
PacketSinkHelper sink ("ns3::Udp",
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
sink.Install (c0.Get (1));
sink.Install (c1.Get (1));

View File

@@ -140,7 +140,7 @@ main (int argc, char *argv[])
// Configure a multicast packet generator that generates a packet
// every few seconds
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (multicastGroup, multicastPort)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
@@ -156,7 +156,7 @@ main (int argc, char *argv[])
srcC.Stop (Seconds(10.));
// Create an optional packet sink to receive these packets
PacketSinkHelper sink ("ns3::Udp",
PacketSinkHelper sink ("ns3::UdpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny(), multicastPort));
ApplicationContainer sinkC = sink.Install (c1.Get (2)); // Node n4

View File

@@ -95,7 +95,7 @@ main (int argc, char *argv[])
NS_LOG_INFO ("Create Applications.");
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
@@ -106,7 +106,7 @@ main (int argc, char *argv[])
app.Stop (Seconds (10.0));
// Create an optional packet sink to receive these packets
PacketSinkHelper sink ("ns3::Udp",
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
sink.Install (c.Get (1));

View File

@@ -110,7 +110,7 @@ main (int argc, char *argv[])
// 210 bytes at a rate of 448 Kb/s
NS_LOG_INFO ("Create Applications.");
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
InetSocketAddress (i5i6.GetAddress (1), port));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));

View File

@@ -308,7 +308,7 @@ main (int argc, char *argv[])
Ptr<Node> appSink = NodeList::GetNode (13);
Ipv4Address remoteAddr = Ipv4Address ("172.16.0.5");
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (remoteAddr, port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
@@ -317,7 +317,7 @@ main (int argc, char *argv[])
apps.Stop (Seconds (20.0));
// Create a packet sink to receive these packets
PacketSinkHelper sink ("ns3::Udp",
PacketSinkHelper sink ("ns3::UdpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), port));
apps = sink.Install (appSink);
apps.Start (Seconds (3.0));

View File

@@ -141,7 +141,7 @@ main (int argc, char *argv[])
uint16_t port = 9; // Discard port (RFC 863)
// Create a flow from n3 to n1, starting at time 1.1 seconds
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (i1i2.GetAddress (0), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
@@ -151,7 +151,7 @@ main (int argc, char *argv[])
apps.Start (Seconds (10.0));
// Create a packet sink to receive these packets
PacketSinkHelper sink ("ns3::Udp",
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
apps = sink.Install (c.Get (1));
apps.Start (Seconds (1.1));

View File

@@ -122,7 +122,7 @@ main (int argc, char *argv[])
NS_LOG_INFO ("Create Applications.");
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (i3i2.GetAddress (1), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable(1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable(0)));
@@ -132,7 +132,7 @@ main (int argc, char *argv[])
apps.Stop (Seconds(10.0));
// Create an optional packet sink to receive these packets
PacketSinkHelper sink ("ns3::Udp",
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
apps = sink.Install (c.Get (3));
apps.Start (Seconds (1.0));

View File

@@ -122,7 +122,7 @@ main (int argc, char *argv[])
// 210 bytes at a rate of 448 Kb/s
NS_LOG_INFO ("Create Applications.");
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (i3i2.GetAddress (0), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
@@ -131,7 +131,7 @@ main (int argc, char *argv[])
apps.Stop (Seconds (10.0));
// Create a packet sink to receive these packets
PacketSinkHelper sink ("ns3::Udp",
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
apps = sink.Install (c.Get (3));
apps.Start (Seconds (1.0));

View File

@@ -127,7 +127,7 @@ main (int argc, char *argv[])
NS_LOG_INFO ("Create Applications.");
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::Udp",
OnOffHelper onoff ("ns3::UdpSocketFactory",
InetSocketAddress (i34.GetAddress (1), port));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
@@ -137,7 +137,7 @@ main (int argc, char *argv[])
apps.Stop (Seconds (10.0));
// Create a packet sink to receive these packets
PacketSinkHelper sink ("ns3::Udp",
PacketSinkHelper sink ("ns3::UdpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), port));
apps = sink.Install (c.Get (3));

View File

@@ -169,16 +169,15 @@ int main (int argc, char *argv[])
uint16_t servPort = 50000;
// Create a packet sink to receive these packets
PacketSinkHelper sink ("ns3::Tcp",
PacketSinkHelper sink ("ns3::TcpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), servPort));
ApplicationContainer apps = sink.Install (c1.Get (1));
apps.Start (Seconds (0.0));
// and generate traffic to remote sink.
Ptr<SocketFactory> socketFactory =
c0.Get (0)->GetObject<Tcp> ();
Ptr<Socket> localSocket = socketFactory->CreateSocket ();
//TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory");
Ptr<Socket> localSocket = Socket::CreateSocket (c0.Get (0), TcpSocketFactory::GetTypeId ());
localSocket->Bind ();
Simulator::ScheduleNow (&StartFlow, localSocket, nBytes,
ipInterfs.GetAddress (1), servPort);

View File

@@ -38,7 +38,7 @@ public:
Experiment (std::string name);
GnuplotDataset Run (const WifiHelper &wifi);
private:
void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &address);
void ReceivePacket (Ptr<Socket> socket);
void SetPosition (Ptr<Node> node, Vector position);
Vector GetPosition (Ptr<Node> node);
void AdvancePosition (Ptr<Node> node);
@@ -90,17 +90,20 @@ Experiment::AdvancePosition (Ptr<Node> node)
}
void
Experiment::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &address)
Experiment::ReceivePacket (Ptr<Socket> socket)
{
m_bytesTotal += packet->GetSize ();
Ptr<Packet> packet;
while (packet = socket->Recv ())
{
m_bytesTotal += packet->GetSize ();
}
}
Ptr<Socket>
Experiment::SetupPacketReceive (Ptr<Node> node)
{
TypeId tid = TypeId::LookupByName ("ns3::PacketSocketFactory");
Ptr<SocketFactory> socketFactory = node->GetObject<SocketFactory> (tid);
Ptr<Socket> sink = socketFactory->CreateSocket ();
TypeId tid = TypeId::LookupByName ("ns3::PacketSocket");
Ptr<Socket> sink = Socket::CreateSocket (node, tid);
sink->Bind ();
sink->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
return sink;
@@ -133,7 +136,7 @@ Experiment::Run (const WifiHelper &wifi)
socket.SetPhysicalAddress (devices.Get (1)->GetAddress ());
socket.SetProtocol (1);
OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
OnOffHelper onoff ("ns3::PacketSocket", Address (socket));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (250)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
onoff.SetAttribute ("DataRate", DataRateValue (DataRate (60000000)));

View File

@@ -162,7 +162,7 @@ int main (int argc, char *argv[])
socket.SetPhysicalAddress (staDevs.Get (1)->GetAddress ());
socket.SetProtocol (1);
OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
OnOffHelper onoff ("ns3::PacketSocket", Address (socket));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (42)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));

View File

@@ -23,9 +23,13 @@ GenerateTraffic (Ptr<Socket> socket, uint32_t size)
}
static void
SocketPrinter (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
SocketPrinter (Ptr<Socket> socket)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << packet->GetSize () << std::endl;
Ptr<Packet> packet;
while (packet = socket->Recv ())
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << packet->GetSize () << std::endl;
}
}
static void
@@ -44,14 +48,12 @@ RunSimulation (void)
internet.Install (c);
TypeId tid = TypeId::LookupByName ("ns3::Udp");
Ptr<SocketFactory> socketFactory = c.Get (0)->GetObject<SocketFactory> (tid);
Ptr<Socket> sink = socketFactory->CreateSocket ();
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
Ptr<Socket> sink = Socket::CreateSocket (c.Get (0), tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
sink->Bind (local);
Ptr<Socket> source = socketFactory->CreateSocket ();
Ptr<Socket> source = Socket::CreateSocket (c.Get (0), tid);
InetSocketAddress remote = InetSocketAddress (Ipv4Address::GetLoopback (), 80);
source->Connect (remote);

View File

@@ -35,7 +35,7 @@
#include "ns3/uinteger.h"
#include "ns3/trace-source-accessor.h"
#include "onoff-application.h"
#include "ns3/udp.h"
#include "ns3/udp-socket-factory.h"
NS_LOG_COMPONENT_DEFINE ("OnOffApplication");
@@ -79,7 +79,7 @@ OnOffApplication::GetTypeId (void)
MakeUintegerAccessor (&OnOffApplication::m_maxBytes),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("Protocol", "The type of protocol to use.",
TypeIdValue (Udp::GetTypeId ()),
TypeIdValue (UdpSocketFactory::GetTypeId ()),
MakeTypeIdAccessor (&OnOffApplication::m_tid),
MakeTypeIdChecker ())
.AddTraceSource ("Tx", "A new packet is created and is sent",
@@ -130,8 +130,7 @@ void OnOffApplication::StartApplication() // Called at time specified by Start
// Create the socket if not already
if (!m_socket)
{
Ptr<SocketFactory> socketFactory = GetNode ()->GetObject<SocketFactory> (m_tid);
m_socket = socketFactory->CreateSocket ();
m_socket = Socket::CreateSocket (GetNode(), m_tid);
m_socket->Bind ();
m_socket->Connect (m_peer);
}

View File

@@ -26,7 +26,7 @@
#include "ns3/socket-factory.h"
#include "ns3/packet.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/udp.h"
#include "ns3/udp-socket-factory.h"
#include "packet-sink.h"
using namespace std;
@@ -47,7 +47,7 @@ PacketSink::GetTypeId (void)
MakeAddressAccessor (&PacketSink::m_local),
MakeAddressChecker ())
.AddAttribute ("Protocol", "The type id of the protocol to use for the rx socket.",
TypeIdValue (Udp::GetTypeId ()),
TypeIdValue (UdpSocketFactory::GetTypeId ()),
MakeTypeIdAccessor (&PacketSink::m_tid),
MakeTypeIdChecker ())
.AddTraceSource ("Rx", "A packet has been received",
@@ -80,14 +80,12 @@ void PacketSink::StartApplication() // Called at time specified by Start
// Create the socket if not already
if (!m_socket)
{
Ptr<SocketFactory> socketFactory =
GetNode ()->GetObject<SocketFactory> (m_tid);
m_socket = socketFactory->CreateSocket ();
m_socket = Socket::CreateSocket (GetNode(), m_tid);
m_socket->Bind (m_local);
m_socket->Listen (0);
}
m_socket->SetRecvCallback (MakeCallback(&PacketSink::Receive, this));
m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this));
m_socket->SetAcceptCallback (
MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
MakeNullCallback<void, Ptr<Socket>, const Address&> (),
@@ -98,23 +96,30 @@ void PacketSink::StopApplication() // Called at time specified by Stop
{
if (m_socket)
{
m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket>,
Ptr<Packet>, const Address &> ());
m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
}
}
// This LOG output inspired by the application on Joseph Kopena's wiki
void PacketSink::Receive(Ptr<Socket> socket, Ptr<Packet> packet,
const Address &from)
void PacketSink::HandleRead (Ptr<Socket> socket)
{
if (InetSocketAddress::IsMatchingType (from))
Ptr<Packet> packet;
while (packet = socket->Recv ())
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
address.GetIpv4() << " [" << address << "]---'" <<
packet->PeekData() << "'");
SocketRxAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
Address from = tag.GetAddress ();
// XXX packet->RemoveTag (tag);
if (InetSocketAddress::IsMatchingType (from))
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
address.GetIpv4() << " [" << address << "]---'" <<
packet->PeekData() << "'");
}
m_rxTrace (packet, from);
}
m_rxTrace (packet, from);
}
void PacketSink::CloseConnection (Ptr<Socket> socket)

View File

@@ -65,7 +65,8 @@ private:
virtual void StartApplication (void); // Called at time specified by Start
virtual void StopApplication (void); // Called at time specified by Stop
virtual void Receive (Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
virtual void HandleRead (Ptr<Socket> socket);
virtual void CloseConnection (Ptr<Socket> socket);
Ptr<Socket> m_socket; // Associated socket

View File

@@ -95,15 +95,13 @@ UdpEchoClient::StartApplication (void)
if (m_socket == 0)
{
TypeId tid = TypeId::LookupByName ("ns3::Udp");
Ptr<SocketFactory> socketFactory =
GetNode ()->GetObject<SocketFactory> (tid);
m_socket = socketFactory->CreateSocket ();
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
m_socket = Socket::CreateSocket (GetNode(), tid);
m_socket->Bind ();
m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
}
m_socket->SetRecvCallback(MakeCallback(&UdpEchoClient::Receive, this));
m_socket->SetRecvCallback(MakeCallback(&UdpEchoClient::HandleRead, this));
ScheduleTransmit (Seconds(0.));
}
@@ -115,8 +113,7 @@ UdpEchoClient::StopApplication ()
if (m_socket != 0)
{
m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>,
Ptr<Packet>, const Address &> ());
m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket> > ());
}
Simulator::Cancel(m_sendEvent);
@@ -149,20 +146,25 @@ UdpEchoClient::Send (void)
}
void
UdpEchoClient::Receive(
Ptr<Socket> socket,
Ptr<Packet> packet,
const Address &from)
UdpEchoClient::HandleRead (Ptr<Socket> socket)
{
NS_LOG_FUNCTION (this << socket << packet << from);
if (InetSocketAddress::IsMatchingType (from))
NS_LOG_FUNCTION (this << socket);
Ptr<Packet> packet;
while (packet = socket->Recv ())
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
address.GetIpv4());
SocketRxAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
Address from = tag.GetAddress ();
// XXX packet->RemoveTag (tag);
if (InetSocketAddress::IsMatchingType (from))
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
address.GetIpv4());
}
}
}
} // Namespace ns3

View File

@@ -56,7 +56,7 @@ private:
void ScheduleTransmit (Time dt);
void Send (void);
void Receive(Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
void HandleRead (Ptr<Socket> socket);
uint32_t m_count;
Time m_interval;

View File

@@ -71,16 +71,13 @@ UdpEchoServer::StartApplication (void)
if (m_socket == 0)
{
TypeId tid = TypeId::LookupByName ("ns3::Udp");
Ptr<SocketFactory> socketFactory =
GetNode ()->GetObject<SocketFactory> (tid);
m_socket = socketFactory->CreateSocket ();
InetSocketAddress local =
InetSocketAddress (Ipv4Address::GetAny (), m_port);
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
m_socket = Socket::CreateSocket (GetNode(), tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), m_port);
m_socket->Bind (local);
}
m_socket->SetRecvCallback(MakeCallback(&UdpEchoServer::Receive, this));
m_socket->SetRecvCallback(MakeCallback(&UdpEchoServer::HandleRead, this));
}
void
@@ -90,27 +87,31 @@ UdpEchoServer::StopApplication ()
if (m_socket != 0)
{
m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>,
Ptr<Packet>, const Address &> ());
m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket> > ());
}
}
void
UdpEchoServer::Receive(
Ptr<Socket> socket,
Ptr<Packet> packet,
const Address &from)
void
UdpEchoServer::HandleRead (Ptr<Socket> socket)
{
NS_LOG_FUNCTION (this << socket << packet << from);
if (InetSocketAddress::IsMatchingType (from))
Ptr<Packet> packet;
while (packet = socket->Recv ())
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
address.GetIpv4());
SocketRxAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
Address from = tag.GetAddress ();
// XXX packet->RemoveTag (tag);
if (InetSocketAddress::IsMatchingType (from))
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
address.GetIpv4());
NS_LOG_LOGIC ("Echoing packet");
socket->SendTo (from, packet);
NS_LOG_LOGIC ("Echoing packet");
socket->SendTo (packet, from);
}
}
}

View File

@@ -49,7 +49,7 @@ private:
virtual void StartApplication (void);
virtual void StopApplication (void);
void Receive(Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
void HandleRead (Ptr<Socket> socket);
uint16_t m_port;
Ptr<Socket> m_socket;

View File

@@ -80,7 +80,6 @@ public:
*/
uint64_t GetBitRate() const;
ATTRIBUTE_HELPER_HEADER_1 (DataRate);
private:
uint64_t m_bps;
static uint64_t Parse(const std::string);
@@ -94,7 +93,7 @@ std::istream &operator >> (std::istream &is, DataRate &rate);
* \brief hold objects of type ns3::DataRate
*/
ATTRIBUTE_HELPER_HEADER_2 (DataRate);
ATTRIBUTE_HELPER_HEADER (DataRate);
/**
* \param lhs

View File

@@ -304,7 +304,7 @@ cell_tooltip_callback (GtkWidget *widget,
}
break;
case ModelNode::NODE_ATTRIBUTE: {
uint32_t attrIndex;
uint32_t attrIndex = 0;
TypeId tid;
for (tid = node->object->GetInstanceTypeId (); tid.HasParent (); tid = tid.GetParent ())
{

View File

@@ -83,8 +83,7 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
*
* The simple macros are implemented in terms of the complex
* macros and should generally be prefered over the complex macros:
* - \ref ATTRIBUTE_HELPER_HEADER_1,
* - \ref ATTRIBUTE_HELPER_HEADER_2, and,
* - \ref ATTRIBUTE_HELPER_HEADER, and,
* - \ref ATTRIBUTE_HELPER_CPP,
*/
@@ -232,15 +231,6 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
#define ATTRIBUTE_CONVERTER_IMPLEMENT(type)
/**
* \ingroup AttributeHelper
* \param type the name of the class
*
* This macro should be invoked from a public section of the class
* declaration.
*/
#define ATTRIBUTE_HELPER_HEADER_1(type)
/**
* \ingroup AttributeHelper
* \param type the name of the class
@@ -248,7 +238,7 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
* This macro should be invoked outside of the class
* declaration in its public header.
*/
#define ATTRIBUTE_HELPER_HEADER_2(type) \
#define ATTRIBUTE_HELPER_HEADER(type) \
ATTRIBUTE_VALUE_DEFINE (type); \
ATTRIBUTE_ACCESSOR_DEFINE (type); \
ATTRIBUTE_CHECKER_DEFINE (type);

View File

@@ -53,7 +53,7 @@ std::istream & operator >> (std::istream &is, ValueClassTest &v)
{
return is;
}
ATTRIBUTE_HELPER_HEADER_2 (ValueClassTest);
ATTRIBUTE_HELPER_HEADER (ValueClassTest);
ATTRIBUTE_HELPER_CPP (ValueClassTest);
class AttributeTest : public Test

View File

@@ -69,7 +69,7 @@
#define NS_LOG_COMPONENT_DEFINE(name) \
static ns3::LogComponent g_log = ns3::LogComponent (name)
#define APPEND_TIME_PREFIX \
#define NS_LOG_APPEND_TIME_PREFIX \
if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) \
{ \
LogTimePrinter printer = LogGetTimePrinter (); \
@@ -80,13 +80,17 @@
} \
}
#define APPEND_FUNC_PREFIX \
#define NS_LOG_APPEND_FUNC_PREFIX \
if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) \
{ \
std::clog << g_log.Name () << ":" << \
__FUNCTION__ << "(): "; \
} \
#ifndef NS_LOG_APPEND_CONTEXT
#define NS_LOG_APPEND_CONTEXT
#endif /* NS_LOG_APPEND_CONTEXT */
/**
* \ingroup logging
@@ -107,8 +111,9 @@
{ \
if (g_log.IsEnabled (level)) \
{ \
APPEND_TIME_PREFIX; \
APPEND_FUNC_PREFIX; \
NS_LOG_APPEND_TIME_PREFIX; \
NS_LOG_APPEND_CONTEXT; \
NS_LOG_APPEND_FUNC_PREFIX; \
std::clog << msg << std::endl; \
} \
} \
@@ -160,7 +165,8 @@
{ \
if (g_log.IsEnabled (ns3::LOG_FUNCTION)) \
{ \
APPEND_TIME_PREFIX; \
NS_LOG_APPEND_TIME_PREFIX; \
NS_LOG_APPEND_CONTEXT; \
std::clog << g_log.Name () << ":" \
<< __FUNCTION__ << "()" << std::endl; \
} \
@@ -189,7 +195,8 @@
{ \
if (g_log.IsEnabled (ns3::LOG_FUNCTION)) \
{ \
APPEND_TIME_PREFIX; \
NS_LOG_APPEND_TIME_PREFIX; \
NS_LOG_APPEND_CONTEXT; \
std::clog << g_log.Name () << ":" \
<< __FUNCTION__ << "("; \
ParameterLogger (std::clog) << parameters; \

View File

@@ -77,7 +77,6 @@ public:
template <typename T>
Ptr<T> Create (void) const;
ATTRIBUTE_HELPER_HEADER_1 (ObjectFactory);
private:
friend std::ostream & operator << (std::ostream &os, const ObjectFactory &factory);
friend std::istream & operator >> (std::istream &is, ObjectFactory &factory);
@@ -94,7 +93,7 @@ std::istream & operator >> (std::istream &is, ObjectFactory &factory);
* \brief hold objects of type ns3::ObjectFactory
*/
ATTRIBUTE_HELPER_HEADER_2 (ObjectFactory);
ATTRIBUTE_HELPER_HEADER (ObjectFactory);
} // namespace ns3

View File

@@ -386,7 +386,7 @@ TypeId
TypeId::LookupByName (std::string name)
{
uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
NS_ASSERT (uid != 0);
NS_ASSERT_MSG (uid != 0, "Assert in TypeId::LookupByName: " << name << " not found");
return TypeId (uid);
}
bool

View File

@@ -354,7 +354,6 @@ public:
TypeId ();
~TypeId ();
ATTRIBUTE_HELPER_HEADER_1 (TypeId);
private:
friend class AttributeList;
friend bool operator == (TypeId a, TypeId b);
@@ -388,7 +387,7 @@ bool operator < (TypeId a, TypeId b);
*/
ATTRIBUTE_HELPER_HEADER_2 (TypeId);
ATTRIBUTE_HELPER_HEADER (TypeId);
} // namespace ns3

View File

@@ -49,7 +49,6 @@ public:
Buffer::Iterator Serialize (Buffer::Iterator i) const;
Buffer::Iterator Deserialize (Buffer::Iterator i);
ATTRIBUTE_HELPER_HEADER_1 (Ssid);
private:
uint8_t m_ssid[33];
uint8_t m_length;
@@ -63,7 +62,7 @@ std::istream &operator >> (std::istream &is, Ssid &ssid);
* \brief hold objects of type ns3::Ssid
*/
ATTRIBUTE_HELPER_HEADER_2 (Ssid);
ATTRIBUTE_HELPER_HEADER (Ssid);
} // namespace ns3

View File

@@ -107,7 +107,6 @@ class WifiMode
*/
WifiMode ();
ATTRIBUTE_HELPER_HEADER_1 (WifiMode);
private:
friend class WifiModeFactory;
WifiMode (uint32_t uid);
@@ -123,7 +122,7 @@ std::istream & operator >> (std::istream &is, WifiMode &mode);
* \brief hold objects of type ns3::WifiMode
*/
ATTRIBUTE_HELPER_HEADER_2 (WifiMode);
ATTRIBUTE_HELPER_HEADER (WifiMode);
/**
* \brief create WifiMode class instances and keep track of them.

View File

@@ -41,13 +41,13 @@ PacketSinkHelper::SetAttribute (std::string name, const AttributeValue &value)
void
PacketSinkHelper::SetUdpLocal (Ipv4Address ip, uint16_t port)
{
m_factory.Set ("Protocol", String ("ns3::Udp"));
m_factory.Set ("Protocol", String ("ns3::UdpSocketFactory"));
m_factory.Set ("Local", Address (InetSocketAddress (ip, port)));
}
void
PacketSinkHelper::SetTcpLocal (Ipv4Address ip, uint16_t port)
{
m_factory.Set ("Protocol", String ("ns3::Tcp"));
m_factory.Set ("Protocol", String ("ns3::TcpSocketFactory"));
m_factory.Set ("Local", Address (InetSocketAddress (ip, port)));
}
#endif

View File

@@ -27,8 +27,8 @@
#include "tcp-l4-protocol.h"
#include "ipv4-l3-protocol.h"
#include "arp-l3-protocol.h"
#include "udp-impl.h"
#include "tcp-impl.h"
#include "udp-socket-factory-impl.h"
#include "tcp-socket-factory-impl.h"
#include "ipv4-impl.h"
namespace ns3 {
@@ -58,19 +58,19 @@ AddInternetStack (Ptr<Node> node)
ipv4L4Demux->Insert (udp);
ipv4L4Demux->Insert (tcp);
Ptr<UdpImpl> udpImpl = CreateObject<UdpImpl> ();
Ptr<TcpImpl> tcpImpl = CreateObject<TcpImpl> ();
Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> ();
udpImpl->SetUdp (udp);
tcpImpl->SetTcp (tcp);
udpFactory->SetUdp (udp);
tcpFactory->SetTcp (tcp);
ipv4Impl->SetIpv4 (ipv4);
node->AggregateObject (ipv4);
node->AggregateObject (arp);
node->AggregateObject (ipv4Impl);
node->AggregateObject (udpImpl);
node->AggregateObject (tcpImpl);
node->AggregateObject (udpFactory);
node->AggregateObject (tcpFactory);
node->AggregateObject (ipv4L4Demux);
}

View File

@@ -24,6 +24,7 @@
#include "ns3/ipv4-address.h"
#include "ns3/ipv4-route.h"
#include "ns3/node.h"
#include "ns3/socket.h"
#include "ns3/net-device.h"
#include "ns3/uinteger.h"
#include "ns3/trace-source-accessor.h"
@@ -491,6 +492,34 @@ Ipv4L3Protocol::Send (Ptr<Packet> packet,
m_identification ++;
// Set TTL to 1 if it is a broadcast packet of any type. Otherwise,
// possibly override the default TTL if the packet is tagged
SocketIpTtlTag tag;
bool found = packet->FindFirstMatchingTag (tag);
if (destination.IsBroadcast ())
{
ipHeader.SetTtl (1);
}
else if (found)
{
ipHeader.SetTtl (tag.GetTtl ());
// XXX remove tag here?
}
else
{
uint32_t ifaceIndex = 0;
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
{
Ptr<Ipv4Interface> outInterface = *ifaceIter;
if (destination.IsSubnetDirectedBroadcast (
outInterface->GetNetworkMask ()))
{
ipHeader.SetTtl (1);
}
}
}
if (destination.IsBroadcast ())
{
uint32_t ifaceIndex = 0;

View File

@@ -20,7 +20,7 @@
#include <stdint.h>
#include <iostream>
#include "tcp-socket.h"
#include "tcp-socket-impl.h"
#include "tcp-header.h"
#include "ns3/buffer.h"

View File

@@ -24,7 +24,7 @@
#include <stdint.h>
#include "ns3/header.h"
#include "ns3/buffer.h"
#include "ns3/tcp.h"
#include "ns3/tcp-socket-factory.h"
#include "ns3/ipv4-address.h"
#include "ns3/sequence-number.h"

View File

@@ -30,7 +30,7 @@
#include "ipv4-end-point-demux.h"
#include "ipv4-end-point.h"
#include "ipv4-l3-protocol.h"
#include "tcp-socket.h"
#include "tcp-socket-impl.h"
#include "tcp-typedefs.h"
@@ -379,7 +379,7 @@ TcpL4Protocol::CreateSocket (void)
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
Ptr<TcpSocket> socket = CreateObject<TcpSocket> ();
Ptr<TcpSocketImpl> socket = CreateObject<TcpSocketImpl> ();
socket->SetNode (m_node);
socket->SetTcp (this);
socket->SetRtt (rtt);

View File

@@ -58,7 +58,7 @@ public:
virtual int GetVersion (void) const;
/**
* \return A smart Socket pointer to a TcpSocket, allocated by this instance
* \return A smart Socket pointer to a TcpSocketImpl, allocated by this instance
* of the TCP protocol
*/
Ptr<Socket> CreateSocket (void);
@@ -72,7 +72,7 @@ public:
void DeAllocate (Ipv4EndPoint *endPoint);
// // called by TcpSocket.
// // called by TcpSocketImpl.
// bool Connect (const Ipv4Address& saddr, const Ipv4Address& daddr,
// uint16_t sport, uint16_t dport);
@@ -106,7 +106,7 @@ private:
Ipv4EndPointDemux *m_endPoints;
ObjectFactory m_rttFactory;
private:
friend class TcpSocket;
friend class TcpSocketImpl;
void SendPacket (Ptr<Packet>, TcpHeader,
Ipv4Address, Ipv4Address);
static ObjectFactory GetDefaultRttEstimatorFactory (void);

View File

@@ -17,38 +17,38 @@
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#include "tcp-impl.h"
#include "tcp-socket-factory-impl.h"
#include "tcp-l4-protocol.h"
#include "ns3/socket.h"
#include "ns3/assert.h"
namespace ns3 {
TcpImpl::TcpImpl ()
TcpSocketFactoryImpl::TcpSocketFactoryImpl ()
: m_tcp (0)
{}
TcpImpl::~TcpImpl ()
TcpSocketFactoryImpl::~TcpSocketFactoryImpl ()
{
NS_ASSERT (m_tcp == 0);
}
void
TcpImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
TcpSocketFactoryImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
{
m_tcp = tcp;
}
Ptr<Socket>
TcpImpl::CreateSocket (void)
TcpSocketFactoryImpl::CreateSocket (void)
{
return m_tcp->CreateSocket ();
}
void
TcpImpl::DoDispose (void)
TcpSocketFactoryImpl::DoDispose (void)
{
m_tcp = 0;
Tcp::DoDispose ();
TcpSocketFactory::DoDispose ();
}
} // namespace ns3

View File

@@ -17,10 +17,10 @@
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#ifndef TCP_IMPL_H
#define TCP_IMPL_H
#ifndef TCP_SOCKET_FACTORY_IMPL_H
#define TCP_SOCKET_FACTORY_IMPL_H
#include "ns3/tcp.h"
#include "ns3/tcp-socket-factory.h"
#include "ns3/ptr.h"
namespace ns3 {
@@ -37,13 +37,13 @@ class TcpL4Protocol;
* <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.
* Most of the logic is in class ns3::TcpSocketImpl.
*/
class TcpImpl : public Tcp
class TcpSocketFactoryImpl : public TcpSocketFactory
{
public:
TcpImpl ();
virtual ~TcpImpl ();
TcpSocketFactoryImpl ();
virtual ~TcpSocketFactoryImpl ();
void SetTcp (Ptr<TcpL4Protocol> tcp);
@@ -57,4 +57,4 @@ private:
} // namespace ns3
#endif /* TCP_IMPL_H */
#endif /* TCP_SOCKET_FACTORY_IMPL_H */

View File

@@ -17,13 +17,14 @@
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#ifndef TCP_SOCKET_H
#define TCP_SOCKET_H
#ifndef TCP_SOCKET_IMPL_H
#define TCP_SOCKET_IMPL_H
#include <stdint.h>
#include <queue>
#include "ns3/callback.h"
#include "ns3/traced-value.h"
#include "ns3/socket.h"
#include "ns3/tcp-socket.h"
#include "ns3/ptr.h"
#include "ns3/ipv4-address.h"
#include "ns3/event-id.h"
@@ -41,16 +42,16 @@ class Packet;
class TcpL4Protocol;
class TcpHeader;
class TcpSocket : public Socket
class TcpSocketImpl : public TcpSocket
{
public:
static TypeId GetTypeId (void);
/**
* Create an unbound tcp socket.
*/
TcpSocket ();
TcpSocket (const TcpSocket& sock);
virtual ~TcpSocket ();
TcpSocketImpl ();
TcpSocketImpl (const TcpSocketImpl& sock);
virtual ~TcpSocketImpl ();
void SetNode (Ptr<Node> node);
void SetTcp (Ptr<TcpL4Protocol> tcp);
@@ -66,9 +67,13 @@ public:
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 SendTo(Ptr<Packet> p, const Address &address);
virtual uint32_t GetTxAvailable (void) const;
virtual int Listen(uint32_t queueLimit);
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual uint32_t GetRxAvailable (void) const;
private:
friend class Tcp;
// invoked by Tcp class
@@ -99,7 +104,7 @@ private:
// Manage data tx/rx
void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
// XXX This should be virtual and overridden
Ptr<TcpSocket> Copy ();
Ptr<TcpSocketImpl> Copy ();
void NewAck (SequenceNumber seq);
// XXX This should be virtual and overridden
void DupAck (const TcpHeader& t, uint32_t count);
@@ -109,6 +114,28 @@ private:
void Retransmit ();
void CommonNewAck (SequenceNumber seq, bool skipTimer = false);
// attribute related
virtual void SetSndBufSize (uint32_t size);
virtual uint32_t GetSndBufSize (void) const;
virtual void SetRcvBufSize (uint32_t size);
virtual uint32_t GetRcvBufSize (void) const;
virtual void SetSegSize (uint32_t size);
virtual uint32_t GetSegSize (void) const;
virtual void SetAdvWin (uint32_t window);
virtual uint32_t GetAdvWin (void) const;
virtual void SetSSThresh (uint32_t threshold);
virtual uint32_t GetSSThresh (void) const;
virtual void SetInitialCwnd (uint32_t cwnd);
virtual uint32_t GetInitialCwnd (void) const;
virtual void SetConnTimeout (Time timeout);
virtual Time GetConnTimeout (void) const;
virtual void SetConnCount (uint32_t count);
virtual uint32_t GetConnCount (void) const;
virtual void SetDelAckTimeout (Time timeout);
virtual Time GetDelAckTimeout (void) const;
virtual void SetDelAckMaxCount (uint32_t count);
virtual uint32_t GetDelAckMaxCount (void) const;
bool m_skipRetxResched;
uint32_t m_dupAckCount;
EventId m_retxEvent;
@@ -117,7 +144,7 @@ private:
EventId m_delAckEvent;
uint32_t m_delAckCount;
uint32_t m_delAckMaxCount;
Time m_delAckTimout;
Time m_delAckTimeout;
Ipv4EndPoint *m_endPoint;
Ptr<Node> m_node;
@@ -150,7 +177,9 @@ private:
SequenceNumber m_nextRxSequence;
//history data
//this is the incoming data buffer which sorts out of sequence data
UnAckData_t m_bufferedData;
//this is kind of the tx buffer
PendingData* m_pendingData;
SequenceNumber m_firstPendingSequence;
@@ -170,8 +199,17 @@ private:
Time m_cnTimeout;
uint32_t m_cnCount;
// Temporary queue for delivering data to application
std::queue<Ptr<Packet> > m_deliveryQueue;
uint32_t m_rxAvailable;
bool m_wouldBlock; // set to true whenever socket would block on send()
// Attributes
uint32_t m_rcvBufSize; // maximum receive socket buffer size
uint32_t m_sndBufSize; // buffer limit for the outgoing queue
};
}//namespace ns3
#endif /* UDP_SOCKET_H */
#endif /* TCP_SOCKET_IMPL_H */

View File

@@ -28,7 +28,7 @@
#include "ipv4-end-point-demux.h"
#include "ipv4-end-point.h"
#include "ipv4-l3-protocol.h"
#include "udp-socket.h"
#include "udp-socket-impl.h"
NS_LOG_COMPONENT_DEFINE ("UdpL4Protocol");
@@ -95,7 +95,7 @@ Ptr<Socket>
UdpL4Protocol::CreateSocket (void)
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<UdpSocket> socket = CreateObject<UdpSocket> ();
Ptr<UdpSocketImpl> socket = CreateObject<UdpSocketImpl> ();
socket->SetNode (m_node);
socket->SetUdp (this);
return socket;

View File

@@ -17,38 +17,38 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "udp-impl.h"
#include "udp-socket-factory-impl.h"
#include "udp-l4-protocol.h"
#include "ns3/socket.h"
#include "ns3/assert.h"
namespace ns3 {
UdpImpl::UdpImpl ()
UdpSocketFactoryImpl::UdpSocketFactoryImpl ()
: m_udp (0)
{}
UdpImpl::~UdpImpl ()
UdpSocketFactoryImpl::~UdpSocketFactoryImpl ()
{
NS_ASSERT (m_udp == 0);
}
void
UdpImpl::SetUdp (Ptr<UdpL4Protocol> udp)
UdpSocketFactoryImpl::SetUdp (Ptr<UdpL4Protocol> udp)
{
m_udp = udp;
}
Ptr<Socket>
UdpImpl::CreateSocket (void)
UdpSocketFactoryImpl::CreateSocket (void)
{
return m_udp->CreateSocket ();
}
void
UdpImpl::DoDispose (void)
UdpSocketFactoryImpl::DoDispose (void)
{
m_udp = 0;
Udp::DoDispose ();
UdpSocketFactory::DoDispose ();
}
} // namespace ns3

View File

@@ -17,10 +17,10 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef UDP_IMPL_H
#define UDP_IMPL_H
#ifndef UDP_SOCKET_FACTORY_IMPL_H
#define UDP_SOCKET_FACTORY_IMPL_H
#include "ns3/udp.h"
#include "ns3/udp-socket-factory.h"
#include "ns3/ptr.h"
namespace ns3 {
@@ -31,21 +31,19 @@ class UdpL4Protocol;
* \brief Object to create UDP socket instances
* \internal
*
* This class implements the API for UDP sockets.
* It is a socket factory (deriving from class SocketFactory) and can
* also hold global variables used to initialize newly created sockets,
* such as values that are set through the sysctl or proc interfaces in Linux.
* This class implements the API for creating UDP sockets.
* It is a socket factory (deriving from class SocketFactory).
*/
class UdpImpl : public Udp
class UdpSocketFactoryImpl : public UdpSocketFactory
{
public:
UdpImpl ();
virtual ~UdpImpl ();
UdpSocketFactoryImpl ();
virtual ~UdpSocketFactoryImpl ();
void SetUdp (Ptr<UdpL4Protocol> udp);
/**
* \brief Implements a method to create a UdpImpl-based socket and return
* \brief Implements a method to create a Udp-based socket and return
* a base class smart pointer to the socket.
* \internal
*
@@ -61,4 +59,4 @@ private:
} // namespace ns3
#endif /* UDP_IMPL_H */
#endif /* UDP_SOCKET_FACTORY_IMPL_H */

View File

@@ -23,29 +23,48 @@
#include "ns3/inet-socket-address.h"
#include "ns3/ipv4-route.h"
#include "ns3/ipv4.h"
#include "udp-socket.h"
#include "ns3/udp-socket-factory.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/uinteger.h"
#include "ns3/boolean.h"
#include "udp-socket-impl.h"
#include "udp-l4-protocol.h"
#include "ipv4-end-point.h"
#include "ipv4-l4-demux.h"
#include "ns3/ipv4.h"
NS_LOG_COMPONENT_DEFINE ("UdpSocket");
NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl");
namespace ns3 {
UdpSocket::UdpSocket ()
static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE = 65507;
// Add attributes generic to all UdpSockets to base class UdpSocket
TypeId
UdpSocketImpl::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::UdpSocketImpl")
.SetParent<UdpSocket> ()
.AddConstructor<UdpSocketImpl> ()
.AddTraceSource ("Drop", "Drop UDP packet due to receive buffer overflow",
MakeTraceSourceAccessor (&UdpSocketImpl::m_dropTrace))
;
return tid;
}
UdpSocketImpl::UdpSocketImpl ()
: m_endPoint (0),
m_node (0),
m_udp (0),
m_errno (ERROR_NOTERROR),
m_shutdownSend (false),
m_shutdownRecv (false),
m_connected (false)
m_connected (false),
m_rxAvailable (0)
{
NS_LOG_FUNCTION_NOARGS ();
}
UdpSocket::~UdpSocket ()
UdpSocketImpl::~UdpSocketImpl ()
{
NS_LOG_FUNCTION_NOARGS ();
@@ -69,33 +88,36 @@ UdpSocket::~UdpSocket ()
}
void
UdpSocket::SetNode (Ptr<Node> node)
UdpSocketImpl::SetNode (Ptr<Node> node)
{
NS_LOG_FUNCTION_NOARGS ();
m_node = node;
}
void
UdpSocket::SetUdp (Ptr<UdpL4Protocol> udp)
UdpSocketImpl::SetUdp (Ptr<UdpL4Protocol> udp)
{
NS_LOG_FUNCTION_NOARGS ();
m_udp = udp;
}
enum Socket::SocketErrno
UdpSocket::GetErrno (void) const
UdpSocketImpl::GetErrno (void) const
{
NS_LOG_FUNCTION_NOARGS ();
return m_errno;
}
Ptr<Node>
UdpSocket::GetNode (void) const
UdpSocketImpl::GetNode (void) const
{
NS_LOG_FUNCTION_NOARGS ();
return m_node;
}
void
UdpSocket::Destroy (void)
UdpSocketImpl::Destroy (void)
{
NS_LOG_FUNCTION_NOARGS ();
m_node = 0;
@@ -104,20 +126,20 @@ UdpSocket::Destroy (void)
}
int
UdpSocket::FinishBind (void)
UdpSocketImpl::FinishBind (void)
{
NS_LOG_FUNCTION_NOARGS ();
if (m_endPoint == 0)
{
return -1;
}
m_endPoint->SetRxCallback (MakeCallback (&UdpSocket::ForwardUp, this));
m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocket::Destroy, this));
m_endPoint->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp, this));
m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, this));
return 0;
}
int
UdpSocket::Bind (void)
UdpSocketImpl::Bind (void)
{
NS_LOG_FUNCTION_NOARGS ();
m_endPoint = m_udp->Allocate ();
@@ -125,7 +147,7 @@ UdpSocket::Bind (void)
}
int
UdpSocket::Bind (const Address &address)
UdpSocketImpl::Bind (const Address &address)
{
NS_LOG_FUNCTION (this << address);
@@ -158,7 +180,7 @@ UdpSocket::Bind (const Address &address)
}
int
UdpSocket::ShutdownSend (void)
UdpSocketImpl::ShutdownSend (void)
{
NS_LOG_FUNCTION_NOARGS ();
m_shutdownSend = true;
@@ -166,7 +188,7 @@ UdpSocket::ShutdownSend (void)
}
int
UdpSocket::ShutdownRecv (void)
UdpSocketImpl::ShutdownRecv (void)
{
NS_LOG_FUNCTION_NOARGS ();
m_shutdownRecv = false;
@@ -174,7 +196,7 @@ UdpSocket::ShutdownRecv (void)
}
int
UdpSocket::Close(void)
UdpSocketImpl::Close(void)
{
NS_LOG_FUNCTION_NOARGS ();
NotifyCloseCompleted ();
@@ -182,10 +204,9 @@ UdpSocket::Close(void)
}
int
UdpSocket::Connect(const Address & address)
UdpSocketImpl::Connect(const Address & address)
{
NS_LOG_FUNCTION (this << address);
Ipv4Route routeToDest;
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
m_defaultAddress = transport.GetIpv4 ();
m_defaultPort = transport.GetPort ();
@@ -196,7 +217,7 @@ UdpSocket::Connect(const Address & address)
}
int
UdpSocket::Send (Ptr<Packet> p)
UdpSocketImpl::Send (Ptr<Packet> p)
{
NS_LOG_FUNCTION (this << p);
@@ -209,7 +230,7 @@ UdpSocket::Send (Ptr<Packet> p)
}
int
UdpSocket::DoSend (Ptr<Packet> p)
UdpSocketImpl::DoSend (Ptr<Packet> p)
{
NS_LOG_FUNCTION_NOARGS ();
if (m_endPoint == 0)
@@ -231,7 +252,7 @@ UdpSocket::DoSend (Ptr<Packet> p)
}
int
UdpSocket::DoSendTo (Ptr<Packet> p, const Address &address)
UdpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
{
NS_LOG_FUNCTION (this << p << address);
@@ -252,12 +273,10 @@ UdpSocket::DoSendTo (Ptr<Packet> p, const Address &address)
}
int
UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
UdpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
{
NS_LOG_FUNCTION (this << p << dest << port);
Ipv4Route routeToDest;
if (m_endPoint == 0)
{
if (Bind () == -1)
@@ -273,9 +292,36 @@ UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
return -1;
}
if (p->GetSize () > GetTxAvailable () )
{
m_errno = ERROR_MSGSIZE;
return -1;
}
uint32_t localIfIndex;
Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
// Locally override the IP TTL for this socket
// We cannot directly modify the TTL at this stage, so we set a Packet tag
// The destination can be either multicast, unicast/anycast, or
// either all-hosts broadcast or limited (subnet-directed) broadcast.
// For the latter two broadcast types, the TTL will later be set to one
// irrespective of what is set in these socket options. So, this tagging
// may end up setting the TTL of a limited broadcast packet to be
// the same as a unicast, but it will be fixed further down the stack
//NS_LOG_UNCOND ("IPttl: " << m_ipTtl);
if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
{
SocketIpTtlTag tag;
tag.SetTtl (m_ipMulticastTtl);
p->AddTag (tag);
}
else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
{
SocketIpTtlTag tag;
tag.SetTtl (m_ipTtl);
p->AddTag (tag);
}
//
// If dest is sent to the limited broadcast address (all ones),
// convert it to send a copy of the packet out of every interface
@@ -315,8 +361,19 @@ UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
return 0;
}
// XXX maximum message size for UDP broadcast is limited by MTU
// size of underlying link; we are not checking that now.
uint32_t
UdpSocketImpl::GetTxAvailable (void) const
{
NS_LOG_FUNCTION_NOARGS ();
// No finite send buffer is modelled, but we must respect
// the maximum size of an IP datagram (65535 bytes - headers).
return MAX_IPV4_UDP_DATAGRAM_SIZE;
}
int
UdpSocket::SendTo(const Address &address, Ptr<Packet> p)
UdpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
{
NS_LOG_FUNCTION (this << address << p);
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
@@ -325,8 +382,38 @@ UdpSocket::SendTo(const Address &address, Ptr<Packet> p)
return DoSendTo (p, ipv4, port);
}
Ptr<Packet>
UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
{
NS_LOG_FUNCTION_NOARGS ();
if (m_deliveryQueue.empty() )
{
return 0;
}
Ptr<Packet> p = m_deliveryQueue.front ();
if (p->GetSize () <= maxSize)
{
m_deliveryQueue.pop ();
m_rxAvailable -= p->GetSize ();
}
else
{
p = 0;
}
return p;
}
uint32_t
UdpSocketImpl::GetRxAvailable (void) const
{
NS_LOG_FUNCTION_NOARGS ();
// We separately maintain this state to avoid walking the queue
// every time this might be called
return m_rxAvailable;
}
void
UdpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
{
NS_LOG_FUNCTION (this << packet << ipv4 << port);
@@ -334,9 +421,63 @@ UdpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
{
return;
}
Address address = InetSocketAddress (ipv4, port);
NotifyDataReceived (packet, address);
if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
{
Address address = InetSocketAddress (ipv4, port);
SocketRxAddressTag tag;
tag.SetAddress (address);
packet->AddTag (tag);
m_deliveryQueue.push (packet);
m_rxAvailable += packet->GetSize ();
NotifyDataRecv ();
}
else
{
// In general, this case should not occur unless the
// receiving application reads data from this socket slowly
// in comparison to the arrival rate
//
// drop and trace packet
NS_LOG_WARN ("No receive buffer space available. Drop.");
m_dropTrace (packet);
}
}
void
UdpSocketImpl::SetRcvBufSize (uint32_t size)
{
m_rcvBufSize = size;
}
uint32_t
UdpSocketImpl::GetRcvBufSize (void) const
{
return m_rcvBufSize;
}
void
UdpSocketImpl::SetIpTtl (uint32_t ipTtl)
{
m_ipTtl = ipTtl;
}
uint32_t
UdpSocketImpl::GetIpTtl (void) const
{
return m_ipTtl;
}
void
UdpSocketImpl::SetIpMulticastTtl (uint32_t ipTtl)
{
m_ipMulticastTtl = ipTtl;
}
uint32_t
UdpSocketImpl::GetIpMulticastTtl (void) const
{
return m_ipMulticastTtl;
}
} //namespace ns3
@@ -346,7 +487,7 @@ UdpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
#include "ns3/test.h"
#include "ns3/socket-factory.h"
#include "ns3/udp.h"
#include "ns3/udp-socket-factory.h"
#include "ns3/simulator.h"
#include "ns3/simple-channel.h"
#include "ns3/simple-net-device.h"
@@ -356,36 +497,55 @@ UdpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
namespace ns3 {
class UdpSocketTest: public Test
class UdpSocketImplTest: public Test
{
Ptr<Packet> m_receivedPacket;
Ptr<Packet> m_receivedPacket2;
public:
virtual bool RunTests (void);
UdpSocketTest ();
UdpSocketImplTest ();
void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
void ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
void ReceivePkt (Ptr<Socket> socket);
void ReceivePkt2 (Ptr<Socket> socket);
};
UdpSocketTest::UdpSocketTest ()
: Test ("UdpSocket") {}
UdpSocketImplTest::UdpSocketImplTest ()
: Test ("UdpSocketImpl")
{
}
void UdpSocketTest::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
void UdpSocketImplTest::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
{
m_receivedPacket = packet;
}
void UdpSocketTest::ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
void UdpSocketImplTest::ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
{
m_receivedPacket2 = packet;
}
void UdpSocketImplTest::ReceivePkt (Ptr<Socket> socket)
{
uint32_t availableData;
availableData = socket->GetRxAvailable ();
m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max(), 0);
NS_ASSERT (availableData == m_receivedPacket->GetSize ());
}
void UdpSocketImplTest::ReceivePkt2 (Ptr<Socket> socket)
{
uint32_t availableData;
availableData = socket->GetRxAvailable ();
m_receivedPacket2 = socket->Recv (std::numeric_limits<uint32_t>::max(), 0);
NS_ASSERT (availableData == m_receivedPacket2->GetSize ());
}
bool
UdpSocketTest::RunTests (void)
UdpSocketImplTest::RunTests (void)
{
bool result = true;
@@ -454,16 +614,16 @@ UdpSocketTest::RunTests (void)
// Create the UDP sockets
Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<Udp> ();
Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
NS_TEST_ASSERT_EQUAL (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.1"), 1234)), 0);
rxSocket->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket, this));
rxSocket->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt, this));
Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket2, this));
rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("10.0.1.1"), 1234)), 0);
Ptr<SocketFactory> txSocketFactory = txNode->GetObject<Udp> ();
Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
// ------ Now the tests ------------
@@ -471,24 +631,28 @@ UdpSocketTest::RunTests (void)
// Unicast test
m_receivedPacket = Create<Packet> ();
m_receivedPacket2 = Create<Packet> ();
NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("10.0.0.1"), 1234),
Create<Packet> (123)), 123);
NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123),
InetSocketAddress (Ipv4Address("10.0.0.1"), 1234)), 123);
Simulator::Run ();
NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0); // second interface should receive it
m_receivedPacket->RemoveAllTags ();
m_receivedPacket2->RemoveAllTags ();
// Simple broadcast test
m_receivedPacket = Create<Packet> ();
m_receivedPacket2 = Create<Packet> ();
NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234),
Create<Packet> (123)), 123);
NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123),
InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
Simulator::Run ();
NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
// second socket should not receive it (it is bound specifically to the second interface's address
NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0);
m_receivedPacket->RemoveAllTags ();
m_receivedPacket2->RemoveAllTags ();
// Broadcast test with multiple receiving sockets
@@ -497,24 +661,26 @@ UdpSocketTest::RunTests (void)
// the socket address matches.
rxSocket2->Dispose ();
rxSocket2 = rxSocketFactory->CreateSocket ();
rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket2, this));
rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0);
m_receivedPacket = Create<Packet> ();
m_receivedPacket2 = Create<Packet> ();
NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234),
Create<Packet> (123)), 123);
NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create<Packet> (123),
InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
Simulator::Run ();
NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 123);
m_receivedPacket->RemoveAllTags ();
m_receivedPacket2->RemoveAllTags ();
Simulator::Destroy ();
return result;
}
static UdpSocketTest gUdpSocketTest;
static UdpSocketImplTest gUdpSocketImplTest;
}; // namespace ns3

View File

@@ -17,14 +17,17 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef UDP_SOCKET_H
#define UDP_SOCKET_H
#ifndef UDP_SOCKET_IMPL_H
#define UDP_SOCKET_IMPL_H
#include <stdint.h>
#include <queue>
#include "ns3/callback.h"
#include "ns3/traced-callback.h"
#include "ns3/socket.h"
#include "ns3/ptr.h"
#include "ns3/ipv4-address.h"
#include "ns3/udp-socket.h"
namespace ns3 {
@@ -33,14 +36,15 @@ class Node;
class Packet;
class UdpL4Protocol;
class UdpSocket : public Socket
class UdpSocketImpl : public UdpSocket
{
public:
static TypeId GetTypeId (void);
/**
* Create an unbound udp socket.
*/
UdpSocket ();
virtual ~UdpSocket ();
UdpSocketImpl ();
virtual ~UdpSocketImpl ();
void SetNode (Ptr<Node> node);
void SetUdp (Ptr<UdpL4Protocol> udp);
@@ -54,12 +58,22 @@ public:
virtual int ShutdownRecv (void);
virtual int Connect(const Address &address);
virtual int Send (Ptr<Packet> p);
virtual int SendTo(const Address &address,Ptr<Packet> p);
virtual int SendTo (Ptr<Packet> p, const Address &address);
virtual uint32_t GetTxAvailable (void) const;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual uint32_t GetRxAvailable (void) const;
private:
// Attributes set through UdpSocket base class
virtual void SetRcvBufSize (uint32_t size);
virtual uint32_t GetRcvBufSize (void) const;
virtual void SetIpTtl (uint32_t ipTtl);
virtual uint32_t GetIpTtl (void) const;
virtual void SetIpMulticastTtl (uint32_t ipTtl);
virtual uint32_t GetIpMulticastTtl (void) const;
private:
friend class Udp;
friend class UdpSocketFactory;
// invoked by Udp class
int FinishBind (void);
void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
@@ -75,12 +89,23 @@ private:
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;
TracedCallback<Ptr<const Packet> > m_dropTrace;
enum SocketErrno m_errno;
bool m_shutdownSend;
bool m_shutdownRecv;
bool m_connected;
std::queue<Ptr<Packet> > m_deliveryQueue;
uint32_t m_rxAvailable;
// Socket attributes
uint32_t m_rcvBufSize;
uint32_t m_ipTtl;
uint32_t m_ipMulticastTtl;
};
}//namespace ns3
#endif /* UDP_SOCKET_H */
#endif /* UDP_SOCKET_IMPL_H */

View File

@@ -22,12 +22,12 @@ def build(bld):
'arp-ipv4-interface.cc',
'arp-l3-protocol.cc',
'ipv4-loopback-interface.cc',
'udp-socket.cc',
'tcp-socket.cc',
'udp-socket-impl.cc',
'tcp-socket-impl.cc',
'ipv4-end-point-demux.cc',
'ipv4-impl.cc',
'udp-impl.cc',
'tcp-impl.cc',
'udp-socket-factory-impl.cc',
'tcp-socket-factory-impl.cc',
'pending-data.cc',
'sequence-number.cc',
'rtt-estimator.cc',

View File

@@ -61,8 +61,6 @@ public:
double xMax;
double yMin;
double yMax;
ATTRIBUTE_HELPER_HEADER_1 (Rectangle);
};
std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
@@ -73,7 +71,7 @@ std::istream &operator >> (std::istream &is, Rectangle &rectangle);
* \brief hold objects of type ns3::Rectangle
*/
ATTRIBUTE_HELPER_HEADER_2 (Rectangle);
ATTRIBUTE_HELPER_HEADER (Rectangle);
} // namespace ns3

View File

@@ -57,8 +57,6 @@ public:
* z coordinate of vector vector
*/
double z;
ATTRIBUTE_HELPER_HEADER_1 (Vector);
};
double CalculateDistance (const Vector &a, const Vector &b);
@@ -68,7 +66,7 @@ double CalculateDistance (const Vector &a, const Vector &b);
* \brief hold objects of type ns3::Vector
*/
ATTRIBUTE_HELPER_HEADER_2 (Vector);
ATTRIBUTE_HELPER_HEADER (Vector);
std::ostream &operator << (std::ostream &os, const Vector &vector);
std::istream &operator >> (std::istream &is, Vector &vector);

View File

@@ -107,6 +107,30 @@ Address::Register (void)
return type;
}
uint32_t
Address::GetSerializedSize (void) const
{
return 1 + 1 + m_len;
}
void
Address::Serialize (uint8_t* buf, uint32_t len) const
{
NS_ASSERT (len >= static_cast<uint32_t> (m_len + 2));
buf[0] = m_type;
buf[1] = m_len;
for (uint8_t i = 0; i < m_len; i++)
{
buf[i+2] = m_data[i];
}
}
Address
Address::Deserialize (const uint8_t* buf)
{
return Address (buf[0], buf + 2, buf[1]);
}
ATTRIBUTE_HELPER_CPP (Address);

View File

@@ -153,8 +153,28 @@ public:
* \returns a new type id.
*/
static uint8_t Register (void);
/**
* Get the number of bytes needed to serialize the underlying Address
* Typically, this is GetLength () + 2
*
* \returns the number of bytes required for an Address in serialized form
*/
uint32_t GetSerializedSize (void) const;
/**
* Serialize this address in host byte order to a byte buffer
*
* \param buf output buffer that gets written with this Address
* \param len length of output buffer
*/
void Serialize (uint8_t* buf, uint32_t len) const;
/**
* \param buf buffer to read address from
* \returns an Address
*
* The input address buffer is expected to be in host byte order format.
*/
static Address Deserialize (const uint8_t* buf);
ATTRIBUTE_HELPER_HEADER_1 (Address);
private:
friend bool operator == (const Address &a, const Address &b);
friend bool operator < (const Address &a, const Address &b);
@@ -171,7 +191,7 @@ private:
* \brief hold objects of type ns3::Address
*/
ATTRIBUTE_HELPER_HEADER_2 (Address);
ATTRIBUTE_HELPER_HEADER (Address);
bool operator == (const Address &a, const Address &b);
bool operator != (const Address &a, const Address &b);

View File

@@ -142,7 +142,6 @@ public:
static Ipv4Address GetBroadcast (void);
static Ipv4Address GetLoopback (void);
ATTRIBUTE_HELPER_HEADER_1 (Ipv4Address);
private:
Address ConvertTo (void) const;
static uint8_t GetType (void);
@@ -180,7 +179,6 @@ public:
static Ipv4Mask GetLoopback (void);
static Ipv4Mask GetZero (void);
ATTRIBUTE_HELPER_HEADER_1 (Ipv4Mask);
private:
uint32_t m_mask;
};
@@ -194,8 +192,8 @@ private:
* \brief hold objects of type ns3::Ipv4Mask
*/
ATTRIBUTE_HELPER_HEADER_2 (Ipv4Address);
ATTRIBUTE_HELPER_HEADER_2 (Ipv4Mask);
ATTRIBUTE_HELPER_HEADER (Ipv4Address);
ATTRIBUTE_HELPER_HEADER (Ipv4Mask);
std::ostream& operator<< (std::ostream& os, Ipv4Address const& address);
std::ostream& operator<< (std::ostream& os, Ipv4Mask const& mask);

View File

@@ -96,7 +96,6 @@ public:
*/
static Mac48Address GetBroadcast (void);
ATTRIBUTE_HELPER_HEADER_1 (Mac48Address);
private:
/**
* \returns a new Address instance
@@ -117,7 +116,7 @@ private:
* \brief hold objects of type ns3::Mac48Address
*/
ATTRIBUTE_HELPER_HEADER_2 (Mac48Address);
ATTRIBUTE_HELPER_HEADER (Mac48Address);
bool operator == (const Mac48Address &a, const Mac48Address &b);
bool operator != (const Mac48Address &a, const Mac48Address &b);

View File

@@ -24,12 +24,31 @@
#include "ns3/log.h"
#include "ns3/node.h"
#include "ns3/packet.h"
#include "ns3/uinteger.h"
#include "ns3/trace-source-accessor.h"
NS_LOG_COMPONENT_DEFINE ("PacketSocket");
namespace ns3 {
PacketSocket::PacketSocket ()
TypeId
PacketSocket::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::PacketSocket")
.SetParent<Socket> ()
.AddConstructor<PacketSocket> ()
.AddTraceSource ("Drop", "Drop packet due to receive buffer overflow",
MakeTraceSourceAccessor (&PacketSocket::m_dropTrace))
.AddAttribute ("RcvBufSize",
"PacketSocket maximum receive buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&PacketSocket::m_rcvBufSize),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
PacketSocket::PacketSocket () : m_rxAvailable (0)
{
NS_LOG_FUNCTION_NOARGS ();
m_state = STATE_OPEN;
@@ -41,6 +60,7 @@ PacketSocket::PacketSocket ()
void
PacketSocket::SetNode (Ptr<Node> node)
{
NS_LOG_FUNCTION_NOARGS ();
m_node = node;
}
@@ -211,11 +231,19 @@ PacketSocket::Send (Ptr<Packet> p)
m_errno = ERROR_NOTCONN;
return -1;
}
return SendTo (m_destAddr, p);
return SendTo (p, m_destAddr);
}
// XXX must limit it to interface MTU
uint32_t
PacketSocket::GetTxAvailable (void) const
{
// Use 65536 for now
return 0xffff;
}
int
PacketSocket::SendTo(const Address &address, Ptr<Packet> p)
PacketSocket::SendTo(Ptr<Packet> p, const Address &address)
{
NS_LOG_FUNCTION_NOARGS ();
PacketSocketAddress ad;
@@ -244,6 +272,11 @@ PacketSocket::SendTo(const Address &address, Ptr<Packet> p)
m_errno = ERROR_AFNOSUPPORT;
return -1;
}
if (p->GetSize () > GetTxAvailable ())
{
m_errno = ERROR_MSGSIZE;
return -1;
}
ad = PacketSocketAddress::ConvertFrom (address);
bool error = false;
@@ -301,8 +334,56 @@ PacketSocket::ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet,
address.SetSingleDevice (device->GetIfIndex ());
address.SetProtocol (protocol);
NS_LOG_LOGIC ("UID is " << packet->GetUid() << " PacketSocket " << this);
NotifyDataReceived (packet, address);
if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
{
SocketRxAddressTag tag;
tag.SetAddress (address);
packet->AddTag (tag);
m_deliveryQueue.push (packet);
m_rxAvailable += packet->GetSize ();
NS_LOG_LOGIC ("UID is " << packet->GetUid() << " PacketSocket " << this);
NotifyDataRecv ();
}
else
{
// In general, this case should not occur unless the
// receiving application reads data from this socket slowly
// in comparison to the arrival rate
//
// drop and trace packet
NS_LOG_WARN ("No receive buffer space available. Drop.");
m_dropTrace (packet);
}
}
Ptr<Packet>
PacketSocket::Recv (uint32_t maxSize, uint32_t flags)
{
NS_LOG_FUNCTION_NOARGS ();
if (m_deliveryQueue.empty() )
{
return 0;
}
Ptr<Packet> p = m_deliveryQueue.front ();
if (p->GetSize () <= maxSize)
{
m_deliveryQueue.pop ();
m_rxAvailable -= p->GetSize ();
}
else
{
p = 0;
}
return p;
}
uint32_t
PacketSocket::GetRxAvailable (void) const
{
NS_LOG_FUNCTION_NOARGS ();
// We separately maintain this state to avoid walking the queue
// every time this might be called
return m_rxAvailable;
}
}//namespace ns3

View File

@@ -22,7 +22,9 @@
#define PACKET_SOCKET_H
#include <stdint.h>
#include <queue>
#include "ns3/callback.h"
#include "ns3/traced-callback.h"
#include "ns3/ptr.h"
#include "ns3/socket.h"
@@ -71,6 +73,8 @@ class PacketSocketAddress;
class PacketSocket : public Socket
{
public:
static TypeId GetTypeId (void);
PacketSocket ();
virtual ~PacketSocket ();
@@ -85,8 +89,12 @@ public:
virtual int ShutdownRecv (void);
virtual int Connect(const Address &address);
virtual int Send (Ptr<Packet> p);
virtual int SendTo(const Address &address,Ptr<Packet> p);
virtual uint32_t GetTxAvailable (void) const;
virtual int SendTo(Ptr<Packet> p, const Address &address);
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual uint32_t GetRxAvailable (void) const;
private:
void ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet,
@@ -109,6 +117,15 @@ private:
bool m_isSingleDevice;
uint32_t m_device;
Address m_destAddr; /// Default destination address
std::queue<Ptr<Packet> > m_deliveryQueue;
uint32_t m_rxAvailable;
TracedCallback<Ptr<const Packet> > m_dropTrace;
// Socket options (attributes)
uint32_t m_rcvBufSize;
};
}//namespace ns3

View File

@@ -0,0 +1,42 @@
/* -*- 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
*
*/
#include "socket-defaults.h"
#include "ns3/uinteger.h"
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (SocketDefaults);
TypeId SocketDefaults::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::SocketDefaults")
.SetParent<Object> ()
.AddAttribute ("DefaultSndBufLimit",
"Default maximum receive buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&SocketDefaults::m_defaultSndBufLimit),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultRcvBufLimit",
"Default maximum receive buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&SocketDefaults::m_defaultRcvBufLimit),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
} // namespace ns3

View File

@@ -0,0 +1,42 @@
/* -*- 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
*/
#ifndef SOCKET_DEFAULTS_H
#define SOCKET_DEFAULTS_H
#include "ns3/object.h"
namespace ns3 {
/**
* \brief Object to hold socket option defaults
*
* This class can be aggregated to a Node and can be used to store
* socket defaults for a Node.
*
*/
class SocketDefaults : public Object
{
public:
static TypeId GetTypeId (void);
private:
uint32_t m_defaultSndBufLimit;
uint32_t m_defaultRcvBufLimit;
};
} // namespace ns3
#endif /* SOCKET_DEFAULTS_H */

View File

@@ -22,17 +22,34 @@
#include "ns3/log.h"
#include "ns3/packet.h"
#include "node.h"
#include "socket.h"
#include "socket-factory.h"
NS_LOG_COMPONENT_DEFINE ("Socket");
namespace ns3 {
Socket::Socket (void)
{
NS_LOG_FUNCTION_NOARGS ();
}
Socket::~Socket ()
{
NS_LOG_FUNCTION_NOARGS ();
}
Ptr<Socket>
Socket::CreateSocket (Ptr<Node> node, TypeId tid)
{
Ptr<Socket> s;
Ptr<SocketFactory> socketFactory = node->GetObject<SocketFactory> (tid);
s = socketFactory->CreateSocket ();
NS_ASSERT (s != 0);
return s;
}
void
Socket::SetCloseCallback (Callback<void,Ptr<Socket> > closeCompleted)
{
@@ -80,7 +97,7 @@ Socket::SetSendCallback (Callback<void, Ptr<Socket>, uint32_t> sendCb)
}
void
Socket::SetRecvCallback (Callback<void, Ptr<Socket>, Ptr<Packet>,const Address&> receivedData)
Socket::SetRecvCallback (Callback<void, Ptr<Socket> > receivedData)
{
NS_LOG_FUNCTION_NOARGS ();
m_receivedData = receivedData;
@@ -107,7 +124,21 @@ int Socket::Send (const uint8_t* buf, uint32_t size)
return Send (p);
}
int Socket::SendTo (const Address &address, const uint8_t* buf, uint32_t size)
Ptr<Packet>
Socket::Recv (void)
{
return Recv (std::numeric_limits<uint32_t>::max(), 0);
}
int
Socket::Recv (uint8_t* buf, uint32_t size, uint32_t flags)
{
Ptr<Packet> p = Recv (size, flags); // read up to "size" bytes
memcpy (buf, p->PeekData (), p->GetSize());
return p->GetSize ();
}
int Socket::SendTo (const uint8_t* buf, uint32_t size, const Address &address)
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<Packet> p;
@@ -119,7 +150,7 @@ int Socket::SendTo (const Address &address, const uint8_t* buf, uint32_t size)
{
p = Create<Packet> (size);
}
return SendTo (address,p);
return SendTo (p, address);
}
void
@@ -221,13 +252,127 @@ Socket::NotifySend (uint32_t spaceAvailable)
}
void
Socket::NotifyDataReceived (Ptr<Packet> p, const Address &from)
Socket::NotifyDataRecv (void)
{
NS_LOG_FUNCTION_NOARGS ();
if (!m_receivedData.IsNull ())
{
m_receivedData (this, p, from);
m_receivedData (this);
}
}
/***************************************************************
* Socket Tags
***************************************************************/
SocketRxAddressTag::SocketRxAddressTag ()
{
}
void
SocketRxAddressTag::SetAddress (Address addr)
{
m_address = addr;
}
Address
SocketRxAddressTag::GetAddress (void) const
{
return m_address;
}
TypeId
SocketRxAddressTag::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::SocketRxAddressTag")
.SetParent<Tag> ()
.AddConstructor<SocketRxAddressTag> ()
;
return tid;
}
TypeId
SocketRxAddressTag::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
uint32_t
SocketRxAddressTag::GetSerializedSize (void) const
{
return m_address.GetSerializedSize ();
}
void
SocketRxAddressTag::Serialize (TagBuffer i) const
{
uint8_t len = m_address.GetSerializedSize ();
uint8_t* buffer = new uint8_t[len];
memset (buffer, 0, len);
m_address.Serialize (buffer, len);
i.Write (buffer, len);
delete [] buffer;
}
void
SocketRxAddressTag::Deserialize (TagBuffer i)
{
uint8_t type = i.ReadU8 ();
uint8_t len = i.ReadU8 ();
// Len is the length of the address starting from buffer[2]
NS_ASSERT (len >= 2);
uint8_t* buffer = new uint8_t[len];
memset (buffer, 0, len);
buffer[0] = type;
buffer[1] = len;
i.Read (buffer+2, len); // ReadU8 consumes a byte
m_address = Address::Deserialize (buffer);
delete [] buffer;
}
SocketIpTtlTag::SocketIpTtlTag ()
{
}
void
SocketIpTtlTag::SetTtl (uint8_t ttl)
{
m_ttl = ttl;
}
uint8_t
SocketIpTtlTag::GetTtl (void) const
{
return m_ttl;
}
TypeId
SocketIpTtlTag::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::SocketIpTtlTag")
.SetParent<Tag> ()
.AddConstructor<SocketIpTtlTag> ()
;
return tid;
}
TypeId
SocketIpTtlTag::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
uint32_t
SocketIpTtlTag::GetSerializedSize (void) const
{
return 1;
}
void
SocketIpTtlTag::Serialize (TagBuffer i) const
{
i.WriteU8 (m_ttl);
}
void
SocketIpTtlTag::Deserialize (TagBuffer i)
{
m_ttl = i.ReadU8 ();
}
}//namespace ns3

View File

@@ -25,29 +25,43 @@
#include "ns3/callback.h"
#include "ns3/ptr.h"
#include "ns3/tag.h"
#include "ns3/object.h"
#include "address.h"
#include <stdint.h>
namespace ns3 {
class Node;
class Packet;
/**
* \brief Define a Socket API based on the BSD Socket API.
* \ingroup node
* \defgroup socket Socket
* \brief A low-level Socket API based loosely on the BSD Socket API.
*
* Contrary to the original BSD socket API, this API is asynchronous:
* it does not contain blocking calls. It also uses class ns3::Packet
* as a fancy byte buffer, allowing data to be passed across the API
* using an ns3::Packet instead of a raw data pointer. Other than that,
* it tries to stick to the BSD API to make it easier for those who know
* the BSD API to use this API.
* A few things to keep in mind about this type of socket:
* - it uses ns-3 API constructs such as class ns3::Address instead of
* C-style structs
* - in contrast to the original BSD socket API, this API is asynchronous:
* it does not contain blocking calls. Sending and receiving operations
* must make use of the callbacks provided.
* - It also uses class ns3::Packet as a fancy byte buffer, allowing
* data to be passed across the API using an ns-3 Packet instead of
* a raw data pointer.
* - Not all of the full POSIX sockets API is supported
*
* Other than that, it tries to stick to the BSD API to make it
* easier for those who know the BSD API to use this API.
* More details are provided in the ns-3 tutorial.
*/
class Socket : public Object
{
public:
virtual ~Socket();
Socket (void);
virtual ~Socket (void);
enum SocketErrno {
ERROR_NOTERROR,
@@ -64,6 +78,17 @@ public:
SOCKET_ERRNO_LAST
};
/**
* This method wraps the creation of sockets that is performed
* by a socket factory on a given node based on a TypeId.
*
* \return A smart pointer to a newly created socket.
*
* \param node The node on which to create the socket
* \param tid The TypeId of the socket to create
*/
static Ptr<Socket> CreateSocket (Ptr<Node> node, TypeId tid);
/**
* \return the errno associated to the last call which failed in this
* socket. Each socket's errno is initialized to zero
@@ -151,13 +176,13 @@ public:
*/
void SetSendCallback (Callback<void, Ptr<Socket>, uint32_t> sendCb);
/**
* \brief Receive data
* \param receivedData Invoked whenever new data is received.
* \brief Notify application when new data is available to be read.
*
* This callback is intended to notify a socket that would
* have been blocked in a blocking socket model that data
* is available to be read.
*/
void SetRecvCallback (Callback<void, Ptr<Socket>, Ptr<Packet>,
const Address&> receivedData);
void SetRecvCallback (Callback<void, Ptr<Socket> >);
/**
* \param address the address to try to allocate
* \returns 0 on success, -1 on failure.
@@ -212,12 +237,53 @@ public:
/**
* \brief Send data (or dummy data) to the remote host
* \param p packet to send
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*
* This function matches closely in semantics to the send() function
* call in the standard C library (libc):
* ssize_t send (int s, const void *msg, size_t len, int flags);
* except that the function call is asynchronous.
*
* In a typical blocking sockets model, this call would block upon
* lack of space to hold the message to be sent. In ns-3 at this
* API, the call returns immediately in such a case, but the callback
* registered with SetSendCallback() is invoked when the socket
* has space (when it conceptually unblocks); this is an asynchronous
* I/O model for send().
*
* This variant of Send() uses class ns3::Packet to encapsulate
* data, rather than providing a raw pointer and length field.
* This allows an ns-3 application to attach tags if desired (such
* as a flow ID) and may allow the simulator to avoid some data
* copies. Despite the appearance of sending Packets on a stream
* socket, just think of it as a fancy byte buffer with streaming
* semantics.
*
* If either the message buffer within the Packet is too long to pass
* atomically through the underlying protocol (for datagram sockets),
* or the message buffer cannot entirely fit in the transmit buffer
* (for stream sockets), -1 is returned and SocketErrno is set
* to ERROR_MSGSIZE. If the packet does not fit, the caller can
* split the Packet (based on information obtained from
* GetTxAvailable) and reattempt to send the data.
*
* \param p ns3::Packet to send
* \returns the number of bytes accepted for transmission if no error
* occurs, and -1 otherwise.
*/
virtual int Send (Ptr<Packet> p) = 0;
/**
* \brief Returns the number of bytes which can be sent in a single call
* to Send.
*
* For datagram sockets, this returns the number of bytes that
* can be passed atomically through the underlying protocol.
*
* For stream sockets, this returns the available space in bytes
* left in the transmit buffer.
*/
virtual uint32_t GetTxAvailable (void) const = 0;
/**
* \brief Send data (or dummy data) to the remote host
* \param buf A pointer to a raw byte buffer of some data to send. If this
@@ -231,27 +297,66 @@ public:
/**
* \brief Send data to a specified peer.
* \param address IP Address of remote host
* \param p packet to send
* \param address IP Address of remote host
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*/
virtual int SendTo (const Address &address,Ptr<Packet> p) = 0;
virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
/**
* \brief Send data to a specified peer.
* \param address IP Address of remote host
* \param buf A pointer to a raw byte buffer of some data to send. If this
* is 0, we send dummy data whose size is specified by the third parameter
* \param size the number of bytes to copy from the buffer
* \param address IP Address of remote host
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*
* This is provided so as to have an API which is closer in appearance
* to that of real network or BSD sockets.
*/
int SendTo (const Address &address, const uint8_t* buf, uint32_t size);
int SendTo (const uint8_t* buf, uint32_t size, const Address &address);
/**
* \brief Read a single packet from the socket
* \param maxSize reader will accept packet up to maxSize
* \param flags Socket recv flags
* \returns Ptr<Packet> of the next in-sequence packet. Returns
* 0 if the socket cannot return a next in-sequence packet conforming
* to the maxSize and flags.
*/
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
/**
* \brief Read a single packet from the socket
*
* Overloaded version of Recv(maxSize, flags) with maxSize
* implicitly set to maximum sized integer, and flags set to zero.
*
* \returns Ptr<Packet> of the next in-sequence packet. Returns
* 0 if the socket cannot return a next in-sequence packet.
*/
Ptr<Packet> Recv (void);
/**
* \brief Recv data (or dummy data) from the remote host
* \param buf A pointer to a raw byte buffer to write the data to.
* If the underlying packet was carring null (fake) data, this buffer
* will be zeroed up to the length specified by the return value.
* \param size Number of bytes (at most) to copy to buf
* \param flags any flags to pass to the socket
* \returns number of bytes copied into buf
*
* This is provided so as to have an API which is closer in appearance
* to that of real network or BSD sockets.
*/
int Recv (uint8_t* buf, uint32_t size, uint32_t flags);
/**
* Return number of bytes which can be returned from one or
* multiple calls to Recv.
* Must be possible to call this method from the Recv callback.
*/
virtual uint32_t GetRxAvailable (void) const = 0;
protected:
void NotifyCloseCompleted (void);
void NotifyConnectionSucceeded (void);
@@ -262,7 +367,7 @@ protected:
void NotifyCloseRequested (void);
void NotifyDataSent (uint32_t size);
void NotifySend (uint32_t spaceAvailable);
void NotifyDataReceived (Ptr<Packet> p, const Address &from);
void NotifyDataRecv (void);
Callback<void,Ptr<Socket> > m_closeCompleted;
Callback<void, Ptr<Socket> > m_connectionSucceeded;
@@ -273,7 +378,50 @@ protected:
Callback<void, Ptr<Socket>, const Address&> m_newConnectionCreated;
Callback<void, Ptr<Socket>, uint32_t> m_dataSent;
Callback<void, Ptr<Socket>, uint32_t > m_sendCb;
Callback<void, Ptr<Socket>, Ptr<Packet>,const Address&> m_receivedData;
Callback<void, Ptr<Socket> > m_receivedData;
};
/**
* \brief This class implements a tag that carries the source address
* of a packet across the receiving socket interface.
*/
class SocketRxAddressTag : public Tag
{
public:
SocketRxAddressTag ();
void SetAddress (Address addr);
Address GetAddress (void) const;
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual uint32_t GetSerializedSize (void) const;
virtual void Serialize (TagBuffer i) const;
virtual void Deserialize (TagBuffer i);
private:
Address m_address;
};
/**
* \brief This class implements a tag that carries the socket-specific
* TTL of a packet to the IP layer
*/
class SocketIpTtlTag : public Tag
{
public:
SocketIpTtlTag ();
void SetTtl (uint8_t ttl);
uint8_t GetTtl (void) const;
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual uint32_t GetSerializedSize (void) const;
virtual void Serialize (TagBuffer i) const;
virtual void Deserialize (TagBuffer i);
private:
uint8_t m_ttl;
};
} //namespace ns3

View File

@@ -0,0 +1,37 @@
/* -*- 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-socket-factory.h"
#include "ns3/uinteger.h"
#include "ns3/double.h"
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (TcpSocketFactory);
TypeId
TcpSocketFactory::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::TcpSocketFactory")
.SetParent<SocketFactory> ()
;
return tid;
}
} // namespace ns3

View File

@@ -17,8 +17,8 @@
*
* Author: Raj Bhattacharjea <raj.b@gatech.edu>
*/
#ifndef TCP_H
#define TCP_H
#ifndef TCP_SOCKET_FACTORY_H
#define TCP_SOCKET_FACTORY_H
#include "socket-factory.h"
@@ -34,44 +34,22 @@ class Socket;
* 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
* All TCP socket factory implementations must provide an implementation
* of CreateSocket
* below, and should make use of the default values configured below.
*
* \see TcpImpl
* \see TcpSocketFactoryImpl
*
*/
class Tcp : public SocketFactory
class TcpSocketFactory : public SocketFactory
{
public:
static TypeId GetTypeId (void);
virtual Ptr<Socket> CreateSocket (void) = 0;
uint32_t GetDefaultSegSize (void) const;
uint32_t GetDefaultAdvWin (void) const;
uint32_t GetDefaultSsThresh (void) const;
uint32_t GetDefaultTxBuffer (void) const;
uint32_t GetDefaultRxBuffer (void) const;
uint32_t GetDefaultInitialCwnd (void) const;
uint32_t GetDefaultConnTimeout (void) const;
uint32_t GetDefaultConnCount (void) const;
double GetDefaultDelAckTimeout (void) const;
uint32_t GetDefaultDelAckCount (void) const;
private:
uint32_t m_defaultSegSize;
uint32_t m_defaultAdvWin;
uint32_t m_defaultSsThresh;
uint32_t m_defaultTxBuffer;
uint32_t m_defaultRxBuffer;
uint32_t m_defaultInitialCwnd;
uint32_t m_defaultConnTimeout;
uint32_t m_defaultConnCount;
double m_defaultDelAckTimeout;
uint32_t m_defaultDelAckCount;
};
} // namespace ns3
#endif /* TCP_H */
#endif /* TCP_SOCKET_FACTORY_H */

114
src/node/tcp-socket.cc Normal file
View File

@@ -0,0 +1,114 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ns3/object.h"
#include "ns3/log.h"
#include "ns3/uinteger.h"
#include "ns3/double.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/nstime.h"
#include "tcp-socket.h"
NS_LOG_COMPONENT_DEFINE ("TcpSocket");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (TcpSocket);
TypeId
TcpSocket::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::TcpSocket")
.SetParent<Socket> ()
.AddAttribute ("SndBufSize",
"TcpSocket maximum transmit buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&TcpSocket::GetSndBufSize,
&TcpSocket::SetSndBufSize),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("RcvBufSize",
"TcpSocket maximum receive buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&TcpSocket::GetRcvBufSize,
&TcpSocket::SetRcvBufSize),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("SegmentSize",
"TCP maximum segment size in bytes (may be adjusted based on MTU discovery)",
UintegerValue (536),
MakeUintegerAccessor (&TcpSocket::GetSegSize,
&TcpSocket::SetSegSize),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("AdvertisedWindowSize",
"TCP advertised window size (bytes)",
UintegerValue (0xffff),
MakeUintegerAccessor (&TcpSocket::GetAdvWin,
&TcpSocket::SetAdvWin),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("SlowStartThreshold",
"TCP slow start threshold (bytes)",
UintegerValue (0xffff),
MakeUintegerAccessor (&TcpSocket::GetSSThresh,
&TcpSocket::SetSSThresh),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("InitialCwnd",
"TCP initial congestion window size (segments)",
UintegerValue (1),
MakeUintegerAccessor (&TcpSocket::GetInitialCwnd,
&TcpSocket::SetInitialCwnd),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ConnTimeout",
"TCP retransmission timeout when opening connection (seconds)",
TimeValue (Seconds (3)),
MakeTimeAccessor (&TcpSocket::GetConnTimeout,
&TcpSocket::SetConnTimeout),
MakeTimeChecker ())
.AddAttribute ("ConnCount",
"Number of connection attempts (SYN retransmissions) before returning failure",
UintegerValue (6),
MakeUintegerAccessor (&TcpSocket::GetConnCount,
&TcpSocket::SetConnCount),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DelAckTimeout",
"Timeout value for TCP delayed acks, in seconds",
TimeValue (Seconds (0.2)),
MakeTimeAccessor (&TcpSocket::GetDelAckTimeout,
&TcpSocket::SetDelAckTimeout),
MakeTimeChecker ())
.AddAttribute ("DelAckCount",
"Number of packets to wait before sending a TCP ack",
UintegerValue (2),
MakeUintegerAccessor (&TcpSocket::GetDelAckMaxCount,
&TcpSocket::SetDelAckMaxCount),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
TcpSocket::TcpSocket ()
{
NS_LOG_FUNCTION_NOARGS ();
}
TcpSocket::~TcpSocket ()
{
NS_LOG_FUNCTION_NOARGS ();
}
}; // namespace ns3

94
src/node/tcp-socket.h Normal file
View File

@@ -0,0 +1,94 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2006 Georgia Tech Research Corporation
* 2007 INRIA
*
* 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
*
* Authors: George F. Riley<riley@ece.gatech.edu>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef __TCP_SOCKET_H__
#define __TCP_SOCKET_H__
#include "socket.h"
#include "ns3/traced-callback.h"
#include "ns3/callback.h"
#include "ns3/ptr.h"
#include "ns3/object.h"
#include "ns3/nstime.h"
namespace ns3 {
class Node;
class Packet;
/**
* \brief (abstract) base class of all TcpSockets
*
* This class exists solely for hosting TcpSocket attributes that can
* be reused across different implementations.
*/
class TcpSocket : public Socket
{
public:
static TypeId GetTypeId (void);
TcpSocket (void);
virtual ~TcpSocket (void);
virtual enum Socket::SocketErrno GetErrno (void) const = 0;
virtual Ptr<Node> GetNode (void) const = 0;
virtual int Bind () = 0;
virtual int Close (void) = 0;
virtual int ShutdownSend (void) = 0;
virtual int ShutdownRecv (void) = 0;
virtual int Connect (const Address &address) = 0;
virtual int Send (Ptr<Packet> p) = 0;
virtual uint32_t GetTxAvailable (void) const = 0;
virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
virtual uint32_t GetRxAvailable (void) const = 0;
private:
// Indirect the attribute setting and getting through private virtual methods
virtual void SetSndBufSize (uint32_t size) = 0;
virtual uint32_t GetSndBufSize (void) const = 0;
virtual void SetRcvBufSize (uint32_t size) = 0;
virtual uint32_t GetRcvBufSize (void) const = 0;
virtual void SetSegSize (uint32_t size) = 0;
virtual uint32_t GetSegSize (void) const = 0;
virtual void SetAdvWin (uint32_t window) = 0;
virtual uint32_t GetAdvWin (void) const = 0;
virtual void SetSSThresh (uint32_t threshold) = 0;
virtual uint32_t GetSSThresh (void) const = 0;
virtual void SetInitialCwnd (uint32_t count) = 0;
virtual uint32_t GetInitialCwnd (void) const = 0;
virtual void SetConnTimeout (Time timeout) = 0;
virtual Time GetConnTimeout (void) const = 0;
virtual void SetConnCount (uint32_t count) = 0;
virtual uint32_t GetConnCount (void) const = 0;
virtual void SetDelAckTimeout (Time timeout) = 0;
virtual Time GetDelAckTimeout (void) const = 0;
virtual void SetDelAckMaxCount (uint32_t count) = 0;
virtual uint32_t GetDelAckMaxCount (void) const = 0;
};
} //namespace ns3
#endif /* TCP_SOCKET_H */

View File

@@ -1,140 +0,0 @@
/* -*- 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"
#include "ns3/uinteger.h"
#include "ns3/double.h"
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (Tcp);
TypeId
Tcp::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Tcp")
.SetParent<SocketFactory> ()
.AddAttribute ("DefaultSegmentSize",
"Default TCP maximum segment size in bytes (may be adjusted based on MTU discovery)",
UintegerValue (536),
MakeUintegerAccessor (&Tcp::m_defaultSegSize),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultAdvertisedWindowSize",
"Default TCP advertised window size (bytes)",
UintegerValue (0xffff),
MakeUintegerAccessor (&Tcp::m_defaultAdvWin),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultSlowStartThreshold",
"Default TCP slow start threshold (bytes)",
UintegerValue (0xffff),
MakeUintegerAccessor (&Tcp::m_defaultSsThresh),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultTxBufferSize",
"Default TCP maximum transmit buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&Tcp::m_defaultTxBuffer),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultRxBufferSize",
"Default TCP maximum receive buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&Tcp::m_defaultRxBuffer),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultInitialCongestionWindowSize",
"Default TCP initial congestion window size (segments)",
UintegerValue (1),
MakeUintegerAccessor (&Tcp::m_defaultInitialCwnd),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultConnTimeout",
"Default TCP retransmission timeout when opening connection (seconds)",
UintegerValue (3),
MakeUintegerAccessor (&Tcp::m_defaultConnTimeout),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultConnCount",
"Default number of connection attempts (SYN retransmissions) before returning failure",
UintegerValue (6),
MakeUintegerAccessor (&Tcp::m_defaultConnCount),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("DefaultDelAckTimeout",
"Default timeout value for TCP delayed acks, in seconds",
DoubleValue (0.2),
MakeDoubleAccessor (&Tcp::m_defaultDelAckTimeout),
MakeDoubleChecker<double> ())
.AddAttribute ("DefaultDelAckCount",
"Default number of packets to wait before sending a TCP ack",
UintegerValue (2),
MakeUintegerAccessor (&Tcp::m_defaultDelAckCount),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
uint32_t
Tcp::GetDefaultSegSize (void) const
{
return m_defaultSegSize;
}
uint32_t
Tcp::GetDefaultAdvWin (void) const
{
return m_defaultAdvWin;
}
uint32_t
Tcp::GetDefaultSsThresh (void) const
{
return m_defaultSsThresh;
}
uint32_t
Tcp::GetDefaultTxBuffer (void) const
{
return m_defaultTxBuffer;
}
uint32_t
Tcp::GetDefaultRxBuffer (void) const
{
return m_defaultRxBuffer;
}
uint32_t
Tcp::GetDefaultInitialCwnd (void) const
{
return m_defaultInitialCwnd;
}
uint32_t
Tcp::GetDefaultConnTimeout (void) const
{
return m_defaultConnTimeout;
}
uint32_t
Tcp::GetDefaultConnCount (void) const
{
return m_defaultConnCount;
}
double
Tcp::GetDefaultDelAckTimeout (void) const
{
return m_defaultDelAckTimeout;
}
uint32_t
Tcp::GetDefaultDelAckCount (void) const
{
return m_defaultDelAckCount;
}
} // namespace ns3

View File

@@ -17,20 +17,19 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "udp.h"
#include "udp-socket-factory.h"
#include "ns3/uinteger.h"
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (Udp);
NS_OBJECT_ENSURE_REGISTERED (UdpSocketFactory);
TypeId Udp::GetTypeId (void)
TypeId UdpSocketFactory::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Udp")
.SetParent<SocketFactory> ();
static TypeId tid = TypeId ("ns3::UdpSocketFactory")
.SetParent<SocketFactory> ()
;
return tid;
}
Udp::Udp ()
{}
} // namespace ns3

View File

@@ -17,8 +17,8 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef UDP_H
#define UDP_H
#ifndef UDP_SOCKET_FACTORY_H
#define UDP_SOCKET_FACTORY_H
#include "socket-factory.h"
@@ -29,23 +29,17 @@ class Socket;
/**
* \brief API to create UDP socket instances
*
* This abstract class defines the API for UDP sockets.
* This class also can hold the global default variables used to
* initialize newly created sockets, such as values that are
* set through the sysctl or proc interfaces in Linux.
* This abstract class defines the API for UDP socket factory.
* All UDP implementations must provide an implementation of CreateSocket
* below.
*
* \see UdpImpl
* \see UdpSocketFactoryImpl
*/
class Udp : public SocketFactory
class UdpSocketFactory : public SocketFactory
{
public:
static TypeId GetTypeId (void);
Udp ();
/**
* \return smart pointer to Socket
*
@@ -53,8 +47,9 @@ public:
* implementations..
*/
virtual Ptr<Socket> CreateSocket (void) = 0;
};
} // namespace ns3
#endif /* UDP_H */
#endif /* UDP_SOCKET_FACTORY_H */

70
src/node/udp-socket.cc Normal file
View File

@@ -0,0 +1,70 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ns3/object.h"
#include "ns3/log.h"
#include "ns3/uinteger.h"
#include "ns3/trace-source-accessor.h"
#include "udp-socket.h"
NS_LOG_COMPONENT_DEFINE ("UdpSocket");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (UdpSocket);
TypeId
UdpSocket::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::UdpSocket")
.SetParent<Socket> ()
.AddAttribute ("RcvBufSize",
"UdpSocket maximum receive buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&UdpSocket::GetRcvBufSize,
&UdpSocket::SetRcvBufSize),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("IpTtl",
"socket-specific TTL for unicast IP packets (if non-zero)",
UintegerValue (0),
MakeUintegerAccessor (&UdpSocket::GetIpTtl,
&UdpSocket::SetIpTtl),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("IpMulticastTtl",
"socket-specific TTL for multicast IP packets (if non-zero)",
UintegerValue (0),
MakeUintegerAccessor (&UdpSocket::GetIpMulticastTtl,
&UdpSocket::SetIpMulticastTtl),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
UdpSocket::UdpSocket ()
{
NS_LOG_FUNCTION_NOARGS ();
}
UdpSocket::~UdpSocket ()
{
NS_LOG_FUNCTION_NOARGS ();
}
}; // namespace ns3

79
src/node/udp-socket.h Normal file
View File

@@ -0,0 +1,79 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2006 Georgia Tech Research Corporation
* 2007 INRIA
*
* 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
*
* Authors: George F. Riley<riley@ece.gatech.edu>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef __UDP_SOCKET_H__
#define __UDP_SOCKET_H__
#include "socket.h"
#include "ns3/traced-callback.h"
#include "ns3/callback.h"
#include "ns3/ptr.h"
#include "ns3/object.h"
namespace ns3 {
class Node;
class Packet;
/**
* \brief (abstract) base class of all UdpSockets
*
* This class exists solely for hosting UdpSocket attributes that can
* be reused across different implementations.
*/
class UdpSocket : public Socket
{
public:
static TypeId GetTypeId (void);
UdpSocket (void);
virtual ~UdpSocket (void);
virtual enum Socket::SocketErrno GetErrno (void) const = 0;
virtual Ptr<Node> GetNode (void) const = 0;
virtual int Bind () = 0;
virtual int Close (void) = 0;
virtual int ShutdownSend (void) = 0;
virtual int ShutdownRecv (void) = 0;
virtual int Connect (const Address &address) = 0;
virtual int Send (Ptr<Packet> p) = 0;
virtual uint32_t GetTxAvailable (void) const = 0;
virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
virtual uint32_t GetRxAvailable (void) const = 0;
private:
// Indirect the attribute setting and getting through private virtual methods
virtual void SetRcvBufSize (uint32_t size) = 0;
virtual uint32_t GetRcvBufSize (void) const = 0;
virtual void SetIpTtl (uint32_t ipTtl) = 0;
virtual uint32_t GetIpTtl (void) const = 0;
virtual void SetIpMulticastTtl (uint32_t ipTtl) = 0;
virtual uint32_t GetIpMulticastTtl (void) const = 0;
};
} //namespace ns3
#endif /* UDP_SOCKET_H */

View File

@@ -25,8 +25,10 @@ def build(bld):
'socket-factory.cc',
'packet-socket-factory.cc',
'packet-socket.cc',
'udp.cc',
'tcp.cc',
'udp-socket.cc',
'udp-socket-factory.cc',
'tcp-socket.cc',
'tcp-socket-factory.cc',
'ipv4.cc',
'application.cc',
'simple-channel.cc',
@@ -57,8 +59,10 @@ def build(bld):
'socket.h',
'socket-factory.h',
'packet-socket-factory.h',
'udp.h',
'tcp.h',
'udp-socket.h',
'udp-socket-factory.h',
'tcp-socket.h',
'tcp-socket-factory.h',
'ipv4.h',
'application.h',
'simple-channel.h',

View File

@@ -31,7 +31,7 @@
#include "olsr-agent-impl.h"
#include "ns3/socket-factory.h"
#include "ns3/udp.h"
#include "ns3/udp-socket-factory.h"
#include "ns3/simulator.h"
#include "ns3/log.h"
#include "ns3/random-variable.h"
@@ -258,9 +258,7 @@ void AgentImpl::Start ()
// Add OLSR as routing protocol, with slightly higher priority than
// static routing.
m_ipv4->AddRoutingProtocol (m_routingTable, 10);
Ptr<SocketFactory> socketFactory = GetObject<SocketFactory> (Udp::GetTypeId ());
Ipv4Address loopback ("127.0.0.1");
for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
{
@@ -281,7 +279,8 @@ void AgentImpl::Start ()
}
// Create a socket to listen only on this interface
Ptr<Socket> socket = socketFactory->CreateSocket ();
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId());
socket->SetRecvCallback (MakeCallback (&AgentImpl::RecvOlsr, this));
if (socket->Bind (InetSocketAddress (addr, OLSR_PORT_NUMBER)))
{
@@ -307,10 +306,17 @@ void AgentImpl::SetMainInterface (uint32_t interface)
//
// \brief Processes an incoming %OLSR packet following RFC 3626 specification.
void
AgentImpl::RecvOlsr (Ptr<Socket> socket,
Ptr<Packet> receivedPacket,
const Address &sourceAddress)
AgentImpl::RecvOlsr (Ptr<Socket> socket)
{
Ptr<Packet> receivedPacket;
receivedPacket = socket->Recv ();
SocketRxAddressTag tag;
bool found;
found = receivedPacket->FindFirstMatchingTag (tag);
NS_ASSERT (found);
Address sourceAddress = tag.GetAddress ();
InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
Ipv4Address receiverIfaceAddr = m_socketAddresses[socket];

View File

@@ -98,9 +98,7 @@ protected:
/// Increments message sequence number and returns the new value.
inline uint16_t GetMessageSequenceNumber ();
void RecvOlsr (Ptr<Socket> socket,
Ptr<Packet> receivedPacket,
const Address &sourceAddress);
void RecvOlsr (Ptr<Socket> socket);
void MprComputation ();
void RoutingTableComputation ();

View File

@@ -236,8 +236,8 @@ int main (int argc, char *argv[])
NodeContainer c; c.Create (1);
StaticInformation info;
info.RecordAggregationInfo ("ns3::Node", "ns3::Tcp");
info.RecordAggregationInfo ("ns3::Node", "ns3::Udp");
info.RecordAggregationInfo ("ns3::Node", "ns3::TcpSocketFactory");
info.RecordAggregationInfo ("ns3::Node", "ns3::UdpSocketFactory");
info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory");
info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::Agent");
info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel");