merge with HEAD
This commit is contained in:
@@ -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}
|
||||
|
||||
BIN
doc/tutorial/figures/sockets-overview.dia
Normal file
BIN
doc/tutorial/figures/sockets-overview.dia
Normal file
Binary file not shown.
243
doc/tutorial/sockets.texi
Normal file
243
doc/tutorial/sockets.texi
Normal 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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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)));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
42
src/node/socket-defaults.cc
Normal file
42
src/node/socket-defaults.cc
Normal 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
|
||||
42
src/node/socket-defaults.h
Normal file
42
src/node/socket-defaults.h
Normal 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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
37
src/node/tcp-socket-factory.cc
Normal file
37
src/node/tcp-socket-factory.cc
Normal 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
|
||||
@@ -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
114
src/node/tcp-socket.cc
Normal 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
94
src/node/tcp-socket.h
Normal 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 */
|
||||
|
||||
|
||||
140
src/node/tcp.cc
140
src/node/tcp.cc
@@ -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
|
||||
@@ -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
|
||||
@@ -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
70
src/node/udp-socket.cc
Normal 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
79
src/node/udp-socket.h
Normal 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 */
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user