diff --git a/src/applications/helper/three-gpp-http-helper.cc b/src/applications/helper/three-gpp-http-helper.cc index 0a779430f..85b25f39e 100644 --- a/src/applications/helper/three-gpp-http-helper.cc +++ b/src/applications/helper/three-gpp-http-helper.cc @@ -30,7 +30,7 @@ ThreeGppHttpClientHelper::ThreeGppHttpClientHelper(const Address& address) ThreeGppHttpServerHelper::ThreeGppHttpServerHelper(const Address& address) : ApplicationHelper("ns3::ThreeGppHttpServer") { - m_factory.Set("LocalAddress", AddressValue(address)); + m_factory.Set("Local", AddressValue(address)); } } // namespace ns3 diff --git a/src/applications/model/three-gpp-http-server.cc b/src/applications/model/three-gpp-http-server.cc index d104ec622..a90693dcd 100644 --- a/src/applications/model/three-gpp-http-server.cc +++ b/src/applications/model/three-gpp-http-server.cc @@ -11,10 +11,9 @@ #include "three-gpp-http-variables.h" +#include #include #include -#include -#include #include #include #include @@ -34,14 +33,14 @@ namespace ns3 NS_OBJECT_ENSURE_REGISTERED(ThreeGppHttpServer); ThreeGppHttpServer::ThreeGppHttpServer() - : m_state(NOT_STARTED), - m_initialSocket(nullptr), - m_txBuffer(Create()), - m_httpVariables(CreateObject()) + : m_state{NOT_STARTED}, + m_initialSocket{nullptr}, + m_txBuffer{Create()}, + m_httpVariables{CreateObject()}, + m_port{}, + m_mtuSize{m_httpVariables->GetMtuSize()} { NS_LOG_FUNCTION(this); - - m_mtuSize = m_httpVariables->GetMtuSize(); NS_LOG_INFO(this << " MTU size for this server application is " << m_mtuSize << " bytes."); } @@ -63,12 +62,27 @@ ThreeGppHttpServer::GetTypeId() "The local address of the server, " "i.e., the address on which to bind the Rx socket.", AddressValue(), - MakeAddressAccessor(&ThreeGppHttpServer::m_localAddress), - MakeAddressChecker()) + MakeAddressAccessor(&ThreeGppHttpServer::SetLocal), + MakeAddressChecker(), + TypeId::DEPRECATED, + "Replaced by Local in ns-3.44.") .AddAttribute("LocalPort", "Port on which the application listen for incoming packets.", UintegerValue(80), // the default HTTP port - MakeUintegerAccessor(&ThreeGppHttpServer::m_localPort), + MakeUintegerAccessor(&ThreeGppHttpServer::SetPort), + MakeUintegerChecker(), + TypeId::DEPRECATED, + "Replaced by Port in ns-3.44.") + .AddAttribute("Local", + "The Address on which to Bind the rx socket. " + "If it is not specified, it will listen to any address.", + AddressValue(), + MakeAddressAccessor(&ThreeGppHttpServer::SetLocal), + MakeAddressChecker()) + .AddAttribute("Port", + "Port on which the application listens for incoming packets.", + UintegerValue(80), // the default HTTP port + MakeUintegerAccessor(&ThreeGppHttpServer::SetPort), MakeUintegerChecker()) .AddAttribute("Tos", "The Type of Service used to send packets. " @@ -118,6 +132,36 @@ ThreeGppHttpServer::GetTypeId() return tid; } +void +ThreeGppHttpServer::SetLocal(const Address& addr) +{ + NS_LOG_FUNCTION(this << addr); + if (!addr.IsInvalid()) + { + m_local = addr; + if (m_port) + { + SetPort(*m_port); + } + } +} + +void +ThreeGppHttpServer::SetPort(uint16_t port) +{ + NS_LOG_FUNCTION(this << port); + if (m_local.IsInvalid()) + { + // save for later + m_port = port; + return; + } + if (Ipv4Address::IsMatchingType(m_local) || Ipv6Address::IsMatchingType(m_local)) + { + m_local = addressUtils::ConvertToSocketAddress(m_local, port); + } +} + void ThreeGppHttpServer::SetMtuSize(uint32_t mtuSize) { @@ -200,52 +244,51 @@ ThreeGppHttpServer::StartApplication() m_initialSocket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId()); m_initialSocket->SetAttribute("SegmentSize", UintegerValue(m_mtuSize)); - NS_ABORT_MSG_IF(m_localAddress.IsInvalid(), - "'LocalAddress' attribute not properly set"); - - if (Ipv4Address::IsMatchingType(m_localAddress)) + NS_ABORT_MSG_IF(m_local.IsInvalid(), "Local address not properly set"); + if (InetSocketAddress::IsMatchingType(m_local)) { - const Ipv4Address ipv4 = Ipv4Address::ConvertFrom(m_localAddress); - const InetSocketAddress inetSocket = InetSocketAddress(ipv4, m_localPort); - NS_LOG_INFO(this << " Binding on " << ipv4 << " port " << m_localPort << " / " - << inetSocket << "."); - int ret [[maybe_unused]] = m_initialSocket->Bind(inetSocket); - NS_LOG_DEBUG(this << " Bind() return value= " << ret - << " GetErrNo= " << m_initialSocket->GetErrno() << "."); - + const auto ipv4 [[maybe_unused]] = + InetSocketAddress::ConvertFrom(m_local).GetIpv4(); + const auto port [[maybe_unused]] = + InetSocketAddress::ConvertFrom(m_local).GetPort(); m_initialSocket->SetIpTos(m_tos); // Affects only IPv4 sockets. + NS_LOG_INFO(this << " Binding on " << ipv4 << " port " << port << " / " << m_local + << "."); } - else if (Ipv6Address::IsMatchingType(m_localAddress)) + else if (Inet6SocketAddress::IsMatchingType(m_local)) { - const Ipv6Address ipv6 = Ipv6Address::ConvertFrom(m_localAddress); - const Inet6SocketAddress inet6Socket = Inet6SocketAddress(ipv6, m_localPort); - NS_LOG_INFO(this << " Binding on " << ipv6 << " port " << m_localPort << " / " - << inet6Socket << "."); - int ret [[maybe_unused]] = m_initialSocket->Bind(inet6Socket); - NS_LOG_DEBUG(this << " Bind() return value= " << ret - << " GetErrNo= " << m_initialSocket->GetErrno() << "."); + const auto ipv6 [[maybe_unused]] = + Inet6SocketAddress::ConvertFrom(m_local).GetIpv6(); + const auto port [[maybe_unused]] = + Inet6SocketAddress::ConvertFrom(m_local).GetPort(); + NS_LOG_INFO(this << " Binding on " << ipv6 << " port " << port << " / " << m_local + << "."); } else { NS_ABORT_MSG("Incompatible local address"); } - int ret [[maybe_unused]] = m_initialSocket->Listen(); + auto ret [[maybe_unused]] = m_initialSocket->Bind(m_local); + NS_LOG_DEBUG(this << " Bind() return value= " << ret + << " GetErrNo= " << m_initialSocket->GetErrno() << "."); + + ret = m_initialSocket->Listen(); NS_LOG_DEBUG(this << " Listen () return value= " << ret << " GetErrNo= " << m_initialSocket->GetErrno() << "."); + NS_ASSERT_MSG(m_initialSocket, "Failed creating socket."); + m_initialSocket->SetAcceptCallback( + MakeCallback(&ThreeGppHttpServer::ConnectionRequestCallback, this), + MakeCallback(&ThreeGppHttpServer::NewConnectionCreatedCallback, this)); + m_initialSocket->SetCloseCallbacks( + MakeCallback(&ThreeGppHttpServer::NormalCloseCallback, this), + MakeCallback(&ThreeGppHttpServer::ErrorCloseCallback, this)); + m_initialSocket->SetRecvCallback( + MakeCallback(&ThreeGppHttpServer::ReceivedDataCallback, this)); + m_initialSocket->SetSendCallback(MakeCallback(&ThreeGppHttpServer::SendCallback, this)); } // end of `if (m_initialSocket == 0)` - NS_ASSERT_MSG(m_initialSocket, "Failed creating socket."); - m_initialSocket->SetAcceptCallback( - MakeCallback(&ThreeGppHttpServer::ConnectionRequestCallback, this), - MakeCallback(&ThreeGppHttpServer::NewConnectionCreatedCallback, this)); - m_initialSocket->SetCloseCallbacks( - MakeCallback(&ThreeGppHttpServer::NormalCloseCallback, this), - MakeCallback(&ThreeGppHttpServer::ErrorCloseCallback, this)); - m_initialSocket->SetRecvCallback( - MakeCallback(&ThreeGppHttpServer::ReceivedDataCallback, this)); - m_initialSocket->SetSendCallback(MakeCallback(&ThreeGppHttpServer::SendCallback, this)); SwitchToState(STARTED); } // end of `if (m_state == NOT_STARTED)` @@ -372,10 +415,8 @@ ThreeGppHttpServer::ReceivedDataCallback(Ptr socket) { NS_LOG_FUNCTION(this << socket); - Ptr packet; Address from; - - while ((packet = socket->RecvFrom(from))) + while (auto packet = socket->RecvFrom(from)) { if (packet->GetSize() == 0) { @@ -408,11 +449,10 @@ ThreeGppHttpServer::ReceivedDataCallback(Ptr socket) m_rxTrace(packet, from); m_rxDelayTrace(Simulator::Now() - httpHeader.GetClientTs(), from); - Time processingDelay; switch (httpHeader.GetContentType()) { - case ThreeGppHttpHeader::MAIN_OBJECT: - processingDelay = m_httpVariables->GetMainObjectGenerationDelay(); + case ThreeGppHttpHeader::MAIN_OBJECT: { + const auto processingDelay = m_httpVariables->GetMainObjectGenerationDelay(); NS_LOG_INFO(this << " Will finish generating a main object" << " in " << processingDelay.As(Time::S) << "."); m_txBuffer->RecordNextServe(socket, @@ -422,9 +462,9 @@ ThreeGppHttpServer::ReceivedDataCallback(Ptr socket) socket), httpHeader.GetClientTs()); break; - - case ThreeGppHttpHeader::EMBEDDED_OBJECT: - processingDelay = m_httpVariables->GetEmbeddedObjectGenerationDelay(); + } + case ThreeGppHttpHeader::EMBEDDED_OBJECT: { + const auto processingDelay = m_httpVariables->GetEmbeddedObjectGenerationDelay(); NS_LOG_INFO(this << " Will finish generating an embedded object" << " in " << processingDelay.As(Time::S) << "."); m_txBuffer->RecordNextServe( @@ -435,7 +475,7 @@ ThreeGppHttpServer::ReceivedDataCallback(Ptr socket) socket), httpHeader.GetClientTs()); break; - + } default: NS_FATAL_ERROR("Invalid packet."); break; @@ -452,8 +492,8 @@ ThreeGppHttpServer::SendCallback(Ptr socket, uint32_t availableBufferSiz if (!m_txBuffer->IsBufferEmpty(socket)) { - const uint32_t txBufferSize [[maybe_unused]] = m_txBuffer->GetBufferSize(socket); - const uint32_t actualSent [[maybe_unused]] = ServeFromTxBuffer(socket); + const auto txBufferSize [[maybe_unused]] = m_txBuffer->GetBufferSize(socket); + const auto actualSent [[maybe_unused]] = ServeFromTxBuffer(socket); #ifdef NS3_LOG_ENABLE // Some log messages. @@ -500,11 +540,11 @@ ThreeGppHttpServer::ServeNewMainObject(Ptr socket) { NS_LOG_FUNCTION(this << socket); - const uint32_t objectSize = m_httpVariables->GetMainObjectSize(); + const auto objectSize = m_httpVariables->GetMainObjectSize(); NS_LOG_INFO(this << " Main object to be served is " << objectSize << " bytes."); m_mainObjectTrace(objectSize); m_txBuffer->WriteNewObject(socket, ThreeGppHttpHeader::MAIN_OBJECT, objectSize); - const uint32_t actualSent = ServeFromTxBuffer(socket); + const auto actualSent = ServeFromTxBuffer(socket); if (actualSent < objectSize) { @@ -522,11 +562,11 @@ ThreeGppHttpServer::ServeNewEmbeddedObject(Ptr socket) { NS_LOG_FUNCTION(this << socket); - const uint32_t objectSize = m_httpVariables->GetEmbeddedObjectSize(); + const auto objectSize = m_httpVariables->GetEmbeddedObjectSize(); NS_LOG_INFO(this << " Embedded object to be served is " << objectSize << " bytes."); m_embeddedObjectTrace(objectSize); m_txBuffer->WriteNewObject(socket, ThreeGppHttpHeader::EMBEDDED_OBJECT, objectSize); - const uint32_t actualSent = ServeFromTxBuffer(socket); + const auto actualSent = ServeFromTxBuffer(socket); if (actualSent < objectSize) { @@ -549,19 +589,18 @@ ThreeGppHttpServer::ServeFromTxBuffer(Ptr socket) NS_LOG_LOGIC(this << " Tx buffer is empty. Not sending anything."); return 0; } - bool firstPartOfObject = !m_txBuffer->HasTxedPartOfObject(socket); - const uint32_t socketSize = socket->GetTxAvailable(); + const auto socketSize = socket->GetTxAvailable(); NS_LOG_DEBUG(this << " Socket has " << socketSize << " bytes available for Tx."); // Get the number of bytes remaining to be sent. - const uint32_t txBufferSize = m_txBuffer->GetBufferSize(socket); + const auto txBufferSize = m_txBuffer->GetBufferSize(socket); // Compute the size of actual content to be sent; has to fit into the socket. // Note that header size is NOT counted as TxBuffer content. Header size is overhead. - uint32_t contentSize = std::min(txBufferSize, socketSize - 22); - Ptr packet = Create(contentSize); - uint32_t packetSize = contentSize; + const auto contentSize = std::min(txBufferSize, socketSize - 22); + auto packet = Create(contentSize); + auto packetSize = contentSize; if (packetSize == 0) { NS_LOG_LOGIC(this << " Socket size leads to packet size of zero; not sending anything."); @@ -569,7 +608,7 @@ ThreeGppHttpServer::ServeFromTxBuffer(Ptr socket) } // If this is the first packet of an object, attach a header. - if (firstPartOfObject) + if (!m_txBuffer->HasTxedPartOfObject(socket)) { // Create header. ThreeGppHttpHeader httpHeader; @@ -592,7 +631,7 @@ ThreeGppHttpServer::ServeFromTxBuffer(Ptr socket) } // Send. - const int actualBytes = socket->Send(packet); + const auto actualBytes = socket->Send(packet); NS_LOG_DEBUG(this << " Send() packet " << packet << " of " << packetSize << " bytes," << " return value= " << actualBytes << "."); m_txTrace(packet); @@ -619,8 +658,8 @@ ThreeGppHttpServer::ServeFromTxBuffer(Ptr socket) void ThreeGppHttpServer::SwitchToState(ThreeGppHttpServer::State_t state) { - const std::string oldState = GetStateString(); - const std::string newState = GetStateString(state); + const auto oldState = GetStateString(); + const auto newState = GetStateString(state); NS_LOG_FUNCTION(this << oldState << newState); m_state = state; NS_LOG_INFO(this << " ThreeGppHttpServer " << oldState << " --> " << newState << "."); @@ -717,20 +756,20 @@ ThreeGppHttpServerTxBuffer::CloseAllSockets() { NS_LOG_FUNCTION(this); - for (auto it = m_txBuffer.begin(); it != m_txBuffer.end(); ++it) + for (auto& [socket, buffer] : m_txBuffer) { - if (!Simulator::IsExpired(it->second.nextServe)) + if (!Simulator::IsExpired(buffer.nextServe)) { NS_LOG_INFO(this << " Canceling a serving event which is due in " - << Simulator::GetDelayLeft(it->second.nextServe).As(Time::S) << "."); - Simulator::Cancel(it->second.nextServe); + << Simulator::GetDelayLeft(buffer.nextServe).As(Time::S) << "."); + Simulator::Cancel(buffer.nextServe); } - it->first->Close(); - it->first->SetCloseCallbacks(MakeNullCallback>(), - MakeNullCallback>()); - it->first->SetRecvCallback(MakeNullCallback>()); - it->first->SetSendCallback(MakeNullCallback, uint32_t>()); + socket->Close(); + socket->SetCloseCallbacks(MakeNullCallback>(), + MakeNullCallback>()); + socket->SetRecvCallback(MakeNullCallback>()); + socket->SetSendCallback(MakeNullCallback, uint32_t>()); } m_txBuffer.clear(); @@ -739,40 +778,40 @@ ThreeGppHttpServerTxBuffer::CloseAllSockets() bool ThreeGppHttpServerTxBuffer::IsBufferEmpty(Ptr socket) const { - auto it = m_txBuffer.find(socket); - NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found."); + const auto it = m_txBuffer.find(socket); + NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found."); return (it->second.txBufferSize == 0); } Time ThreeGppHttpServerTxBuffer::GetClientTs(Ptr socket) const { - auto it = m_txBuffer.find(socket); - NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found."); + const auto it = m_txBuffer.find(socket); + NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found."); return it->second.clientTs; } ThreeGppHttpHeader::ContentType_t ThreeGppHttpServerTxBuffer::GetBufferContentType(Ptr socket) const { - auto it = m_txBuffer.find(socket); - NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found."); + const auto it = m_txBuffer.find(socket); + NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found."); return it->second.txBufferContentType; } uint32_t ThreeGppHttpServerTxBuffer::GetBufferSize(Ptr socket) const { - auto it = m_txBuffer.find(socket); - NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found."); + const auto it = m_txBuffer.find(socket); + NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found."); return it->second.txBufferSize; } bool ThreeGppHttpServerTxBuffer::HasTxedPartOfObject(Ptr socket) const { - auto it = m_txBuffer.find(socket); - NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found"); + const auto it = m_txBuffer.find(socket); + NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found"); return it->second.hasTxedPartOfObject; } diff --git a/src/applications/model/three-gpp-http-server.h b/src/applications/model/three-gpp-http-server.h index fd7321bcf..98a3f53bc 100644 --- a/src/applications/model/three-gpp-http-server.h +++ b/src/applications/model/three-gpp-http-server.h @@ -21,6 +21,7 @@ #include #include +#include #include namespace ns3 @@ -143,6 +144,18 @@ class ThreeGppHttpServer : public Application void StartApplication() override; void StopApplication() override; + /** + * \brief set the local address (temporary function until deprecated attributes are removed) + * \param addr local address + */ + void SetLocal(const Address& addr); + + /** + * \brief set the server port (temporary function until deprecated attributes are removed) + * \param port server port + */ + void SetPort(uint16_t port); + // SOCKET CALLBACK METHODS /** @@ -256,9 +269,9 @@ class ThreeGppHttpServer : public Application /// The `Variables` attribute. Ptr m_httpVariables; /// The `LocalAddress` attribute. - Address m_localAddress; + Address m_local; /// The `LocalPort` attribute. - uint16_t m_localPort; + std::optional m_port; /// The `Tos` attribute. uint8_t m_tos; /// The `Mtu` attribute. diff --git a/src/applications/test/three-gpp-http-client-server-test.cc b/src/applications/test/three-gpp-http-client-server-test.cc index 8cab4987e..9bd090824 100644 --- a/src/applications/test/three-gpp-http-client-server-test.cc +++ b/src/applications/test/three-gpp-http-client-server-test.cc @@ -329,17 +329,18 @@ ThreeGppHttpObjectTestCase::CreateSimpleInternetNode(Ptr channel, m_internetStackHelper.Install(node); // Assign IP address according to the selected Ip version. + const auto httpPort = 80; if (m_useIpv6) { Ipv6InterfaceContainer ipv6Ifs = m_ipv6AddressHelper.Assign(NetDeviceContainer(dev)); NS_ASSERT(ipv6Ifs.GetN() == 1); - assignedAddress = ipv6Ifs.GetAddress(0, 0); + assignedAddress = Inet6SocketAddress(ipv6Ifs.GetAddress(0, 0), httpPort); } else { Ipv4InterfaceContainer ipv4Ifs = m_ipv4AddressHelper.Assign(NetDeviceContainer(dev)); NS_ASSERT(ipv4Ifs.GetN() == 1); - assignedAddress = ipv4Ifs.GetAddress(0, 0); + assignedAddress = InetSocketAddress(ipv4Ifs.GetAddress(0, 0), httpPort); } NS_LOG_DEBUG(this << " node is assigned to " << assignedAddress << ".");