14#include <ns3/address-utils.h>
15#include <ns3/callback.h>
16#include <ns3/config.h>
18#include <ns3/packet.h>
19#include <ns3/pointer.h>
20#include <ns3/simulator.h>
21#include <ns3/socket.h>
22#include <ns3/tcp-socket-factory.h>
23#include <ns3/tcp-socket.h>
24#include <ns3/uinteger.h>
38 m_initialSocket{nullptr},
42 m_mtuSize{m_httpVariables->GetMtuSize()}
53 TypeId(
"ns3::ThreeGppHttpServer")
55 .AddConstructor<ThreeGppHttpServer>()
56 .AddAttribute(
"Variables",
57 "Variable collection, which is used to control e.g. processing and "
58 "object generation delays.",
62 .AddAttribute(
"LocalAddress",
63 "The local address of the server, "
64 "i.e., the address on which to bind the Rx socket.",
69 "Replaced by Local in ns-3.44.")
70 .AddAttribute(
"LocalPort",
71 "Port on which the application listen for incoming packets.",
76 "Replaced by Port in ns-3.44.")
78 "The Type of Service used to send packets. "
79 "All 8 bits of the TOS byte are set (including ECN bits).",
84 "Maximum transmission unit (in bytes) of the TCP sockets "
85 "used in this application, excluding the compulsory 40 "
86 "bytes TCP header. Typical values are 1460 and 536 bytes. "
87 "The attribute is read-only because the value is randomly "
94 "ConnectionEstablished",
95 "Connection to a remote web client has been established.",
97 "ns3::HttpServer::ConnectionEstablishedCallback")
98 .AddTraceSource(
"MainObject",
99 "A main object has been generated.",
101 "ns3::HttpServer::HttpObjectCallback")
102 .AddTraceSource(
"EmbeddedObject",
103 "An embedded object has been generated.",
105 "ns3::HttpServer::HttpObjectCallback")
106 .AddTraceSource(
"Tx",
107 "A packet has been sent.",
109 "ns3::Packet::TracedCallback")
110 .AddTraceSource(
"Rx",
111 "A packet has been received.",
113 "ns3::Packet::AddressTracedCallback")
114 .AddTraceSource(
"RxWithAddresses",
115 "A packet has been received.",
117 "ns3::Packet::TwoAddressTracedCallback")
118 .AddTraceSource(
"RxDelay",
119 "A packet has been received with delay information.",
121 "ns3::Application::DelayAddressCallback")
122 .AddTraceSource(
"StateTransition",
123 "Trace fired upon every HTTP client state transition.",
125 "ns3::Application::StateTransitionCallback");
195 return "NOT_STARTED";
202 return "FATAL_ERROR";
238 if (attrInfo.
name ==
"SegmentSize")
356 <<
" when the server instance is still running.");
359 else if (
m_txBuffer->IsSocketAvailable(socket))
368 socket->ShutdownSend();
392 <<
" when the server instance is still running.");
395 else if (
m_txBuffer->IsSocketAvailable(socket))
407 while (
auto packet = socket->RecvFrom(from))
409 if (packet->GetSize() == 0)
418 NS_LOG_INFO(
this <<
" A packet of " << packet->GetSize() <<
" bytes"
425 NS_LOG_INFO(
this <<
" A packet of " << packet->GetSize() <<
" bytes"
434 packet->PeekHeader(httpHeader);
444 const auto processingDelay =
m_httpVariables->GetMainObjectGenerationDelay();
445 NS_LOG_INFO(
this <<
" Will finish generating a main object"
446 <<
" in " << processingDelay.As(
Time::S) <<
".");
456 const auto processingDelay =
m_httpVariables->GetEmbeddedObjectGenerationDelay();
457 NS_LOG_INFO(
this <<
" Will finish generating an embedded object"
458 <<
" in " << processingDelay.As(
Time::S) <<
".");
487 const auto txBufferSize [[maybe_unused]] =
m_txBuffer->GetBufferSize(socket);
492 if (actualSent < txBufferSize)
494 switch (
m_txBuffer->GetBufferContentType(socket))
497 NS_LOG_INFO(
this <<
" Transmission of main object is suspended"
498 <<
" after " << actualSent <<
" bytes.");
501 NS_LOG_INFO(
this <<
" Transmission of embedded object is suspended"
502 <<
" after " << actualSent <<
" bytes.");
511 switch (
m_txBuffer->GetBufferContentType(socket))
514 NS_LOG_INFO(
this <<
" Finished sending a whole main object.");
517 NS_LOG_INFO(
this <<
" Finished sending a whole embedded object.");
534 NS_LOG_INFO(
this <<
" Main object to be served is " << objectSize <<
" bytes.");
539 if (actualSent < objectSize)
541 NS_LOG_INFO(
this <<
" Transmission of main object is suspended"
542 <<
" after " << actualSent <<
" bytes.");
546 NS_LOG_INFO(
this <<
" Finished sending a whole main object.");
556 NS_LOG_INFO(
this <<
" Embedded object to be served is " << objectSize <<
" bytes.");
561 if (actualSent < objectSize)
563 NS_LOG_INFO(
this <<
" Transmission of embedded object is suspended"
564 <<
" after " << actualSent <<
" bytes.");
568 NS_LOG_INFO(
this <<
" Finished sending a whole embedded object.");
579 NS_LOG_LOGIC(
this <<
" Tx buffer is empty. Not sending anything.");
583 const auto socketSize = socket->GetTxAvailable();
584 NS_LOG_DEBUG(
this <<
" Socket has " << socketSize <<
" bytes available for Tx.");
587 const auto txBufferSize =
m_txBuffer->GetBufferSize(socket);
591 const auto contentSize = std::min(txBufferSize, socketSize - 22);
596 NS_LOG_LOGIC(
this <<
" Socket size leads to packet size of zero; not sending anything.");
610 packet->AddHeader(httpHeader);
614 <<
" The corresponding request came "
620 <<
" bytes to be appended to a previous packet.");
624 const auto actualBytes = socket->Send(packet);
626 <<
" return value= " << actualBytes <<
".");
629 if (actualBytes ==
static_cast<int>(
packetSize))
632 m_txBuffer->DepleteBufferSize(socket, contentSize);
640 <<
" GetErrNo= " << socket->GetErrno() <<
","
641 <<
" suspending transmission"
642 <<
" and waiting for another Tx opportunity.");
655 NS_LOG_INFO(
this <<
" ThreeGppHttpServer " << oldState <<
" --> " << newState <<
".");
679 this <<
" Cannot add socket " << socket
680 <<
" because it has already been added before.");
700 NS_LOG_INFO(
this <<
" Canceling a serving event which is due in "
723 NS_LOG_INFO(
this <<
" Canceling a serving event which is due in "
728 if (it->second.txBufferSize > 0)
730 NS_LOG_WARN(
this <<
" Closing a socket where " << it->second.txBufferSize
731 <<
" bytes of transmission"
732 <<
" is still pending in the corresponding Tx buffer.");
753 NS_LOG_INFO(
this <<
" Canceling a serving event which is due in "
773 return (it->second.txBufferSize == 0);
781 return it->second.clientTs;
789 return it->second.txBufferContentType;
797 return it->second.txBufferSize;
805 return it->second.hasTxedPartOfObject;
816 "Unable to write an object without a proper Content-Type.");
817 NS_ASSERT_MSG(objectSize > 0,
"Unable to write a zero-sized object.");
822 "Cannot write to Tx buffer of socket "
823 << socket <<
" until the previous content has been completely sent.");
824 it->second.txBufferContentType = contentType;
825 it->second.txBufferSize = objectSize;
826 it->second.hasTxedPartOfObject =
false;
832 const Time& clientTs)
838 it->second.nextServe = eventId;
839 it->second.clientTs = clientTs;
852 "The requested amount is larger than the current buffer size.");
853 it->second.txBufferSize -= amount;
854 it->second.hasTxedPartOfObject =
true;
856 if (it->second.isClosing && (it->second.txBufferSize == 0))
873 it->second.isClosing =
true;
a polymophic address class
AttributeValue implementation for Address.
void DoDispose() override
Destructor implementation.
Ptr< Node > GetNode() const
An identifier for simulation events.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
uint16_t GetPort() const
Get the port.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6() const
Get the IPv6 address.
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
static bool IsMatchingType(const Address &address)
static bool IsMatchingType(const Address &address)
If the Address matches the type.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
static bool IsFinished()
Check if the simulation should finish.
static Time Now()
Return the current simulation virtual time.
static bool IsExpired(const EventId &id)
Check if an event has already run or been cancelled.
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Base class for sink applications.
static constexpr uint32_t INVALID_PORT
invalid port
Address m_local
Local address to bind to (address and port)
uint32_t m_port
Local port to bind to.
virtual Socket::SocketErrno GetErrno() const =0
Get last error number.
void SetIpTos(uint8_t ipTos)
Manually set IP Type of Service field.
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
void SetSendCallback(Callback< void, Ptr< Socket >, uint32_t > sendCb)
Notify application when space in transmit buffer is added.
void SetCloseCallbacks(Callback< void, Ptr< Socket > > normalClose, Callback< void, Ptr< Socket > > errorClose)
Detect socket recv() events such as graceful shutdown or error.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
virtual int Close()=0
Close a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int Listen()=0
Listen for incoming connections.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
State_t
The possible states of the application.
@ NOT_STARTED
Before StartApplication() is invoked.
@ STOPPED
After StopApplication() is invoked.
@ STARTED
Passively listening and responding to requests.
void StartApplication() override
Application specific startup code.
uint32_t ServeFromTxBuffer(Ptr< Socket > socket)
Creates a packet out of a pending object in the Tx buffer send it over the given socket.
State_t m_state
The current state of the client application. Begins with NOT_STARTED.
Ptr< ThreeGppHttpVariables > m_httpVariables
The Variables attribute.
void SetLocal(const Address &addr) override
set the local address
TracedCallback< uint32_t > m_embeddedObjectTrace
The EmbeddedObject trace source.
void ReceivedDataCallback(Ptr< Socket > socket)
Invoked when m_initialSocket receives some packet data.
void ServeNewMainObject(Ptr< Socket > socket)
Generates a new main object and push it into the Tx buffer.
TracedCallback< uint32_t > m_mainObjectTrace
The MainObject trace source.
uint32_t m_mtuSize
The Mtu attribute.
TracedCallback< const Time &, const Address & > m_rxDelayTrace
The RxDelay trace source.
State_t GetState() const
Returns the current state of the application.
Ptr< ThreeGppHttpServerTxBuffer > m_txBuffer
Pointer to the transmission buffer.
bool ConnectionRequestCallback(Ptr< Socket > socket, const Address &address)
Invoked when m_initialSocket receives a connection request.
TracedCallback< Ptr< const Packet >, const Address &, const Address & > m_rxTraceWithAddresses
The Rx trace source with the local address.
void ServeNewEmbeddedObject(Ptr< Socket > socket)
Generates a new embedded object and push it into the Tx buffer.
TracedCallback< const std::string &, const std::string & > m_stateTransitionTrace
The StateTransition trace source.
void ErrorCloseCallback(Ptr< Socket > socket)
Invoked when a connection with a web client is terminated.
void SendCallback(Ptr< Socket > socket, uint32_t availableBufferSize)
Invoked when more buffer space for transmission is added to a socket.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
The Rx trace source.
uint8_t m_tos
The Tos attribute.
Ptr< Socket > GetSocket() const
Returns a pointer to the listening socket.
TracedCallback< Ptr< const ThreeGppHttpServer >, Ptr< Socket > > m_connectionEstablishedTrace
The ConnectionEstablished trace source.
Ptr< Socket > m_initialSocket
The listening socket, for receiving connection requests from clients.
static TypeId GetTypeId()
Returns the object TypeId.
std::string GetStateString() const
Returns the current state of the application in string format.
ThreeGppHttpServer()
Creates a new instance of HTTP server application.
TracedCallback< Ptr< const Packet > > m_txTrace
The Tx trace source.
void NormalCloseCallback(Ptr< Socket > socket)
Invoked when a connection with a web client is terminated.
void DoDispose() override
Destructor implementation.
void StopApplication() override
Application specific shutdown code.
void NewConnectionCreatedCallback(Ptr< Socket > socket, const Address &address)
Invoked when a new connection has been established.
void SetMtuSize(uint32_t mtuSize)
Sets the maximum transmission unit (MTU) size used by the application.
std::optional< uint16_t > m_optPort
The LocalPort attribute.
void SwitchToState(State_t state)
Change the state of the server.
void SetPort(uint32_t port) override
set the server port
void DepleteBufferSize(Ptr< Socket > socket, uint32_t amount)
Decrements a buffer size by a given amount.
ThreeGppHttpHeader::ContentType_t GetBufferContentType(Ptr< Socket > socket) const
Returns ThreeGppHttpHeader::NOT_SET when the buffer is new and never been filled with any data before...
uint32_t GetBufferSize(Ptr< Socket > socket) const
void CloseAllSockets()
Close and remove all stored sockets, hence clearing the buffer.
bool HasTxedPartOfObject(Ptr< Socket > socket) const
void PrepareClose(Ptr< Socket > socket)
Tell the buffer to close the associated socket once the buffer becomes empty.
Time GetClientTs(Ptr< Socket > socket) const
void CloseSocket(Ptr< Socket > socket)
Close and remove a socket and its associated transmission buffer, and then unset the socket's callbac...
ThreeGppHttpServerTxBuffer()
Create an empty instance of transmission buffer.
void RecordNextServe(Ptr< Socket > socket, const EventId &eventId, const Time &clientTs)
Informs about a pending transmission event associated with the socket, so that it would be automatica...
std::map< Ptr< Socket >, TxBuffer_t > m_txBuffer
Collection of accepted sockets and its individual transmission buffer.
void WriteNewObject(Ptr< Socket > socket, ThreeGppHttpHeader::ContentType_t contentType, uint32_t objectSize)
Writes a data representing a new main object or embedded object to the transmission buffer.
bool IsBufferEmpty(Ptr< Socket > socket) const
bool IsSocketAvailable(Ptr< Socket > socket) const
This method is typically used before calling other methods.
void AddSocket(Ptr< Socket > socket)
Add a new socket and create an empty transmission buffer for it.
void RemoveSocket(Ptr< Socket > socket)
Remove a socket and its associated transmission buffer, and then unset the socket's callbacks to prev...
Container of various random variables to assist in generating web browsing traffic pattern.
Simulation virtual time values and global simulation resolution.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
a unique identifier for an interface.
@ ATTR_GET
The attribute can be read.
std::size_t GetAttributeN() const
Get the number of attributes.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Hold an unsigned integer type.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeAddressChecker()
Ptr< const AttributeAccessor > MakeAddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Ptr< const AttributeChecker > MakeUintegerChecker()
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Callback< R, Args... > MakeNullCallback()
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Address ConvertToSocketAddress(const Address &address, uint16_t port)
Convert IPv4/IPv6 address with port to a socket address.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Set of fields representing a single transmission buffer, which will be associated with a socket.
ThreeGppHttpHeader::ContentType_t txBufferContentType
The content type of the current data inside the transmission buffer.
uint32_t txBufferSize
The length (in bytes) of the current data inside the transmission buffer.
bool isClosing
True if the remote end has issued a request to close, which means that this socket will immediately c...
bool hasTxedPartOfObject
True if the buffer content has been read since it is written.
static const uint32_t packetSize
Packet size generated at the AP.