applications: Combine RemoteAddress and RemotePort attributes to a single one in UdpClient

Proposed by Sharan Naribole
This commit is contained in:
Sébastien Deronne
2024-04-18 17:27:34 +02:00
parent e8310b680c
commit 4357df33ca
4 changed files with 140 additions and 77 deletions

View File

@@ -8,6 +8,7 @@
#include "udp-client-server-helper.h"
#include <ns3/address-utils.h>
#include <ns3/string.h>
#include <ns3/uinteger.h>
@@ -33,13 +34,12 @@ UdpClientHelper::UdpClientHelper()
UdpClientHelper::UdpClientHelper(const Address& address)
: UdpClientHelper()
{
SetAttribute("RemoteAddress", AddressValue(address));
SetAttribute("Remote", AddressValue(address));
}
UdpClientHelper::UdpClientHelper(const Address& address, uint16_t port)
: UdpClientHelper(address)
: UdpClientHelper(addressUtils::ConvertToSocketAddress(address, port))
{
SetAttribute("RemotePort", UintegerValue(port));
}
UdpTraceClientHelper::UdpTraceClientHelper()

View File

@@ -6,13 +6,12 @@
* Author: Amine Ismail <amine.ismail@sophia.inria.fr>
* <amine.ismail@udcast.com>
*/
#include "udp-client.h"
#include "seq-ts-header.h"
#include "ns3/inet-socket-address.h"
#include "ns3/inet6-socket-address.h"
#include "ns3/ipv4-address.h"
#include "ns3/address-utils.h"
#include "ns3/log.h"
#include "ns3/nstime.h"
#include "ns3/packet.h"
@@ -53,13 +52,30 @@ UdpClient::GetTypeId()
.AddAttribute("RemoteAddress",
"The destination Address of the outbound packets",
AddressValue(),
MakeAddressAccessor(&UdpClient::m_peerAddress),
MakeAddressChecker())
MakeAddressAccessor(
(void(UdpClient::*)(const Address&)) &
UdpClient::SetRemote, // this is needed to indicate which version
// of the function overload to use
&UdpClient::GetRemote),
MakeAddressChecker(),
TypeId::DEPRECATED,
"Replaced by Remote in ns-3.44.")
.AddAttribute("RemotePort",
"The destination port of the outbound packets",
UintegerValue(100),
MakeUintegerAccessor(&UdpClient::m_peerPort),
MakeUintegerChecker<uint16_t>())
UintegerValue(UdpClient::DEFAULT_PORT),
MakeUintegerAccessor(&UdpClient::SetPort, &UdpClient::GetPort),
MakeUintegerChecker<uint16_t>(),
TypeId::DEPRECATED,
"Replaced by Remote in ns-3.44.")
.AddAttribute("Remote",
"The address of the destination",
AddressValue(),
MakeAddressAccessor(
(void(UdpClient::*)(const Address&)) &
UdpClient::SetRemote, // this is needed to indicate which version
// of the function overload to use
&UdpClient::GetRemote),
MakeAddressChecker())
.AddAttribute("Tos",
"The Type of Service used to send IPv4 packets. "
"All 8 bits of the TOS byte are set (including ECN bits).",
@@ -84,12 +100,14 @@ UdpClient::GetTypeId()
}
UdpClient::UdpClient()
: m_sent{0},
m_totalTx{0},
m_socket{nullptr},
m_peer{},
m_peerPort{},
m_sendEvent{}
{
NS_LOG_FUNCTION(this);
m_sent = 0;
m_totalTx = 0;
m_socket = nullptr;
m_sendEvent = EventId();
}
UdpClient::~UdpClient()
@@ -98,18 +116,65 @@ UdpClient::~UdpClient()
}
void
UdpClient::SetRemote(Address ip, uint16_t port)
UdpClient::SetRemote(const Address& ip, uint16_t port)
{
NS_LOG_FUNCTION(this << ip << port);
m_peerAddress = ip;
m_peerPort = port;
SetRemote(ip);
SetPort(port);
}
void
UdpClient::SetRemote(Address addr)
UdpClient::SetRemote(const Address& addr)
{
NS_LOG_FUNCTION(this << addr);
m_peerAddress = addr;
if (!addr.IsInvalid())
{
m_peer = addr;
if (m_peerPort)
{
SetPort(*m_peerPort);
}
}
}
Address
UdpClient::GetRemote() const
{
return m_peer;
}
void
UdpClient::SetPort(uint16_t port)
{
NS_LOG_FUNCTION(this << port);
if (m_peer.IsInvalid())
{
// save for later
m_peerPort = port;
return;
}
if (Ipv4Address::IsMatchingType(m_peer) || Ipv6Address::IsMatchingType(m_peer))
{
m_peer = addressUtils::ConvertToSocketAddress(m_peer, port);
}
}
uint16_t
UdpClient::GetPort() const
{
if (m_peer.IsInvalid())
{
return m_peerPort.value_or(UdpClient::DEFAULT_PORT);
}
if (InetSocketAddress::IsMatchingType(m_peer))
{
return InetSocketAddress::ConvertFrom(m_peer).GetPort();
}
else if (Inet6SocketAddress::IsMatchingType(m_peer))
{
return Inet6SocketAddress::ConvertFrom(m_peer).GetPort();
}
return UdpClient::DEFAULT_PORT;
}
void
@@ -119,73 +184,46 @@ UdpClient::StartApplication()
if (!m_socket)
{
TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
auto tid = TypeId::LookupByName("ns3::UdpSocketFactory");
m_socket = Socket::CreateSocket(GetNode(), tid);
if (Ipv4Address::IsMatchingType(m_peerAddress))
NS_ABORT_MSG_IF(m_peer.IsInvalid(), "Remote address not properly set");
if (InetSocketAddress::IsMatchingType(m_peer))
{
if (m_socket->Bind() == -1)
{
NS_FATAL_ERROR("Failed to bind socket");
}
m_socket->SetIpTos(m_tos); // Affects only IPv4 sockets.
m_socket->Connect(
InetSocketAddress(Ipv4Address::ConvertFrom(m_peerAddress), m_peerPort));
}
else if (Ipv6Address::IsMatchingType(m_peerAddress))
else if (Inet6SocketAddress::IsMatchingType(m_peer))
{
if (m_socket->Bind6() == -1)
{
NS_FATAL_ERROR("Failed to bind socket");
}
m_socket->Connect(
Inet6SocketAddress(Ipv6Address::ConvertFrom(m_peerAddress), m_peerPort));
}
else if (InetSocketAddress::IsMatchingType(m_peerAddress))
{
if (m_socket->Bind() == -1)
{
NS_FATAL_ERROR("Failed to bind socket");
}
m_socket->SetIpTos(m_tos); // Affects only IPv4 sockets.
m_socket->Connect(m_peerAddress);
}
else if (Inet6SocketAddress::IsMatchingType(m_peerAddress))
{
if (m_socket->Bind6() == -1)
{
NS_FATAL_ERROR("Failed to bind socket");
}
m_socket->Connect(m_peerAddress);
}
else
{
NS_ASSERT_MSG(false, "Incompatible address type: " << m_peerAddress);
NS_ASSERT_MSG(false, "Incompatible address type: " << m_peer);
}
m_socket->SetIpTos(m_tos); // Affects only IPv4 sockets.
m_socket->Connect(m_peer);
m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>>());
m_socket->SetAllowBroadcast(true);
}
#ifdef NS3_LOG_ENABLE
std::stringstream peerAddressStringStream;
if (Ipv4Address::IsMatchingType(m_peerAddress))
if (InetSocketAddress::IsMatchingType(m_peer))
{
peerAddressStringStream << Ipv4Address::ConvertFrom(m_peerAddress);
peerAddressStringStream << InetSocketAddress::ConvertFrom(m_peer).GetIpv4();
}
else if (Ipv6Address::IsMatchingType(m_peerAddress))
else if (Inet6SocketAddress::IsMatchingType(m_peer))
{
peerAddressStringStream << Ipv6Address::ConvertFrom(m_peerAddress);
peerAddressStringStream << Inet6SocketAddress::ConvertFrom(m_peer).GetIpv6();
}
else if (InetSocketAddress::IsMatchingType(m_peerAddress))
{
peerAddressStringStream << InetSocketAddress::ConvertFrom(m_peerAddress).GetIpv4();
}
else if (Inet6SocketAddress::IsMatchingType(m_peerAddress))
{
peerAddressStringStream << Inet6SocketAddress::ConvertFrom(m_peerAddress).GetIpv6();
}
m_peerAddressString = peerAddressStringStream.str();
m_peerString = peerAddressStringStream.str();
#endif // NS3_LOG_ENABLE
m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>>());
m_socket->SetAllowBroadcast(true);
m_sendEvent = Simulator::Schedule(Seconds(0.0), &UdpClient::Send, this);
}
@@ -209,7 +247,7 @@ UdpClient::Send()
SeqTsHeader seqTs;
seqTs.SetSeq(m_sent);
NS_ABORT_IF(m_size < seqTs.GetSerializedSize());
Ptr<Packet> p = Create<Packet>(m_size - seqTs.GetSerializedSize());
auto p = Create<Packet>(m_size - seqTs.GetSerializedSize());
// Trace before adding header, for consistency with PacketSink
m_txTrace(p);
@@ -222,14 +260,14 @@ UdpClient::Send()
++m_sent;
m_totalTx += p->GetSize();
#ifdef NS3_LOG_ENABLE
NS_LOG_INFO("TraceDelay TX " << m_size << " bytes to " << m_peerAddressString << " Uid: "
NS_LOG_INFO("TraceDelay TX " << m_size << " bytes to " << m_peerString << " Uid: "
<< p->GetUid() << " Time: " << (Simulator::Now()).As(Time::S));
#endif // NS3_LOG_ENABLE
}
#ifdef NS3_LOG_ENABLE
else
{
NS_LOG_INFO("Error while sending " << m_size << " bytes to " << m_peerAddressString);
NS_LOG_INFO("Error while sending " << m_size << " bytes to " << m_peerString);
}
#endif // NS3_LOG_ENABLE

