remove DatagramSocket, use Socket base class for UdpSocket subclass.
This commit is contained in:
15
SConstruct
15
SConstruct
@@ -200,7 +200,6 @@ node.add_sources ([
|
||||
'ipv4.cc',
|
||||
'ipv4-end-point.cc',
|
||||
'udp-end-point.cc',
|
||||
'datagram-socket.cc',
|
||||
'udp.cc',
|
||||
'capability.cc',
|
||||
'arp-header.cc',
|
||||
@@ -218,13 +217,13 @@ node.add_sources ([
|
||||
'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 @@ node.add_headers ([
|
||||
'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 @@ node.add_inst_headers ([
|
||||
'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')
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 @@ protected:
|
||||
};
|
||||
|
||||
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 @@ GenerateTraffic (DatagramSocket *socket, uint32_t size)
|
||||
}
|
||||
|
||||
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 @@ DatagramSocketPrinter (DatagramSocket *socket, uint32_t size, Ipv4Address from,
|
||||
}
|
||||
|
||||
static void
|
||||
PrintTraffic (DatagramSocket *socket)
|
||||
PrintTraffic (Socket *socket)
|
||||
{
|
||||
socket->SetDummyRxCallback (MakeCallback (&DatagramSocketPrinter));
|
||||
socket->RecvDummy (MakeCallback (&SocketPrinter));
|
||||
}
|
||||
|
||||
|
||||
@@ -200,10 +201,10 @@ int main (int argc, char *argv[])
|
||||
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");
|
||||
|
||||
|
||||
@@ -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 @@ SmallTests (void)
|
||||
}
|
||||
|
||||
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 @@ GenerateTraffic (DatagramSocket *socket, uint32_t size)
|
||||
}
|
||||
|
||||
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 @@ int main (int argc, char *argv[])
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 @@ void OnOffApplication::StartApplication() // Called at time specified by Star
|
||||
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::ScheduleStopEvent()
|
||||
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 @@ void OnOffApplication::SendPacket()
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace ns3 {
|
||||
|
||||
class Ipv4Address;
|
||||
class RandomVariable;
|
||||
class DatagramSocket;
|
||||
class Socket;
|
||||
class DataRate;
|
||||
|
||||
class OnOffApplication : public Application {
|
||||
@@ -69,7 +69,7 @@ public: // Static methods
|
||||
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 @@ private:
|
||||
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:
|
||||
};
|
||||
|
||||
|
||||
81
src/node/socket.cc
Normal file
81
src/node/socket.cc
Normal file
@@ -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
|
||||
@@ -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 IPAddr;
|
||||
class L4Protocol;
|
||||
class Process;
|
||||
class Node;
|
||||
|
||||
// \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);
|
||||
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 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));
|
||||
|
||||
/**
|
||||
* \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 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));
|
||||
|
||||
public:
|
||||
// Define the BSD Socket API, with some slight variations.
|
||||
|
||||
// \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.
|
||||
// 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));
|
||||
|
||||
// \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 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 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 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 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.
|
||||
*
|
||||
* 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
|
||||
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 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
|
||||
|
||||
// \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 */
|
||||
|
||||
|
||||
|
||||
@@ -28,11 +28,11 @@ UdpEndPoint::UdpEndPoint (Ipv4Address address, uint16_t port)
|
||||
{}
|
||||
|
||||
void
|
||||
UdpEndPoint::SetSocket (DatagramSocket *socket)
|
||||
UdpEndPoint::SetSocket (UdpSocket *socket)
|
||||
{
|
||||
m_socket = socket;
|
||||
}
|
||||
DatagramSocket *
|
||||
UdpSocket *
|
||||
UdpEndPoint::GetSocket (void) const
|
||||
{
|
||||
return m_socket;
|
||||
|
||||
@@ -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
|
||||
|
||||
251
src/node/udp-socket.cc
Normal file
251
src/node/udp-socket.cc
Normal file
@@ -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
|
||||
96
src/node/udp-socket.h
Normal file
96
src/node/udp-socket.h
Normal file
@@ -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 */
|
||||
@@ -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 @@ Udp::CreateTraceResolver (TraceContext const &context)
|
||||
return new EmptyTraceResolver (context);
|
||||
}
|
||||
|
||||
Socket *
|
||||
Udp::CreateSocket (void)
|
||||
{
|
||||
return new UdpSocket (m_node);
|
||||
}
|
||||
|
||||
UdpEndPoint *
|
||||
Udp::Allocate (void)
|
||||
{
|
||||
@@ -102,7 +108,7 @@ Udp::Receive(Packet& packet,
|
||||
{
|
||||
return;
|
||||
}
|
||||
DatagramSocket *socket = endPoint->GetSocket ();
|
||||
UdpSocket *socket = endPoint->GetSocket ();
|
||||
socket->ForwardUp (packet, source, udpHeader.GetSource ());
|
||||
NS_ASSERT (socket != 0);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace ns3 {
|
||||
class Node;
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
class Socket;
|
||||
|
||||
class Udp : public Ipv4L4Protocol {
|
||||
public:
|
||||
@@ -45,6 +46,8 @@ public:
|
||||
|
||||
virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
|
||||
|
||||
Socket *CreateSocket (void);
|
||||
|
||||
UdpEndPoint *Allocate (void);
|
||||
UdpEndPoint *Allocate (Ipv4Address address);
|
||||
UdpEndPoint *Allocate (uint16_t port);
|
||||
|
||||
Reference in New Issue
Block a user