A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
three-gpp-http-server.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013 Magister Solutions
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Budiarto Herman <budiarto.herman@magister.fi>
7 *
8 */
9
11
13
14#include "ns3/address-utils.h"
15#include "ns3/callback.h"
16#include "ns3/config.h"
17#include "ns3/log.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"
25
26NS_LOG_COMPONENT_DEFINE("ThreeGppHttpServer");
27
28namespace ns3
29{
30
31// HTTP SERVER ////////////////////////////////////////////////////////////////
32
34
39 m_mtuSize{m_httpVariables->GetMtuSize()}
40{
41 NS_LOG_FUNCTION(this);
42 NS_LOG_INFO(this << " MTU size for this server application is " << m_mtuSize << " bytes.");
43 m_protocolTid = TypeId::LookupByName("ns3::TcpSocketFactory");
44}
45
46// static
49{
50 static TypeId tid =
51 TypeId("ns3::ThreeGppHttpServer")
53 .AddConstructor<ThreeGppHttpServer>()
54 .AddAttribute("Variables",
55 "Variable collection, which is used to control e.g. processing and "
56 "object generation delays.",
60 // NS_DEPRECATED_3_44
61 .AddAttribute("LocalAddress",
62 "The local address of the server, "
63 "i.e., the address on which to bind the Rx socket.",
68 "Replaced by Local in ns-3.44.")
69 // NS_DEPRECATED_3_44
70 .AddAttribute("LocalPort",
71 "Port on which the application listen for incoming packets.",
72 UintegerValue(80), // the default HTTP port
76 "Replaced by Port in ns-3.44.")
77 .AddAttribute("Tos",
78 "The Type of Service used to send packets. "
79 "All 8 bits of the TOS byte are set (including ECN bits).",
83 .AddAttribute("Mtu",
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 "
88 "determined.",
93 .AddTraceSource(
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("RxWithAddresses",
111 "A packet has been received.",
113 "ns3::Packet::TwoAddressTracedCallback")
114 .AddTraceSource("RxDelay",
115 "A packet has been received with delay information.",
117 "ns3::Application::DelayAddressCallback")
118 .AddTraceSource("StateTransition",
119 "Trace fired upon every HTTP client state transition.",
121 "ns3::Application::StateTransitionCallback");
122 return tid;
123}
124
125void
127{
128 NS_LOG_FUNCTION(this << addr);
129 if (!addr.IsInvalid())
130 {
131 m_local = addr;
132 if (m_optPort)
133 {
135 }
136 }
137}
138
139void
141{
142 NS_LOG_FUNCTION(this << port);
143 if (port != INVALID_PORT)
144 {
145 m_port = port;
146 }
147 if (m_local.IsInvalid())
148 {
149 // save for later
151 return;
152 }
154 {
156 }
157}
158
159void
161{
162 NS_LOG_FUNCTION(this << mtuSize);
163 m_mtuSize = mtuSize;
164}
165
168{
169 return m_socket;
170}
171
174{
175 return m_state;
176}
177
178std::string
183
184// static
185std::string
187{
188 switch (state)
189 {
190 case NOT_STARTED:
191 return "NOT_STARTED";
192 case STARTED:
193 return "STARTED";
194 case STOPPED:
195 return "STOPPED";
196 default:
197 NS_FATAL_ERROR("Unknown state");
198 return "FATAL_ERROR";
199 }
200}
201
202void
204{
205 NS_LOG_FUNCTION(this);
206
208 {
210 }
211
212 SinkApplication::DoDispose(); // Chain up.
213}
214
215void
217{
218 NS_LOG_FUNCTION(this);
219
220 if (m_state != NOT_STARTED)
221 {
222 NS_FATAL_ERROR("Invalid state " << GetStateString() << " for StartApplication().");
223 }
224
225 m_httpVariables->Initialize();
226
227 m_socket->SetAttribute("SegmentSize", UintegerValue(m_mtuSize));
228
229 NS_ABORT_MSG_IF(m_local.IsInvalid(), "Local address not properly set");
231 {
232 const auto ipv4 [[maybe_unused]] = InetSocketAddress::ConvertFrom(m_local).GetIpv4();
233 m_socket->SetIpTos(m_tos); // Affects only IPv4 sockets.
234 NS_LOG_INFO(this << " Binding on " << ipv4 << " port " << m_port << " / " << m_local
235 << ".");
236 }
238 {
239 const auto ipv6 [[maybe_unused]] = Inet6SocketAddress::ConvertFrom(m_local).GetIpv6();
240 NS_LOG_INFO(this << " Binding on " << ipv6 << " port " << m_port << " / " << m_local
241 << ".");
242 }
243 else
244 {
245 NS_ABORT_MSG("Incompatible local address");
246 }
247
248 auto ret [[maybe_unused]] = m_socket->Bind(m_local);
249 NS_LOG_DEBUG(this << " Bind() return value= " << ret << " GetErrNo= " << m_socket->GetErrno()
250 << ".");
251
252 ret = m_socket->Listen();
253 NS_LOG_DEBUG(this << " Listen () return value= " << ret << " GetErrNo= " << m_socket->GetErrno()
254 << ".");
255
256 NS_ASSERT_MSG(m_socket, "Failed creating socket.");
257 m_socket->SetAcceptCallback(
264
266}
267
268void
270{
271 NS_LOG_FUNCTION(this);
272
274
275 // Close all accepted sockets.
276 m_txBuffer->CloseAllSockets();
277}
278
279bool
281{
282 NS_LOG_FUNCTION(this << socket << address);
283 return true; // Unconditionally accept the connection request.
284}
285
286void
288{
289 NS_LOG_FUNCTION(this << socket << address);
290
291 socket->SetCloseCallbacks(MakeCallback(&ThreeGppHttpServer::NormalCloseCallback, this),
293 socket->SetRecvCallback(MakeCallback(&ThreeGppHttpServer::ReceivedDataCallback, this));
294 socket->SetSendCallback(MakeCallback(&ThreeGppHttpServer::SendCallback, this));
295
296 m_connectionEstablishedTrace(this, socket);
297 m_txBuffer->AddSocket(socket);
298
299 /*
300 * A typical connection is established after receiving an empty (i.e., no
301 * data) TCP packet with ACK flag. The actual data will follow in a separate
302 * packet after that and will be received by ReceivedDataCallback().
303 *
304 * However, that empty ACK packet might get lost. In this case, we may
305 * receive the first data packet right here already, because it also counts
306 * as a new connection. The statement below attempts to fetch the data from
307 * that packet, if any.
308 */
309 ReceivedDataCallback(socket);
310}
311
312void
314{
315 NS_LOG_FUNCTION(this << socket);
316
317 if (socket == m_socket)
318 {
319 if (m_state == STARTED)
320 {
321 NS_FATAL_ERROR("Initial listener socket shall not be closed"
322 << " when the server instance is still running.");
323 }
324 }
325 else if (m_txBuffer->IsSocketAvailable(socket))
326 {
327 // The application should now prepare to close the socket.
328 if (m_txBuffer->IsBufferEmpty(socket))
329 {
330 /*
331 * Here we declare that we have nothing more to send and the socket
332 * may be closed immediately.
333 */
334 socket->ShutdownSend();
335 m_txBuffer->RemoveSocket(socket);
336 }
337 else
338 {
339 /*
340 * Remember to close the socket later, whenever the buffer becomes
341 * empty.
342 */
343 m_txBuffer->PrepareClose(socket);
344 }
345 }
346}
347
348void
350{
351 NS_LOG_FUNCTION(this << socket);
352
353 if (socket == m_socket)
354 {
355 if (m_state == STARTED)
356 {
357 NS_FATAL_ERROR("Initial listener socket shall not be closed"
358 << " when the server instance is still running.");
359 }
360 }
361 else if (m_txBuffer->IsSocketAvailable(socket))
362 {
363 m_txBuffer->CloseSocket(socket);
364 }
365}
366
367void
369{
370 NS_LOG_FUNCTION(this << socket);
371
372 Address from;
373 while (auto packet = socket->RecvFrom(from))
374 {
375 if (packet->GetSize() == 0)
376 {
377 break; // EOF
378 }
379
380#ifdef NS3_LOG_ENABLE
381 // Some log messages.
383 {
384 NS_LOG_INFO(this << " A packet of " << packet->GetSize() << " bytes"
385 << " received from " << InetSocketAddress::ConvertFrom(from).GetIpv4()
386 << " port " << InetSocketAddress::ConvertFrom(from).GetPort() << " / "
388 }
390 {
391 NS_LOG_INFO(this << " A packet of " << packet->GetSize() << " bytes"
392 << " received from " << Inet6SocketAddress::ConvertFrom(from).GetIpv6()
393 << " port " << Inet6SocketAddress::ConvertFrom(from).GetPort() << " / "
395 }
396#endif /* NS3_LOG_ENABLE */
397
398 // Check the header. No need to remove it, since it is not a "real" header.
399 ThreeGppHttpHeader httpHeader;
400 packet->PeekHeader(httpHeader);
401
402 // Fire trace sources.
404 m_rxTrace(packet, from);
405 m_rxTraceWithAddresses(packet, from, m_local);
406 m_rxDelayTrace(Simulator::Now() - httpHeader.GetClientTs(), from);
407
408 switch (httpHeader.GetContentType())
409 {
411 const auto processingDelay = m_httpVariables->GetMainObjectGenerationDelay();
412 NS_LOG_INFO(this << " Will finish generating a main object in "
413 << processingDelay.As(Time::S) << ".");
414 m_txBuffer->RecordNextServe(socket,
415 Simulator::Schedule(processingDelay,
417 this,
418 socket),
419 httpHeader.GetClientTs());
420 break;
421 }
423 const auto processingDelay = m_httpVariables->GetEmbeddedObjectGenerationDelay();
424 NS_LOG_INFO(this << " Will finish generating an embedded object in "
425 << processingDelay.As(Time::S) << ".");
426 m_txBuffer->RecordNextServe(
427 socket,
428 Simulator::Schedule(processingDelay,
430 this,
431 socket),
432 httpHeader.GetClientTs());
433 break;
434 }
435 default:
436 NS_FATAL_ERROR("Invalid packet.");
437 break;
438 }
439 }
440}
441
442void
444{
445 NS_LOG_FUNCTION(this << socket << availableBufferSize);
446
447 if (m_txBuffer->IsBufferEmpty(socket))
448 {
449 return;
450 }
451
452 const auto txBufferSize [[maybe_unused]] = m_txBuffer->GetBufferSize(socket);
453 const auto actualSent [[maybe_unused]] = ServeFromTxBuffer(socket);
454
455#ifdef NS3_LOG_ENABLE
456 // Some log messages.
457 if (actualSent < txBufferSize)
458 {
459 switch (m_txBuffer->GetBufferContentType(socket))
460 {
462 NS_LOG_INFO(this << " Transmission of main object is suspended after " << actualSent
463 << " bytes.");
464 break;
466 NS_LOG_INFO(this << " Transmission of embedded object is suspended after " << actualSent
467 << " bytes.");
468 break;
469 default:
470 NS_FATAL_ERROR("Invalid Tx buffer content type.");
471 break;
472 }
473 }
474 else
475 {
476 switch (m_txBuffer->GetBufferContentType(socket))
477 {
479 NS_LOG_INFO(this << " Finished sending a whole main object.");
480 break;
482 NS_LOG_INFO(this << " Finished sending a whole embedded object.");
483 break;
484 default:
485 NS_FATAL_ERROR("Invalid Tx buffer content type.");
486 break;
487 }
488 }
489#endif /* NS3_LOG_ENABLE */
490}
491
492void
494{
495 NS_LOG_FUNCTION(this << socket);
496
497 const auto objectSize = m_httpVariables->GetMainObjectSize();
498 NS_LOG_INFO(this << " Main object to be served is " << objectSize << " bytes.");
499 m_mainObjectTrace(objectSize);
500 m_txBuffer->WriteNewObject(socket, ThreeGppHttpHeader::MAIN_OBJECT, objectSize);
501 const auto actualSent = ServeFromTxBuffer(socket);
502
503 if (actualSent < objectSize)
504 {
505 NS_LOG_INFO(this << " Transmission of main object is suspended after " << actualSent
506 << " bytes.");
507 }
508 else
509 {
510 NS_LOG_INFO(this << " Finished sending a whole main object.");
511 }
512}
513
514void
516{
517 NS_LOG_FUNCTION(this << socket);
518
519 const auto objectSize = m_httpVariables->GetEmbeddedObjectSize();
520 NS_LOG_INFO(this << " Embedded object to be served is " << objectSize << " bytes.");
521 m_embeddedObjectTrace(objectSize);
522 m_txBuffer->WriteNewObject(socket, ThreeGppHttpHeader::EMBEDDED_OBJECT, objectSize);
523 const auto actualSent = ServeFromTxBuffer(socket);
524
525 if (actualSent < objectSize)
526 {
527 NS_LOG_INFO(this << " Transmission of embedded object is suspended after " << actualSent
528 << " bytes.");
529 }
530 else
531 {
532 NS_LOG_INFO(this << " Finished sending a whole embedded object.");
533 }
534}
535
538{
539 NS_LOG_FUNCTION(this << socket);
540
541 if (m_txBuffer->IsBufferEmpty(socket))
542 {
543 NS_LOG_LOGIC(this << " Tx buffer is empty. Not sending anything.");
544 return 0;
545 }
546
547 const auto socketSize = socket->GetTxAvailable();
548 NS_LOG_DEBUG(this << " Socket has " << socketSize << " bytes available for Tx.");
549
550 // Get the number of bytes remaining to be sent.
551 const auto txBufferSize = m_txBuffer->GetBufferSize(socket);
552
553 // Compute the size of actual content to be sent; has to fit into the socket.
554 // Note that header size is NOT counted as TxBuffer content. Header size is overhead.
555 const auto contentSize = std::min(txBufferSize, socketSize - 22);
556 auto packet = Create<Packet>(contentSize);
557 auto packetSize = contentSize;
558 if (packetSize == 0)
559 {
560 NS_LOG_LOGIC(this << " Socket size leads to packet size of zero; not sending anything.");
561 return 0;
562 }
563
564 // If this is the first packet of an object, attach a header.
565 if (!m_txBuffer->HasTxedPartOfObject(socket))
566 {
567 // Create header.
568 ThreeGppHttpHeader httpHeader;
569 httpHeader.SetContentLength(txBufferSize);
570 httpHeader.SetContentType(m_txBuffer->GetBufferContentType(socket));
571 // Using the client TS value as per the corresponding request packet.
572 httpHeader.SetClientTs(m_txBuffer->GetClientTs(socket));
573 httpHeader.SetServerTs(Simulator::Now());
574 packet->AddHeader(httpHeader);
575 packetSize += httpHeader.GetSerializedSize();
576
577 NS_LOG_INFO(this << " Created packet " << packet << " of " << packetSize << " bytes."
578 << " The corresponding request came "
579 << (Simulator::Now() - httpHeader.GetClientTs()).As(Time::S) << " ago.");
580 }
581 else
582 {
583 NS_LOG_INFO(this << " Created packet " << packet << " of " << packetSize
584 << " bytes to be appended to a previous packet.");
585 }
586
587 // Send.
588 const auto actualBytes = socket->Send(packet);
589 NS_LOG_DEBUG(this << " Send() packet " << packet << " of " << packetSize << " bytes,"
590 << " return value= " << actualBytes << ".");
591 m_txTrace(packet);
592
593 if (actualBytes == static_cast<int>(packetSize))
594 {
595 // The packet goes through successfully.
596 m_txBuffer->DepleteBufferSize(socket, contentSize);
597 NS_LOG_INFO(this << " Remaining object to be sent " << m_txBuffer->GetBufferSize(socket)
598 << " bytes.");
599 return packetSize;
600 }
601 else
602 {
603 NS_LOG_INFO(this << " Failed to send object, GetErrNo= " << socket->GetErrno()
604 << ", suspending transmission and waiting for another Tx opportunity.");
605 return 0;
606 }
607}
608
609void
611{
612 const auto oldState = GetStateString();
613 const auto newState = GetStateString(state);
614 NS_LOG_FUNCTION(this << oldState << newState);
615 m_state = state;
616 NS_LOG_INFO(this << " ThreeGppHttpServer " << oldState << " --> " << newState << ".");
617 m_stateTransitionTrace(oldState, newState);
618}
619
620// HTTP SERVER TX BUFFER //////////////////////////////////////////////////////
621
626
627bool
629{
630 auto it = m_txBuffer.find(socket);
631 return (it != m_txBuffer.end());
632}
633
634void
636{
637 NS_LOG_FUNCTION(this << socket);
638
640 this << " Cannot add socket " << socket
641 << " because it has already been added before.");
642
643 TxBuffer_t txBuffer;
645 txBuffer.txBufferSize = 0;
646 txBuffer.isClosing = false;
647 txBuffer.hasTxedPartOfObject = false;
648 m_txBuffer.insert(std::pair<Ptr<Socket>, TxBuffer_t>(socket, txBuffer));
649}
650
651void
653{
654 NS_LOG_FUNCTION(this << socket);
655
656 auto it = m_txBuffer.find(socket);
657 NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found.");
658
659 if (!Simulator::IsExpired(it->second.nextServe))
660 {
661 NS_LOG_INFO(this << " Canceling a serving event which is due in "
662 << Simulator::GetDelayLeft(it->second.nextServe).As(Time::S) << ".");
663 Simulator::Cancel(it->second.nextServe);
664 }
665
666 it->first->SetCloseCallbacks(MakeNullCallback<void, Ptr<Socket>>(),
668 it->first->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>>());
669 it->first->SetSendCallback(MakeNullCallback<void, Ptr<Socket>, uint32_t>());
670
671 m_txBuffer.erase(it);
672}
673
674void
676{
677 NS_LOG_FUNCTION(this << socket);
678
679 auto it = m_txBuffer.find(socket);
680 NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found.");
681
682 if (!Simulator::IsExpired(it->second.nextServe))
683 {
684 NS_LOG_INFO(this << " Canceling a serving event which is due in "
685 << Simulator::GetDelayLeft(it->second.nextServe).As(Time::S) << ".");
686 Simulator::Cancel(it->second.nextServe);
687 }
688
689 if (it->second.txBufferSize > 0)
690 {
691 NS_LOG_WARN(this << " Closing a socket where " << it->second.txBufferSize
692 << " bytes of transmission"
693 << " is still pending in the corresponding Tx buffer.");
694 }
695
696 it->first->Close();
697 it->first->SetCloseCallbacks(MakeNullCallback<void, Ptr<Socket>>(),
699 it->first->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>>());
700 it->first->SetSendCallback(MakeNullCallback<void, Ptr<Socket>, uint32_t>());
701
702 m_txBuffer.erase(it);
703}
704
705void
707{
708 NS_LOG_FUNCTION(this);
709
710 for (auto& [socket, buffer] : m_txBuffer)
711 {
712 if (!Simulator::IsExpired(buffer.nextServe))
713 {
714 NS_LOG_INFO(this << " Canceling a serving event which is due in "
715 << Simulator::GetDelayLeft(buffer.nextServe).As(Time::S) << ".");
716 Simulator::Cancel(buffer.nextServe);
717 }
718
719 socket->Close();
720 socket->SetCloseCallbacks(MakeNullCallback<void, Ptr<Socket>>(),
722 socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>>());
723 socket->SetSendCallback(MakeNullCallback<void, Ptr<Socket>, uint32_t>());
724 }
725
726 m_txBuffer.clear();
727}
728
729bool
731{
732 const auto it = m_txBuffer.find(socket);
733 NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found.");
734 return (it->second.txBufferSize == 0);
735}
736
737Time
739{
740 const auto it = m_txBuffer.find(socket);
741 NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found.");
742 return it->second.clientTs;
743}
744
747{
748 const auto it = m_txBuffer.find(socket);
749 NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found.");
750 return it->second.txBufferContentType;
751}
752
755{
756 const auto it = m_txBuffer.find(socket);
757 NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found.");
758 return it->second.txBufferSize;
759}
760
761bool
763{
764 const auto it = m_txBuffer.find(socket);
765 NS_ASSERT_MSG(it != m_txBuffer.cend(), "Socket " << socket << " cannot be found");
766 return it->second.hasTxedPartOfObject;
767}
768
769void
772 uint32_t objectSize)
773{
774 NS_LOG_FUNCTION(this << socket << contentType << objectSize);
775
777 "Unable to write an object without a proper Content-Type.");
778 NS_ASSERT_MSG(objectSize > 0, "Unable to write a zero-sized object.");
779
780 auto it = m_txBuffer.find(socket);
781 NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found.");
782 NS_ASSERT_MSG(it->second.txBufferSize == 0,
783 "Cannot write to Tx buffer of socket "
784 << socket << " until the previous content has been completely sent.");
785 it->second.txBufferContentType = contentType;
786 it->second.txBufferSize = objectSize;
787 it->second.hasTxedPartOfObject = false;
788}
789
790void
792 const EventId& eventId,
793 const Time& clientTs)
794{
795 NS_LOG_FUNCTION(this << socket << clientTs.As(Time::S));
796
797 auto it = m_txBuffer.find(socket);
798 NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found.");
799 it->second.nextServe = eventId;
800 it->second.clientTs = clientTs;
801}
802
803void
805{
806 NS_LOG_FUNCTION(this << socket << amount);
807
808 NS_ASSERT_MSG(amount > 0, "Unable to consume zero bytes.");
809
810 auto it = m_txBuffer.find(socket);
811 NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found.");
812 NS_ASSERT_MSG(it->second.txBufferSize >= amount,
813 "The requested amount is larger than the current buffer size.");
814 it->second.txBufferSize -= amount;
815 it->second.hasTxedPartOfObject = true;
816
817 if (it->second.isClosing && (it->second.txBufferSize == 0))
818 {
819 /*
820 * The peer has earlier issued a close request and we have now waited
821 * until all the existing data are pushed into the socket. Now we close
822 * the socket explicitly.
823 */
824 CloseSocket(socket);
825 }
826}
827
828void
830{
831 NS_LOG_FUNCTION(this << socket);
832 auto it = m_txBuffer.find(socket);
833 NS_ASSERT_MSG(it != m_txBuffer.end(), "Socket " << socket << " cannot be found.");
834 it->second.isClosing = true;
835}
836
837} // namespace ns3
a polymophic address class
Definition address.h:111
bool IsInvalid() const
Definition address.cc:81
AttributeValue implementation for Address.
Definition address.h:357
An identifier for simulation events.
Definition event-id.h:44
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
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.
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
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...
Definition simulator.cc:274
static bool IsFinished()
Check if the simulation should finish.
Definition simulator.cc:160
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static bool IsExpired(const EventId &id)
Check if an event has already run or been cancelled.
Definition simulator.cc:284
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition simulator.cc:206
static constexpr uint32_t INVALID_PORT
invalid port
ns3::TracedCallback< Ptr< const Packet > > m_rxTraceWithoutAddress
Callbacks for tracing the packet Rx events.
void DoDispose() override
Destructor implementation.
TypeId m_protocolTid
Protocol TypeId value.
SinkApplication(uint16_t defaultPort=0)
Constructor.
Address m_local
Local address to bind to (address and port).
Ptr< Socket > m_socket
Socket (IPv4 or IPv6, depending on local address).
uint32_t m_port
Local port to bind to.
bool CloseAllSockets()
Close all the sockets.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
Traced Callback: received packets, source address.
Header used by web browsing applications to transmit information about content type,...
uint32_t GetSerializedSize() const override
void SetContentLength(uint32_t contentLength)
void SetContentType(ContentType_t contentType)
ContentType_t
The possible types of content (default = NOT_SET).
@ NOT_SET
Integer equivalent = 0.
@ EMBEDDED_OBJECT
Integer equivalent = 2.
@ MAIN_OBJECT
Integer equivalent = 1.
ContentType_t GetContentType() const
Model application which simulates the traffic of a web server.
static constexpr uint16_t HTTP_DEFAULT_PORT
default HTTP port
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.
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 DoStartApplication() override
Application specific startup code for child subclasses.
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_socket 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_socket 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.
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.
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 DoStopApplication() override
Application specific shutdown code for child subclasses.
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.
Definition nstime.h:96
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:409
@ S
second
Definition nstime.h:107
a unique identifier for an interface.
Definition type-id.h:49
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:872
@ ATTR_GET
The attribute can be read.
Definition type-id.h:54
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Definition type-id.h:65
Hold an unsigned integer type.
Definition uinteger.h:34
uint16_t port
Definition dsdv-manet.cc:33
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeChecker > MakeAddressChecker()
Definition address.cc:193
Ptr< const AttributeAccessor > MakeAddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition address.h:357
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:249
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:270
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#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.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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.
Definition log.h:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:439
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...
Definition callback.h:684
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.