View File

@@ -12,11 +12,14 @@
#define UDP_CLIENT_H
#include "ns3/application.h"
#include "ns3/deprecated.h"
#include "ns3/event-id.h"
#include "ns3/ipv4-address.h"
#include "ns3/ptr.h"
#include <ns3/traced-callback.h>
#include <optional>
namespace ns3
{
@@ -40,20 +43,23 @@ class UdpClient : public Application
static TypeId GetTypeId();
UdpClient();
~UdpClient() override;
static constexpr uint16_t DEFAULT_PORT{100}; //!< default port
/**
* \brief set the remote address and port
* \param ip remote IP address
* \param port remote port
*/
void SetRemote(Address ip, uint16_t port);
NS_DEPRECATED_3_44("Use SetRemote without port parameter instead")
void SetRemote(const Address& ip, uint16_t port);
/**
* \brief set the remote address
* \param addr remote address
*/
void SetRemote(Address addr);
void SetRemote(const Address& addr);
/**
* \return the total bytes sent by this app
@@ -69,6 +75,24 @@ class UdpClient : public Application
*/
void Send();
/**
* \brief Set the remote port (temporary function until deprecated attributes are removed)
* \param port remote port
*/
void SetPort(uint16_t port);
/**
* \brief Get the remote port (temporary function until deprecated attributes are removed)
* \return the remote port
*/
uint16_t GetPort() const;
/**
* \brief Get the remote address (temporary function until deprecated attributes are removed)
* \return the remote address
*/
Address GetRemote() const;
/// Traced Callback: transmitted packets.
TracedCallback<Ptr<const Packet>> m_txTrace;
@@ -79,17 +103,17 @@ class UdpClient : public Application
Time m_interval; //!< Packet inter-send time
uint32_t m_size; //!< Size of the sent packet (including the SeqTsHeader)
uint32_t m_sent; //!< Counter for sent packets
uint64_t m_totalTx; //!< Total bytes sent
Ptr<Socket> m_socket; //!< Socket
Address m_peerAddress; //!< Remote peer address
uint16_t m_peerPort; //!< Remote peer port
uint8_t m_tos; //!< The packets Type of Service
EventId m_sendEvent; //!< Event to send the next packet
uint32_t m_sent; //!< Counter for sent packets
uint64_t m_totalTx; //!< Total bytes sent
Ptr<Socket> m_socket; //!< Socket
Address m_peer; //!< Peer address
std::optional<uint16_t> m_peerPort; //!< Remote peer port (deprecated) // NS_DEPRECATED_3_44
uint8_t m_tos; //!< The packets Type of Service
EventId m_sendEvent; //!< Event to send the next packet
#ifdef NS3_LOG_ENABLE
std::string m_peerAddressString; //!< Remote peer address string
#endif // NS3_LOG_ENABLE
std::string m_peerString; //!< Remote peer address string
#endif // NS3_LOG_ENABLE
};
} // namespace ns3

View File

@@ -94,7 +94,8 @@ UdpClientServerTestCase::DoRun()
uint32_t MaxPacketSize = 1024;
Time interPacketInterval = Seconds(1.);
uint32_t maxPacketCount = 10;
UdpClientHelper clientHelper(i.GetAddress(1), port);
// This voluntarily invokes the c'tor not doing conversion
UdpClientHelper clientHelper(InetSocketAddress(i.GetAddress(1), port));
clientHelper.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
clientHelper.SetAttribute("Interval", TimeValue(interPacketInterval));
clientHelper.SetAttribute("PacketSize", UintegerValue(MaxPacketSize));