applications: Add attribute in UdpEchoServer to specify local address on which to bind to
This commit is contained in:
@@ -22,6 +22,12 @@ UdpEchoServerHelper::UdpEchoServerHelper(uint16_t port)
|
||||
SetAttribute("Port", UintegerValue(port));
|
||||
}
|
||||
|
||||
UdpEchoServerHelper::UdpEchoServerHelper(const Address& address)
|
||||
: ApplicationHelper(UdpEchoServer::GetTypeId())
|
||||
{
|
||||
SetAttribute("Local", AddressValue(address));
|
||||
}
|
||||
|
||||
UdpEchoClientHelper::UdpEchoClientHelper(const Address& address, uint16_t port)
|
||||
: UdpEchoClientHelper(addressUtils::ConvertToSocketAddress(address, port))
|
||||
{
|
||||
|
||||
@@ -31,6 +31,14 @@ class UdpEchoServerHelper : public ApplicationHelper
|
||||
* \param port The port the server will wait on for incoming packets
|
||||
*/
|
||||
UdpEchoServerHelper(uint16_t port);
|
||||
|
||||
/**
|
||||
* Create UdpEchoServerHelper which will make life easier for people trying
|
||||
* to set up simulations with echos.
|
||||
*
|
||||
* \param address The address the server will bind to
|
||||
*/
|
||||
UdpEchoServerHelper(const Address& address);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,6 +35,12 @@ UdpEchoServer::GetTypeId()
|
||||
.SetParent<Application>()
|
||||
.SetGroupName("Applications")
|
||||
.AddConstructor<UdpEchoServer>()
|
||||
.AddAttribute("Local",
|
||||
"The Address on which to Bind the rx socket. "
|
||||
"If it is not specified, it will listen to any address.",
|
||||
AddressValue(),
|
||||
MakeAddressAccessor(&UdpEchoServer::m_local),
|
||||
MakeAddressChecker())
|
||||
.AddAttribute("Port",
|
||||
"Port on which we listen for incoming packets.",
|
||||
UintegerValue(9),
|
||||
@@ -58,6 +64,8 @@ UdpEchoServer::GetTypeId()
|
||||
}
|
||||
|
||||
UdpEchoServer::UdpEchoServer()
|
||||
: m_socket{nullptr},
|
||||
m_socket6{nullptr}
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
}
|
||||
@@ -76,9 +84,13 @@ UdpEchoServer::StartApplication()
|
||||
|
||||
if (!m_socket)
|
||||
{
|
||||
TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
|
||||
auto tid = TypeId::LookupByName("ns3::UdpSocketFactory");
|
||||
m_socket = Socket::CreateSocket(GetNode(), tid);
|
||||
InetSocketAddress local = InetSocketAddress(Ipv4Address::GetAny(), m_port);
|
||||
auto local = m_local;
|
||||
if (local.IsInvalid())
|
||||
{
|
||||
local = InetSocketAddress(Ipv4Address::GetAny(), m_port);
|
||||
}
|
||||
if (m_socket->Bind(local) == -1)
|
||||
{
|
||||
NS_FATAL_ERROR("Failed to bind socket");
|
||||
@@ -96,35 +108,36 @@ UdpEchoServer::StartApplication()
|
||||
NS_FATAL_ERROR("Error: Failed to join multicast group");
|
||||
}
|
||||
}
|
||||
m_socket->SetIpTos(m_tos); // Affects only IPv4 sockets.
|
||||
m_socket->SetRecvCallback(MakeCallback(&UdpEchoServer::HandleRead, this));
|
||||
}
|
||||
|
||||
if (!m_socket6)
|
||||
if (m_local.IsInvalid() && !m_socket6)
|
||||
{
|
||||
TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
|
||||
// local address is not specified, so create another socket to also listen to all IPv6
|
||||
// addresses
|
||||
auto tid = TypeId::LookupByName("ns3::UdpSocketFactory");
|
||||
m_socket6 = Socket::CreateSocket(GetNode(), tid);
|
||||
Inet6SocketAddress local6 = Inet6SocketAddress(Ipv6Address::GetAny(), m_port);
|
||||
if (m_socket6->Bind(local6) == -1)
|
||||
auto local = Inet6SocketAddress(Ipv6Address::GetAny(), m_port);
|
||||
if (m_socket6->Bind(local) == -1)
|
||||
{
|
||||
NS_FATAL_ERROR("Failed to bind socket");
|
||||
}
|
||||
if (addressUtils::IsMulticast(local6))
|
||||
if (addressUtils::IsMulticast(local))
|
||||
{
|
||||
Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket>(m_socket6);
|
||||
if (udpSocket)
|
||||
{
|
||||
// equivalent to setsockopt (MCAST_JOIN_GROUP)
|
||||
udpSocket->MulticastJoinGroup(0, local6);
|
||||
udpSocket->MulticastJoinGroup(0, local);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_FATAL_ERROR("Error: Failed to join multicast group");
|
||||
}
|
||||
}
|
||||
m_socket6->SetRecvCallback(MakeCallback(&UdpEchoServer::HandleRead, this));
|
||||
}
|
||||
|
||||
m_socket->SetIpTos(m_tos); // Affects only IPv4 sockets.
|
||||
m_socket->SetRecvCallback(MakeCallback(&UdpEchoServer::HandleRead, this));
|
||||
m_socket6->SetRecvCallback(MakeCallback(&UdpEchoServer::HandleRead, this));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -149,11 +162,10 @@ UdpEchoServer::HandleRead(Ptr<Socket> socket)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << socket);
|
||||
|
||||
Ptr<Packet> packet;
|
||||
Address from;
|
||||
Address localAddress;
|
||||
while ((packet = socket->RecvFrom(from)))
|
||||
while (auto packet = socket->RecvFrom(from))
|
||||
{
|
||||
Address localAddress;
|
||||
socket->GetSockName(localAddress);
|
||||
m_rxTrace(packet);
|
||||
m_rxTraceWithAddresses(packet, from, localAddress);
|
||||
|
||||
@@ -54,11 +54,12 @@ class UdpEchoServer : public Application
|
||||
*/
|
||||
void HandleRead(Ptr<Socket> socket);
|
||||
|
||||
uint16_t m_port; //!< Port on which we listen for incoming packets.
|
||||
uint16_t
|
||||
m_port; //!< Port on which we listen for incoming packets if local address is not specified
|
||||
uint8_t m_tos; //!< The packets Type of Service
|
||||
Ptr<Socket> m_socket; //!< IPv4 Socket
|
||||
Ptr<Socket> m_socket6; //!< IPv6 Socket
|
||||
Address m_local; //!< local multicast address
|
||||
Ptr<Socket> m_socket; //!< Socket
|
||||
Ptr<Socket> m_socket6; //!< IPv6 Socket (used if only port is specified)
|
||||
Address m_local; //!< Local address to bind to (address and port)
|
||||
|
||||
/// Callbacks for tracing the packet Rx events
|
||||
TracedCallback<Ptr<const Packet>> m_rxTrace;
|
||||
|
||||
@@ -310,7 +310,7 @@ UdpEchoClientSetFillTestCase::DoRun()
|
||||
Ipv4InterfaceContainer interfaces = ipv4.Assign(d);
|
||||
|
||||
uint16_t port = 5000;
|
||||
UdpEchoServerHelper echoServer(port);
|
||||
UdpEchoServerHelper echoServer(InetSocketAddress(Ipv4Address::GetAny(), port));
|
||||
ApplicationContainer serverApps = echoServer.Install(nodes.Get(1));
|
||||
serverApps.Start(Seconds(1.0));
|
||||
serverApps.Stop(Seconds(10.0));
|
||||
|
||||
Reference in New Issue
Block a user