remove DatagramSocket, use Socket base class for UdpSocket subclass.
--- a/SConstruct Mon Apr 30 10:37:57 2007 +0200
+++ b/SConstruct Mon Apr 30 16:23:10 2007 +0200
@@ -200,7 +200,6 @@
'ipv4.cc',
'ipv4-end-point.cc',
'udp-end-point.cc',
- 'datagram-socket.cc',
'udp.cc',
'capability.cc',
'arp-header.cc',
@@ -218,13 +217,13 @@
'channel.cc',
'node-list.cc',
'ascii-trace.cc',
+ 'socket.cc',
+ 'udp-socket.cc',
])
node.add_headers ([
'ipv4-header.h',
'udp-header.h',
'ipv4-checksum.h',
- 'udp.h',
- 'ipv4-l4-protocol.h',
'application.h',
'application-list.h',
'onoff-application.h',
@@ -233,16 +232,15 @@
'arp.h',
'ipv4-loopback-interface.h',
'l3-demux.h',
- 'ipv4-l4-demux.h',
'header-utils.h',
'protocol.h',
'queue.h',
'arp-ipv4-interface.h',
+ 'udp-socket.h',
])
node.add_inst_headers ([
'node.h',
'internet-node.h',
- 'datagram-socket.h',
'ipv4-address.h',
'net-device.h',
'ipv4-interface.h',
@@ -263,6 +261,13 @@
'application-list.h',
'onoff-application.h',
'ascii-trace.h',
+ 'socket.h',
+ 'udp.h',
+ 'ipv4-l4-protocol.h',
+ 'ipv4-l4-demux.h',
+ 'udp-end-point.h',
+ 'ipv4-end-point-demux.h',
+ 'ipv4-end-point.h',
])
p2p = build.Ns3Module ('p2p', 'src/devices/p2p')
--- a/examples/simple-p2p.cc Mon Apr 30 10:37:57 2007 +0200
+++ b/examples/simple-p2p.cc Mon Apr 30 16:23:10 2007 +0200
@@ -55,7 +55,8 @@
#include "ns3/mac-address.h"
#include "ns3/ipv4-address.h"
#include "ns3/ipv4.h"
-#include "ns3/datagram-socket.h"
+#include "ns3/udp.h"
+#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/drop-tail.h"
#include "ns3/node-list.h"
--- a/samples/main-p2p-net-device-if.cc Mon Apr 30 10:37:57 2007 +0200
+++ b/samples/main-p2p-net-device-if.cc Mon Apr 30 16:23:10 2007 +0200
@@ -27,8 +27,9 @@
#include "ns3/p2p-net-device.h"
#include "ns3/drop-tail.h"
#include "ns3/ipv4.h"
+#include "ns3/udp.h"
#include "ns3/trace-context.h"
-#include "ns3/datagram-socket.h"
+#include "ns3/socket.h"
#include "ns3/simulator.h"
#include "ns3/node-list.h"
#include "ns3/trace-root.h"
@@ -77,12 +78,12 @@
};
static void
-GenerateTraffic (DatagramSocket *socket, uint32_t size)
+GenerateTraffic (Socket *socket, uint32_t size)
{
std::cout << "Node: " << socket->GetNode()->GetId ()
<< " at=" << Simulator::Now ().GetSeconds () << "s,"
<< " tx bytes=" << size << std::endl;
- socket->SendDummy (size);
+ socket->Send (0, size);
if (size > 50)
{
Simulator::Schedule (Seconds (0.5), &GenerateTraffic, socket, size - 50);
@@ -90,7 +91,7 @@
}
static void
-DatagramSocketPrinter (DatagramSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
+SocketPrinter (Socket *socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort)
{
std::cout << "Node: " << socket->GetNode()->GetId ()
<< " at=" << Simulator::Now ().GetSeconds () << "s,"
@@ -98,9 +99,9 @@
}
static void
-PrintTraffic (DatagramSocket *socket)
+PrintTraffic (Socket *socket)
{
- socket->SetDummyRxCallback (MakeCallback (&DatagramSocketPrinter));
+ socket->RecvDummy (MakeCallback (&SocketPrinter));
}
@@ -200,10 +201,10 @@
ipb->SetDefaultRoute (Ipv4Address ("10.1.1.1"), 1);
- DatagramSocket *source = new DatagramSocket (&a);
- DatagramSocket *sink = new DatagramSocket(&b);
+ Socket *source = a.GetUdp ()->CreateSocket ();
+ Socket *sink = b.GetUdp ()->CreateSocket ();
sink->Bind (80);
- source->SetDefaultDestination (Ipv4Address ("10.1.1.2"), 80);
+ source->Connect (Ipv4Address ("10.1.1.2"), 80);
Logger logger("p2p-net-test.log");
--- a/samples/main-simple.cc Mon Apr 30 10:37:57 2007 +0200
+++ b/samples/main-simple.cc Mon Apr 30 16:23:10 2007 +0200
@@ -2,7 +2,8 @@
#include "ns3/internet-node.h"
#include "ns3/simulator.h"
-#include "ns3/datagram-socket.h"
+#include "ns3/udp.h"
+#include "ns3/socket.h"
#include "ns3/nstime.h"
using namespace ns3;
@@ -31,10 +32,10 @@
}
static void
-GenerateTraffic (DatagramSocket *socket, uint32_t size)
+GenerateTraffic (Socket *socket, uint32_t size)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl;
- socket->SendDummy (size);
+ socket->Send (0, size);
if (size > 0)
{
Simulator::Schedule (Seconds (0.5), &GenerateTraffic, socket, size - 50);
@@ -42,15 +43,15 @@
}
static void
-DatagramSocketPrinter (DatagramSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
+SocketPrinter (Socket *socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl;
}
static void
-PrintTraffic (DatagramSocket *socket)
+PrintTraffic (Socket *socket)
{
- socket->SetDummyRxCallback (MakeCallback (&DatagramSocketPrinter));
+ socket->RecvDummy (MakeCallback (&SocketPrinter));
}
int main (int argc, char *argv[])
@@ -58,12 +59,12 @@
SmallTests ();
InternetNode *a = new InternetNode ();
-
- DatagramSocket *sink = new DatagramSocket (a);
+
+ Socket *sink = a->GetUdp ()->CreateSocket ();
sink->Bind (80);
- DatagramSocket *source = new DatagramSocket (a);
- source->SetDefaultDestination (Ipv4Address::GetLoopback (), 80);
+ Socket *source = a->GetUdp ()->CreateSocket ();
+ source->Connect (Ipv4Address::GetLoopback (), 80);
GenerateTraffic (source, 500);
PrintTraffic (sink);
--- a/src/node/datagram-socket.cc Mon Apr 30 10:37:57 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "datagram-socket.h"
-#include "udp.h"
-#include "udp-end-point.h"
-#include "node.h"
-#include "ipv4-l4-demux.h"
-
-namespace ns3 {
-
-DatagramSocket::DatagramSocket (Node *node)
- : m_endPoint (0),
- m_node (node)
-{
- NS_ASSERT (GetUdp () != 0);
-}
-DatagramSocket::~DatagramSocket ()
-{
- delete m_endPoint;
-}
-
-int
-DatagramSocket::Bind (void)
-{
- m_endPoint = GetUdp ()->Allocate ();
- if (m_endPoint == 0)
- {
- return -1;
- }
- m_endPoint->SetSocket (this);
- return 0;
-}
-int
-DatagramSocket::Bind (Ipv4Address address)
-{
- m_endPoint = GetUdp ()->Allocate (address);
- if (m_endPoint == 0)
- {
- return -1;
- }
- m_endPoint->SetSocket (this);
- return 0;
-}
-int
-DatagramSocket::Bind (uint16_t port)
-{
- m_endPoint = GetUdp ()->Allocate (port);
- if (m_endPoint == 0)
- {
- return -1;
- }
- m_endPoint->SetSocket (this);
- return 0;
-}
-int
-DatagramSocket::Bind (Ipv4Address address, uint16_t port)
-{
- m_endPoint = GetUdp ()->Allocate (address, port);
- if (m_endPoint == 0)
- {
- return -1;
- }
- m_endPoint->SetSocket (this);
- return 0;
-}
-
-void
-DatagramSocket::SetDefaultDestination (Ipv4Address daddr, uint16_t dport)
-{
- m_defaultAddress = daddr;
- m_defaultPort = dport;
-}
-void
-DatagramSocket::SendDummy (uint32_t size)
-{
- SendDummyTo (size, m_defaultAddress, m_defaultPort);
-}
-void
-DatagramSocket::SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport)
-{
- if (m_endPoint == 0)
- {
- Bind ();
- if (m_endPoint == 0)
- {
- return;
- }
- }
- Packet p = Packet (size);
- GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr,
- m_endPoint->GetLocalPort (), dport);
-}
-
-void
-DatagramSocket::Send (uint8_t const*buffer, uint32_t size)
-{
- SendTo (buffer, size, m_defaultAddress, m_defaultPort);
-}
-void
-DatagramSocket::SendTo (uint8_t const*buffer, uint32_t size,
- Ipv4Address daddr, uint16_t dport)
-{
- if (m_endPoint == 0)
- {
- Bind ();
- if (m_endPoint == 0)
- {
- return;
- }
- }
- Packet p = Packet (buffer, size);
- GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr,
- m_endPoint->GetLocalPort (), dport);
-}
-void
-DatagramSocket::SetDummyRxCallback (Callback<void,DatagramSocket*,
- uint32_t,
- Ipv4Address,uint16_t> cb)
-{
- m_dummyRxCallback = cb;
-}
-void
-DatagramSocket::SetRxCallback (Callback<void,DatagramSocket*,
- uint8_t const*,uint32_t,
- Ipv4Address,uint16_t> cb)
-{
- m_rxCallback = cb;
-}
-
-void
-DatagramSocket::ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport)
-{
- if (!m_dummyRxCallback.IsNull ())
- {
- m_dummyRxCallback (this, p.GetSize (), saddr, sport);
- }
- if (!m_rxCallback.IsNull ())
- {
- m_rxCallback (this, p.PeekData (), p.GetSize (), saddr, sport);
- }
-}
-
-Udp *
-DatagramSocket::GetUdp (void) const
-{
- return m_node->GetUdp ();
-}
-
-Node *
-DatagramSocket::GetNode (void) const
-{
- return m_node;
-}
-
-}//namespace ns3
--- a/src/node/datagram-socket.h Mon Apr 30 10:37:57 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef UDP_SOCKET_H
-#define UDP_SOCKET_H
-
-#include <stdint.h>
-#include "ns3/callback.h"
-#include "ipv4-address.h"
-
-namespace ns3 {
-
-class UdpEndPoint;
-class Node;
-class Packet;
-class Udp;
-
-/**
- * Before any data is sent, the socket must be bound with
- * one of the Bind methods.
- * If none of these Bind methods are called prior to
- * one of the ::Send methods, the socket is implicitely
- * bound to a random port and to all interfaces.
- */
-class DatagramSocket
-{
-public:
- /**
- * Create an unbound udp socket.
- */
- DatagramSocket (Node *node);
- ~DatagramSocket ();
-
- /**
- * Allocate a free port number and
- * bind this socket to this port number on all
- * interfaces of this system.
- *
- * \returns 0 on success, -1 on failure.
- */
- int Bind (void);
- /**
- * Allocate a free port number and
- * bind this socket to this port number on the
- * specified interface.
- *
- * \param address address of interface to bind to.
- * \returns 0 on success, -1 on failure.
- */
- int Bind (Ipv4Address address);
-
- /**
- * Bind this socket to this port number
- * on all interfaces of this system.
- *
- * \param port port to bind to on all interfaces
- * \returns 0 on success, -1 on failure.
- */
- int Bind (uint16_t port);
-
- /**
- * Bind this socket to this port number
- * on the interface specified by address.
- *
- * \param address address of interface to bind to.
- * \param port port to bind to on specified interface
- * \returns 0 on success, -1 on failure.
- */
- int Bind (Ipv4Address address, uint16_t port);
-
-
- /**
- * \param daddr destination address
- * \param dport destination port
- *
- * Set the default destination address and port
- * number for all packets outgoing from this socket.
- */
- void SetDefaultDestination (Ipv4Address daddr, uint16_t dport);
-
- /**
- * \param size size of dummy data to send.
- *
- * Send dummy data to default destination
- */
- void SendDummy (uint32_t size);
- /**
- * \param size size of dummy data to send
- * \param daddr destination address of dummy data
- * \param dport destination port of dummy data
- *
- * Send dummy data to specified destination, ignore any default
- * destination specified with DatagramSocket::SetDefaultDestination
- */
- void SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport);
-
- /**
- * \param buffer data buffer to send
- * \param size size of data buffer to send
- */
- void Send (uint8_t const*buffer, uint32_t size);
- /**
- * \param buffer data buffer to send
- * \param size size of data buffer to send
- * \param daddr destination address
- * \param dport destination port
- *
- * Send data to specified destination, ignore any default
- * destination specified with DatagramSocket::SetDefaultDestination
- */
- void SendTo (uint8_t const*buffer, uint32_t size,
- Ipv4Address daddr, uint16_t dport);
-
- /**
- * \param cb callback to invoke
- *
- * When a packet is received by this socket, it invokes the "dummy callback" which
- * forwards to the application the number of bytes received and from who they
- * were received.
- */
- void SetDummyRxCallback (Callback<void,DatagramSocket*,uint32_t,Ipv4Address,uint16_t> cb);
- /**
- * \param cb callback to invoke
- *
- * When a packet is received by this socket, it invokes the "normal callback" which
- * forwards to the application the buffer of bytes received and from who they
- * were received. The application is responsible for copying that buffer if it wants
- * to keep track of it.
- */
- void SetRxCallback (Callback<void,DatagramSocket*,uint8_t const*,uint32_t,Ipv4Address,uint16_t> cb);
- /**
- * \returns pointer to node
- */
- Node* GetNode(void) const;
-
-private:
- friend class Udp;
- // invoked by Udp class
- void ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport);
- Udp *GetUdp (void) const;
-
- UdpEndPoint *m_endPoint;
- Node *m_node;
- Ipv4Address m_defaultAddress;
- uint16_t m_defaultPort;
- Callback<void,DatagramSocket*,uint32_t,Ipv4Address,uint16_t> m_dummyRxCallback;
- Callback<void,DatagramSocket*,uint8_t const*,uint32_t,Ipv4Address,uint16_t> m_rxCallback;
-};
-
-}//namespace ns3
-
-#endif /* UDP_SOCKET_H */
--- a/src/node/onoff-application.cc Mon Apr 30 10:37:57 2007 +0200
+++ b/src/node/onoff-application.cc Mon Apr 30 16:23:10 2007 +0200
@@ -29,8 +29,9 @@
#include "ns3/data-rate.h"
#include "onoff-application.h"
#include "ns3/random-variable.h"
-#include "datagram-socket.h"
+#include "socket.h"
#include "ns3/simulator.h"
+#include "udp.h"
using namespace std;
@@ -157,8 +158,8 @@
MakeCallback(&OnOffApplication::ConnectionFailed,
this));
#endif
- m_socket = new DatagramSocket (GetNode());
- m_socket->SetDefaultDestination(m_peerIP, m_peerPort);
+ m_socket = GetNode ()->GetUdp ()->CreateSocket ();
+ m_socket->Connect (m_peerIP, m_peerPort);
}
StopApplication(); // Insure no pending event
// If we are not yet connected, there is nothing to do here
@@ -238,7 +239,7 @@
void OnOffApplication::SendPacket()
{
m_sendScheduled = false;
- m_socket->SendDummy(m_pktSize);
+ m_socket->Send(0, m_pktSize);
#ifdef NOTYET
m_socket->Send(0, m_pktSize); // Send the packet
#endif
@@ -248,13 +249,13 @@
ScheduleNextTx();
}
-void OnOffApplication::ConnectionSucceeded(DatagramSocket*)
+void OnOffApplication::ConnectionSucceeded(Socket*)
{
m_connected = true;
ScheduleStartEvent();
}
-void OnOffApplication::ConnectionFailed(DatagramSocket*)
+void OnOffApplication::ConnectionFailed(Socket*)
{
cout << "OnOffApplication, Connection Failed" << endl;
}
--- a/src/node/onoff-application.h Mon Apr 30 10:37:57 2007 +0200
+++ b/src/node/onoff-application.h Mon Apr 30 16:23:10 2007 +0200
@@ -36,7 +36,7 @@
class Ipv4Address;
class RandomVariable;
-class DatagramSocket;
+class Socket;
class DataRate;
class OnOffApplication : public Application {
@@ -69,7 +69,7 @@
static void DefaultSize(uint32_t s) { g_defaultSize = s;}
public:
- DatagramSocket* m_socket; // Associated socket
+ Socket * m_socket; // Associated socket
Ipv4Address m_peerIP; // Peer IP address
uint16_t m_peerPort; // Peer port
bool m_connected; // True if connected
@@ -95,9 +95,9 @@
void ScheduleNextTx();
void ScheduleStartEvent();
void ScheduleStopEvent();
- void ConnectionSucceeded(DatagramSocket*);
- void ConnectionFailed(DatagramSocket*);
- void Ignore(DatagramSocket*);
+ void ConnectionSucceeded(Socket*);
+ void ConnectionFailed(Socket*);
+ void Ignore(Socket*);
protected:
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/socket.cc Mon Apr 30 16:23:10 2007 +0200
@@ -0,0 +1,81 @@
+#include "socket.h"
+
+namespace ns3 {
+
+Socket::~Socket ()
+{}
+
+void
+Socket::Close(Callback<void, Socket*> closeCompleted)
+{
+ DoClose (closeCompleted);
+}
+
+void
+Socket::Connect(const Ipv4Address & address,
+ uint16_t portNumber,
+ Callback<void, Socket*> connectionSucceeded,
+ Callback<void, Socket*> connectionFailed,
+ Callback<void, Socket*> halfClose)
+{
+ DoConnect (address, portNumber, connectionSucceeded, connectionFailed, halfClose);
+}
+int
+Socket::Accept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
+ Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
+ Callback<void, Socket*> closeRequested)
+{
+ return DoAccept (connectionRequest, newConnectionCreated, closeRequested);
+}
+int
+Socket::Send (const uint8_t* buffer,
+ uint32_t size,
+ Callback<void, Socket*, uint32_t> dataSent)
+{
+ return DoSend (buffer, size, dataSent);
+}
+int
+Socket::SendTo(const Ipv4Address &address,
+ uint16_t port,
+ const uint8_t *buffer,
+ uint32_t size,
+ Callback<void, Socket*, uint32_t> dataSent)
+{
+ return DoSendTo (address, port, buffer, size, dataSent);
+}
+void
+Socket::Recv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
+{
+ DoRecv (callback);
+}
+void
+Socket::RecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> callback)
+{
+ DoRecvDummy (callback);
+}
+
+
+bool
+Socket::RefuseAllConnections (Socket* socket, const Ipv4Address& address, uint16_t port)
+{
+ return false;
+}
+void
+Socket::DummyCallbackVoidSocket (Socket *socket)
+{}
+void
+Socket::DummyCallbackVoidSocketUi32 (Socket *socket, uint32_t)
+{}
+void
+Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Socket *socket, uint32_t, const Ipv4Address &, uint16_t)
+{}
+void
+Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Socket *socket, const uint8_t *, uint32_t,
+ const Ipv4Address &, uint16_t)
+{}
+void
+Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Socket *socket, const Ipv4Address &, uint16_t)
+{}
+
+
+}//namespace ns3
--- a/src/node/socket.h Mon Apr 30 10:37:57 2007 +0200
+++ b/src/node/socket.h Mon Apr 30 16:23:10 2007 +0200
@@ -18,187 +18,244 @@
// Author: George F. Riley<riley@ece.gatech.edu>
//
-// Define the Sockets API for ns3.
-// George F. Riley, Georgia Tech, Fall 2006
-
-// The Socket class defines an API based on the well-known
-// BSD sockets. However, in a simulation environment, it is difficult
-// to implement the semantics "blocking" calls, such as recv.
-// The ns3 API will always return immediately from the blocking calls,
-// with an upcall at a later time when the call would unblock.
-// All blocking calls have a parameters with callbacks
-// to the desired upcall. However, the design supports the upcall
-// even if the owner of the socket has not posted the corresponding
-// blocking call, which eases implementation slightly.
-//
-// The ns3 class "Process"is anticipated to be a common way to create
-// and manipulate sockets, so a set of member functions are provided
-// in class Process to give a syntactically easy way to access the
-// sockets with default upcall virtual functions for each of the
-// defined blocking calls. See the definition and implementation
-// Process in process.h for details.
-//
-// As designed, the Socket class is a virtual base class, which defines
-// the services that each layer 4 protocol must provide.
-
#ifndef __SOCKET_H__
#define __SOCKET_H__
#include "ns3/callback.h"
-#include "protocol.h"
+#include "ipv4-address.h"
+#include <stdint.h>
-namespace ns3{
+namespace ns3 {
+
+class Node;
-class IPAddr;
-class L4Protocol;
-class Process;
-
-// \brief Define the BSD Sockets API
+/**
+ * \brief Define a Socket API based on the BSD Socket API.
+ *
+ * Contrary to the original BSD socket API, this API is asynchronous:
+ * it does not contain blocking calls. This API also does not use
+ * the dreaded BSD sockaddr_t type. Other than that, it tries to stick
+ * to the BSD API to make it easier those who know the BSD API to use
+ * this API.
+ */
class Socket {
public:
- Socket(); // Constructor
- virtual ~Socket() {}
-private:
- // These static methods are default, do-nothing callbacks. They are
- // provided as default arguments to the various socket calls, so callers who
- // are not interested in a particular callback can ignore the
- // parameters. Since these are used as formal parameters to MakeCallbac,
- // each must have a unique name (they can't be disambiguated by argument
- // list). The naming convention is a single letter indicating the
- // return type (V = void for example) and a single letter for each
- // argument type (S = Socket for exampls).
- static void CBIgnoreVS(Socket*) {}
- static void CBIgnoreVSIP(Socket*, const IPAddr&, PortId_t) {}
- static void CBIgnoreVSU(Socket*, uint32_t) {}
- static void CBIgnoreVSCU(Socket*, char*, uint32_t) {}
- static bool CBIgnoreBSIP(Socket*, const IPAddr&, PortId_t){ return true;}
- static void CBIgnoreVSCUIP(Socket*, char*, uint32_t, const IPAddr&, PortId_t);
-
-public:
- // Define the BSD Socket API, with some slight variations.
+ virtual ~Socket();
+
+ enum SocketErrno {
+ ENOTERROR,
+ EISCONN,
+ ENOTCONN,
+ EMSGSIZE,
+ EAGAIN,
+ ESHUTDOWN,
+ EOPNOTSUPP,
+ SOCKET_ERRNO_LAST
+ };
+
+ /**
+ * \return the errno associated to the last call which failed in this
+ * socket. Each socket's errno is initialized to zero
+ * when the socket is created.
+ */
+ virtual enum Socket::SocketErrno GetErrno (void) const = 0;
+
+ /**
+ * \returns the node this socket is associated with.
+ */
+ virtual Node *GetNode (void) const = 0;
+
+ /**
+ * Allocate a free port number and
+ * bind this socket to this port number on all
+ * interfaces of this system.
+ *
+ * \returns 0 on success, -1 on failure.
+ */
+ virtual int Bind (void) = 0;
+
+ /**
+ * Allocate a free port number and
+ * bind this socket to this port number on the
+ * specified interface.
+ *
+ * \param address address of interface to bind to.
+ * \returns 0 on success, -1 on failure.
+ */
+ virtual int Bind (Ipv4Address address) = 0;
+
+ /**
+ * Bind this socket to this port number
+ * on all interfaces of this system.
+ *
+ * \param port port to bind to on all interfaces
+ * \returns 0 on success, -1 on failure.
+ */
+ virtual int Bind (uint16_t port) = 0;
+
+ /**
+ * Bind this socket to this port number
+ * on the interface specified by address.
+ *
+ * \param address address of interface to bind to.
+ * \param port port to bind to on specified interface
+ * \returns 0 on success, -1 on failure.
+ */
+ virtual int Bind (Ipv4Address address, uint16_t port) = 0;
- // \brief Bind the socket to a particular port number
- // \param Port number to bind. If zero is specified, an available
- // transient port is assigned.
- // \return Port number assigned, or -1 if port already in use.
-
- virtual PortId_t Bind(PortId_t = 0);
+ /**
+ * \brief Close a socket.
+ * \param closeCompleted Callback invoked when the close operation is
+ * completed.
+ *
+ * After the Close call, the socket is no longer valid, and cannot
+ * safely be used for subsequent operations.
+ */
+ void Close(Callback<void, Socket*> closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
- // \brief Close a socket.
- // After the Close call, the socket is no longer valid, and cannot
- // safely be used for subsequent operations.
- // \param Callback for close completed.
- virtual void Close(ns3::Callback<void, Socket*>
- = MakeCallback(&Socket::CBIgnoreVS));
+ /**
+ * \returns zero on success, -1 on failure.
+ *
+ * Do not allow any further Send calls. This method is typically
+ * implemented for Tcp sockets by a half close.
+ */
+ virtual int ShutdownSend (void) = 0;
+
+ /**
+ * \returns zero on success, -1 on failure.
+ *
+ * Do not allow any further Recv calls. This method is typically
+ * implemented for Tcp sockets by a half close.
+ */
+ virtual int ShutdownRecv (void) = 0;
- // \brief Initiate a connection to a remote host
- // \param IP Address of remote.
- // \param Port number of remote
- // \param Callback for connection succeeded
- // \param Callback for connection failed
- // \param Callback for connection close requested by peer
- virtual void Connect(const IPAddr&, // IPAddress of peer
- PortId_t, // Port number
- ns3::Callback<void, Socket*> = // COnnection succeeded callback,
- MakeCallback(&Socket::CBIgnoreVS),
- ns3::Callback<void, Socket*> = // Connection failed callback
- MakeCallback(&Socket::CBIgnoreVS),
- ns3::Callback<void, Socket*> = // CloseRequested callback
- MakeCallback(&Socket::CBIgnoreVS));
+ /**
+ * \brief Initiate a connection to a remote host
+ * \param address IP Address of remote.
+ * \param portNumber Port number of remote
+ * \param connectionSucceeded this callback is invoked when the connection request
+ * initiated by the user is successfully completed. The callback is passed
+ * back a pointer to the same socket object.
+ * \param connectionFailed this callback is invoked when the connection request
+ * initiated by the user is unsuccessfully completed. The callback is passed
+ * back a pointer to the same socket object.
+ * \param halfClose XXX When exactly is this callback invoked ? If it invoked when the
+ * other side closes the connection ? Or when I call Close ?
+ */
+ void Connect(const Ipv4Address & address,
+ uint16_t portNumber,
+ Callback<void, Socket*> connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
+ Callback<void, Socket*> connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
+ Callback<void, Socket*> halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
+
+ /**
+ * \brief Accept connection requests from remote hosts
+ * \param connectionRequest Callback for connection request from peer.
+ * This user callback is passed a pointer to this socket, the
+ * ip address and the port number of the connection originator.
+ * This callback must return true to accept the incoming connection,
+ * false otherwise. If the connection is accepted, the
+ * "newConnectionCreated" callback will be invoked later to give access
+ * to the user to the socket created to match this new connection. If the
+ * user does not explicitely specify this callback, all incoming
+ * connections will be refused.
+ * \param newConnectionCreated Callback for new connection: when a new
+ * is accepted, it is created and the corresponding socket is passed
+ * back to the user through this callback. This user callback is passed
+ * a pointer to the new socket, and the ip address and port number
+ * of the connection originator.
+ * \param closeRequested Callback for connection close request from peer.
+ * XXX: when is this callback invoked ?
+ */
+ int Accept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest =
+ MakeCallback(&Socket::RefuseAllConnections),
+ Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated =
+ MakeCallback (&Socket::DummyCallbackVoidSocketIpv4AddressUi16),
+ Callback<void, Socket*> closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
+
+ /**
+ * \brief Send data (or dummy data) to the remote host
+ * \param buffer Data to send (nil if dummy data).
+ * \param size Number of bytes to send.
+ * \param dataSent Data sent callback.
+ * \returns -1 in case of error or the number of bytes copied in the
+ * internal buffer and accepted for transmission.
+ */
+ int Send (const uint8_t* buffer,
+ uint32_t size,
+ Callback<void, Socket*, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
- // \brief Specify the number of pending connections to buffer
- // while not blocked on accept. We include this for completeness,
- // but with the callback approach to connection acceptance this
- // does nothing.
- virtual void Listen(uint32_t);
+ /**
+ * \brief Send data to a specified peer.
+ * \param address IP Address of remote host
+ * \param port port number
+ * \param buffer Data to send (nil if dummy data).
+ * \param size Number of bytes to send.
+ * \param dataSent Data sent callback.
+ * \returns -1 in case of error or the number of bytes copied in the
+ * internal buffer and accepted for transmission.
+ */
+ int SendTo(const Ipv4Address &address,
+ uint16_t port,
+ const uint8_t *buffer,
+ uint32_t size,
+ Callback<void, Socket*, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
- // \brief Accept connection requests from remote hosts
- // \param Callback for connection request from peer
- // \param Callback for new connection
- // \param Callback for connection close request from peer
- virtual void Accept(
- // Connection request callback
- ns3::Callback<bool, Socket*, const IPAddr&, PortId_t> =
- MakeCallback(&Socket::CBIgnoreBSIP),
- // New connection callback
- ns3::Callback<void, Socket*, const IPAddr&, PortId_t> =
- MakeCallback(&Socket::CBIgnoreVSIP),
- // CloseRequested callback
- ns3::Callback<void, Socket*> =
- MakeCallback(&Socket::CBIgnoreVS));
-
- // \brief Send data (or dummy data) to the remote host
- // \param Data to send (nil if dummy data).
- // NOTE. The data (if any) is copied by this call, so pointers
- // to local data is allowed and processed correctly.
- // \param Number of bytes to send.
- // \param Data sent callback. A suitable "ignore" callback
- // is used if not specified.
- virtual void Send(char*, // Data to send
- uint32_t, // Number of bytes
- ns3::Callback<void, Socket*, uint32_t> =
- MakeCallback(&CBIgnoreVSU)); // Sent cb
-
- // \brief Send data to a specified peer.
- // \param IP Address of remote host
- // \param port number
- // \param Data to send (nil if dummy data).
- // NOTE. The data (if any) is copied by this call, so pointers
- // to local data is allowed and processed correctly.
- // \param Number of bytes to send.
- // \param Data sent callback
- virtual void SendTo(const IPAddr&, // IP Address of remote peer
- PortId_t, // Port number of remote peer
- char*, // Data to send
- uint32_t, // Number of bytes
- ns3::Callback<void, Socket*, uint32_t> =
- MakeCallback(&Socket::CBIgnoreVSU)); // Sent cb
-
- // \brief Receive data
- // Note that due to the callback nature of the ns3 implementation,
- // there is no data pointer provided here. Rather, the callback
- // will specify where the data can be found, and the callback should
- // copy it to a local buffer if needed at that time.
- // \param Received data callback.
- virtual void Recv(ns3::Callback<void, Socket*, char*, uint32_t,
- const IPAddr&, PortId_t> =
- MakeCallback(&Socket::CBIgnoreVSCUIP));
+ /**
+ * \brief Receive data
+ * \param Received data callback. Invoked whenever new data is received.
+ *
+ * If you wish to transport only dummy packets, this method is not a very
+ * efficient way to receive these dummy packets: it will trigger a memory
+ * allocation to hold the dummy memory into a buffer which can be passed
+ * to the user. Instead, consider using the RecvDummy method.
+ */
+ void Recv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> =
+ MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16));
+
+ /**
+ * \brief Receive data
+ * \param Received data callback. Invoked whenever new data is received.
+ *
+ * This method is included because it is vastly more efficient than the
+ * Recv method when you use dummy payload.
+ */
+ void RecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> =
+ MakeCallback (&Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16));
private:
-// upcalls
-// The members below are all callbacks, created with MakeCallback,
- ns3::Callback<void, Socket*> m_cbCloseComplete; // Socket Closed upcall
- ns3::Callback<void, Socket*> m_cbCloseRequested; // Close req by peer
- ns3::Callback<void, Socket*> m_cbConnectionSucceeded;// Connection successful
- ns3::Callback<void, Socket*> m_cbConnectionFailed; // Connection failed
-
- // \brief For TCP sockets, the cbSent upcall call is made when the data packet
- // is sent, but not acknowledged. For UDP sockets, it is called
- // immediately.
- ns3::Callback<void, Socket*, uint32_t> m_cbSent; // Data delivered
+ virtual void DoClose(Callback<void, Socket*> closeCompleted) = 0;
+ virtual void DoConnect(const Ipv4Address & address,
+ uint16_t portNumber,
+ Callback<void, Socket*> connectionSucceeded,
+ Callback<void, Socket*> connectionFailed,
+ Callback<void, Socket*> halfClose) = 0;
+ virtual int DoAccept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
+ Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
+ Callback<void, Socket*> closeRequested) = 0;
+ virtual int DoSend (const uint8_t* buffer,
+ uint32_t size,
+ Callback<void, Socket*, uint32_t> dataSent) = 0;
+ virtual int DoSendTo(const Ipv4Address &address,
+ uint16_t port,
+ const uint8_t *buffer,
+ uint32_t size,
+ Callback<void, Socket*, uint32_t> dataSent) = 0;
+ virtual void DoRecv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0;
+ virtual void DoRecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t>) = 0;
- // \brief For the cbRecv callback, the char* to the data may be nil if
- // no actual data is present.
- ns3::Callback<void, Socket*, char*, uint32_t,
- const IPAddr&, PortId_t> m_cbRecv;
- // \brief The cbConnectionRequest callback is called when a socket has
- // called Listen, and indicates a remote peer has sent a connection
- // request. The callback can return false to indicate the connection
- // is to be rejected, for example in a peer-to-peer application that
- // wants to limit the number of connections at any one time.
- ns3::Callback<bool, Socket*, const IPAddr&, PortId_t> m_cbConnectionRequest;
-
- // \brief The cbNewConnection callback is called when a connection request
- // from a peer has been received and accepted by the process owning
- // this socket. Note the Socket* passed to the upcall is a new
- // socket. The original socket using accept is still accepting connections.
- ns3::Callback<void, Socket*, const IPAddr&, PortId_t> m_cbNewConnection;
-
+ static bool RefuseAllConnections (Socket* socket, const Ipv4Address& address, uint16_t port);
+ static void DummyCallbackVoidSocket (Socket *socket);
+ static void DummyCallbackVoidSocketUi32 (Socket *socket, uint32_t);
+ static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Socket *socket, uint32_t, const Ipv4Address &, uint16_t);
+ static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Socket *socket, const uint8_t *, uint32_t,
+ const Ipv4Address &, uint16_t);
+ static void DummyCallbackVoidSocketIpv4AddressUi16 (Socket *socket, const Ipv4Address &, uint16_t);
};
} //namespace ns3
-#endif
+#endif /* SOCKET_H */
--- a/src/node/udp-end-point.cc Mon Apr 30 10:37:57 2007 +0200
+++ b/src/node/udp-end-point.cc Mon Apr 30 16:23:10 2007 +0200
@@ -28,11 +28,11 @@
{}
void
-UdpEndPoint::SetSocket (DatagramSocket *socket)
+UdpEndPoint::SetSocket (UdpSocket *socket)
{
m_socket = socket;
}
-DatagramSocket *
+UdpSocket *
UdpEndPoint::GetSocket (void) const
{
return m_socket;
--- a/src/node/udp-end-point.h Mon Apr 30 10:37:57 2007 +0200
+++ b/src/node/udp-end-point.h Mon Apr 30 16:23:10 2007 +0200
@@ -27,17 +27,17 @@
namespace ns3 {
-class DatagramSocket;
+class UdpSocket;
class UdpEndPoint : public Ipv4EndPoint
{
public:
UdpEndPoint (Ipv4Address address, uint16_t port);
- void SetSocket (DatagramSocket *socket);
- DatagramSocket *GetSocket (void) const;
+ void SetSocket (UdpSocket *socket);
+ UdpSocket *GetSocket (void) const;
private:
- DatagramSocket *m_socket;
+ UdpSocket *m_socket;
};
}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/udp-socket.cc Mon Apr 30 16:23:10 2007 +0200
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "udp-socket.h"
+#include "udp.h"
+#include "udp-end-point.h"
+#include "node.h"
+#include "ipv4-l4-demux.h"
+
+namespace ns3 {
+
+UdpSocket::UdpSocket (Node *node)
+ : m_endPoint (0),
+ m_node (node),
+ m_errno (ENOTERROR),
+ m_shutdownSend (false),
+ m_shutdownRecv (false),
+ m_connected (false)
+{
+ NS_ASSERT (GetUdp () != 0);
+}
+UdpSocket::~UdpSocket ()
+{
+ delete m_endPoint;
+}
+
+Node *
+UdpSocket::GetNode (void) const
+{
+ return m_node;
+}
+
+int
+UdpSocket::Bind (void)
+{
+ m_endPoint = GetUdp ()->Allocate ();
+ if (m_endPoint == 0)
+ {
+ return -1;
+ }
+ m_endPoint->SetSocket (this);
+ return 0;
+}
+int
+UdpSocket::Bind (Ipv4Address address)
+{
+ m_endPoint = GetUdp ()->Allocate (address);
+ if (m_endPoint == 0)
+ {
+ return -1;
+ }
+ m_endPoint->SetSocket (this);
+ return 0;
+}
+int
+UdpSocket::Bind (uint16_t port)
+{
+ m_endPoint = GetUdp ()->Allocate (port);
+ if (m_endPoint == 0)
+ {
+ return -1;
+ }
+ m_endPoint->SetSocket (this);
+ return 0;
+}
+int
+UdpSocket::Bind (Ipv4Address address, uint16_t port)
+{
+ m_endPoint = GetUdp ()->Allocate (address, port);
+ if (m_endPoint == 0)
+ {
+ return -1;
+ }
+ m_endPoint->SetSocket (this);
+ return 0;
+}
+
+enum Socket::SocketErrno
+UdpSocket::GetErrno (void) const
+{
+ return m_errno;
+}
+int
+UdpSocket::ShutdownSend (void)
+{
+ m_shutdownSend = true;
+ return 0;
+}
+int
+UdpSocket::ShutdownRecv (void)
+{
+ m_shutdownRecv = false;
+ return 0;
+}
+
+void
+UdpSocket::DoClose(ns3::Callback<void, Socket*> closeCompleted)
+{
+ // XXX: we should set the close state and check it in all API methods.
+ if (!closeCompleted.IsNull ())
+ {
+ closeCompleted (this);
+ }
+}
+void
+UdpSocket::DoConnect(const Ipv4Address & address,
+ uint16_t portNumber,
+ ns3::Callback<void, Socket*> connectionSucceeded,
+ ns3::Callback<void, Socket*> connectionFailed,
+ ns3::Callback<void, Socket*> halfClose)
+{
+ m_defaultAddress = address;
+ m_defaultPort = portNumber;
+ if (!connectionSucceeded.IsNull ())
+ {
+ connectionSucceeded (this);
+ }
+ m_connected = true;
+}
+int
+UdpSocket::DoAccept(ns3::Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
+ ns3::Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
+ ns3::Callback<void, Socket*> closeRequested)
+{
+ // calling accept on a udp socket is a programming error.
+ m_errno = EOPNOTSUPP;
+ return -1;
+}
+int
+UdpSocket::DoSend (const uint8_t* buffer,
+ uint32_t size,
+ ns3::Callback<void, Socket*, uint32_t> dataSent)
+{
+ if (!m_connected)
+ {
+ m_errno = ENOTCONN;
+ return -1;
+ }
+ Packet p;
+ if (buffer == 0)
+ {
+ p = Packet (size);
+ }
+ else
+ {
+ p = Packet (buffer, size);
+ }
+ return DoSendPacketTo (p, m_defaultAddress, m_defaultPort, dataSent);
+}
+int
+UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
+ ns3::Callback<void, Socket*, uint32_t> dataSent)
+{
+ if (m_endPoint == 0)
+ {
+ if (Bind () == -1)
+ {
+ NS_ASSERT (m_endPoint == 0);
+ return -1;
+ }
+ NS_ASSERT (m_endPoint != 0);
+ }
+ if (m_shutdownSend)
+ {
+ m_errno = ESHUTDOWN;
+ return -1;
+ }
+ GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr,
+ m_endPoint->GetLocalPort (), dport);
+ if (!dataSent.IsNull ())
+ {
+ dataSent (this, p.GetSize ());
+ }
+ return 0;
+}
+int
+UdpSocket::DoSendTo(const Ipv4Address &address,
+ uint16_t port,
+ const uint8_t *buffer,
+ uint32_t size,
+ ns3::Callback<void, Socket*, uint32_t> dataSent)
+{
+ if (m_connected)
+ {
+ m_errno = EISCONN;
+ return -1;
+ }
+ Packet p;
+ if (buffer == 0)
+ {
+ p = Packet (size);
+ }
+ else
+ {
+ p = Packet (buffer, size);
+ }
+ return DoSendPacketTo (p, address, port, dataSent);
+}
+void
+UdpSocket::DoRecv(ns3::Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
+{
+ m_rxCallback = callback;
+}
+void
+UdpSocket::DoRecvDummy(ns3::Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> callback)
+{
+ m_dummyRxCallback = callback;
+}
+
+void
+UdpSocket::ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport)
+{
+ if (m_shutdownRecv)
+ {
+ return;
+ }
+ if (!m_dummyRxCallback.IsNull ())
+ {
+ m_dummyRxCallback (this, p.GetSize (), saddr, sport);
+ }
+ if (!m_rxCallback.IsNull ())
+ {
+ m_rxCallback (this, p.PeekData (), p.GetSize (), saddr, sport);
+ }
+}
+
+Udp *
+UdpSocket::GetUdp (void) const
+{
+ return m_node->GetUdp ();
+}
+
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/udp-socket.h Mon Apr 30 16:23:10 2007 +0200
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef UDP_SOCKET_H
+#define UDP_SOCKET_H
+
+#include <stdint.h>
+#include "ns3/callback.h"
+#include "socket.h"
+
+namespace ns3 {
+
+class UdpEndPoint;
+class Node;
+class Packet;
+class Udp;
+
+class UdpSocket : public Socket
+{
+public:
+ /**
+ * Create an unbound udp socket.
+ */
+ UdpSocket (Node *node);
+ virtual ~UdpSocket ();
+
+ virtual enum SocketErrno GetErrno (void) const;
+ virtual Node *GetNode (void) const;
+ virtual int Bind (void);
+ virtual int Bind (Ipv4Address address);
+ virtual int Bind (uint16_t port);
+ virtual int Bind (Ipv4Address address, uint16_t port);
+ virtual int ShutdownSend (void);
+ virtual int ShutdownRecv (void);
+
+private:
+ virtual void DoClose(ns3::Callback<void, Socket*> closeCompleted);
+ virtual void DoConnect(const Ipv4Address & address,
+ uint16_t portNumber,
+ ns3::Callback<void, Socket*> connectionSucceeded,
+ ns3::Callback<void, Socket*> connectionFailed,
+ ns3::Callback<void, Socket*> halfClose);
+ virtual int DoAccept(ns3::Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
+ ns3::Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
+ ns3::Callback<void, Socket*> closeRequested);
+ virtual int DoSend (const uint8_t* buffer,
+ uint32_t size,
+ ns3::Callback<void, Socket*, uint32_t> dataSent);
+ virtual int DoSendTo(const Ipv4Address &address,
+ uint16_t port,
+ const uint8_t *buffer,
+ uint32_t size,
+ ns3::Callback<void, Socket*, uint32_t> dataSent);
+ virtual void DoRecv(ns3::Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t>);
+ virtual void DoRecvDummy(ns3::Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t>);
+
+private:
+ friend class Udp;
+ // invoked by Udp class
+ void ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport);
+ Udp *GetUdp (void) const;
+ int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
+ ns3::Callback<void, Socket*, uint32_t> dataSent);
+
+ UdpEndPoint *m_endPoint;
+ Node *m_node;
+ Ipv4Address m_defaultAddress;
+ uint16_t m_defaultPort;
+ Callback<void,Socket*,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback;
+ Callback<void,Socket*,uint8_t const*,uint32_t,const Ipv4Address &,uint16_t> m_rxCallback;
+ enum SocketErrno m_errno;
+ bool m_shutdownSend;
+ bool m_shutdownRecv;
+ bool m_connected;
+};
+
+}//namespace ns3
+
+#endif /* UDP_SOCKET_H */
--- a/src/node/udp.cc Mon Apr 30 10:37:57 2007 +0200
+++ b/src/node/udp.cc Mon Apr 30 16:23:10 2007 +0200
@@ -27,10 +27,10 @@
#include "udp-header.h"
#include "ipv4-end-point-demux.h"
#include "udp-end-point.h"
-#include "datagram-socket.h"
#include "node.h"
#include "ipv4.h"
#include "l3-demux.h"
+#include "udp-socket.h"
namespace ns3 {
@@ -54,6 +54,12 @@
return new EmptyTraceResolver (context);
}
+Socket *
+Udp::CreateSocket (void)
+{
+ return new UdpSocket (m_node);
+}
+
UdpEndPoint *
Udp::Allocate (void)
{
@@ -102,7 +108,7 @@
{
return;
}
- DatagramSocket *socket = endPoint->GetSocket ();
+ UdpSocket *socket = endPoint->GetSocket ();
socket->ForwardUp (packet, source, udpHeader.GetSource ());
NS_ASSERT (socket != 0);
}
--- a/src/node/udp.h Mon Apr 30 10:37:57 2007 +0200
+++ b/src/node/udp.h Mon Apr 30 16:23:10 2007 +0200
@@ -35,6 +35,7 @@
class Node;
class TraceResolver;
class TraceContext;
+class Socket;
class Udp : public Ipv4L4Protocol {
public:
@@ -45,6 +46,8 @@
virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
+ Socket *CreateSocket (void);
+
UdpEndPoint *Allocate (void);
UdpEndPoint *Allocate (Ipv4Address address);
UdpEndPoint *Allocate (uint16_t port);