21 #include "ns3/assert.h"
23 #include "ns3/nstime.h"
24 #include "ns3/boolean.h"
25 #include "ns3/object-vector.h"
27 #include "ns3/packet.h"
29 #include "ns3/simulator.h"
30 #include "ns3/ipv4-route.h"
31 #include "ns3/ipv6-route.h"
33 #include "tcp-l4-protocol.h"
34 #include "tcp-header.h"
35 #include "ipv4-end-point-demux.h"
36 #include "ipv6-end-point-demux.h"
37 #include "ipv4-end-point.h"
38 #include "ipv6-end-point.h"
39 #include "ipv4-l3-protocol.h"
40 #include "ipv6-l3-protocol.h"
41 #include "ipv6-routing-protocol.h"
42 #include "tcp-socket-factory-impl.h"
43 #include "tcp-newreno.h"
44 #include "rtt-estimator.h"
54 NS_OBJECT_ENSURE_REGISTERED (TcpL4Protocol);
58 #undef NS_LOG_APPEND_CONTEXT
59 #define NS_LOG_APPEND_CONTEXT \
60 if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
63 const uint8_t TcpL4Protocol::PROT_NUMBER = 6;
66 TcpL4Protocol::GetTypeId (
void)
68 static TypeId tid = TypeId (
"ns3::TcpL4Protocol")
69 .SetParent<IpL4Protocol> ()
70 .AddConstructor<TcpL4Protocol> ()
71 .AddAttribute (
"RttEstimatorType",
72 "Type of RttEstimator objects.",
73 TypeIdValue (RttMeanDeviation::GetTypeId ()),
74 MakeTypeIdAccessor (&TcpL4Protocol::m_rttTypeId),
76 .AddAttribute (
"SocketType",
77 "Socket type of TCP objects.",
78 TypeIdValue (TcpNewReno::GetTypeId ()),
79 MakeTypeIdAccessor (&TcpL4Protocol::m_socketTypeId),
81 .AddAttribute (
"SocketList",
"The list of sockets associated to this protocol.",
83 MakeObjectVectorAccessor (&TcpL4Protocol::m_sockets),
84 MakeObjectVectorChecker<TcpSocketBase> ())
96 TcpL4Protocol::~TcpL4Protocol ()
102 TcpL4Protocol::SetNode (Ptr<Node> node)
115 Ptr<Node> node = this->GetObject<Node> ();
116 Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
121 if ((node != 0) && (ipv4 != 0 || ipv6 != 0))
123 this->SetNode (node);
125 tcpFactory->SetTcp (
this);
135 if (ipv4 != 0 && m_downTarget.IsNull ())
140 if (ipv6 != 0 && m_downTarget6.IsNull ())
160 if (m_endPoints != 0)
166 if (m_endPoints6 != 0)
173 m_downTarget.Nullify ();
174 m_downTarget6.Nullify ();
189 socket->SetTcp (
this);
190 socket->SetRtt (rtt);
201 TcpL4Protocol::Allocate (
void)
204 return m_endPoints->Allocate ();
208 TcpL4Protocol::Allocate (Ipv4Address address)
211 return m_endPoints->Allocate (address);
215 TcpL4Protocol::Allocate (uint16_t port)
218 return m_endPoints->Allocate (port);
222 TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
225 return m_endPoints->Allocate (address, port);
229 TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
230 Ipv4Address peerAddress, uint16_t peerPort)
232 NS_LOG_FUNCTION (
this << localAddress << localPort << peerAddress << peerPort);
233 return m_endPoints->Allocate (localAddress, localPort,
234 peerAddress, peerPort);
238 TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
241 m_endPoints->DeAllocate (endPoint);
245 TcpL4Protocol::Allocate6 (
void)
252 TcpL4Protocol::Allocate6 (Ipv6Address address)
255 return m_endPoints6->
Allocate (address);
259 TcpL4Protocol::Allocate6 (uint16_t port)
262 return m_endPoints6->
Allocate (port);
266 TcpL4Protocol::Allocate6 (Ipv6Address address, uint16_t port)
269 return m_endPoints6->
Allocate (address, port);
273 TcpL4Protocol::Allocate6 (Ipv6Address localAddress, uint16_t localPort,
274 Ipv6Address peerAddress, uint16_t peerPort)
276 NS_LOG_FUNCTION (
this << localAddress << localPort << peerAddress << peerPort);
277 return m_endPoints6->
Allocate (localAddress, localPort,
278 peerAddress, peerPort);
282 TcpL4Protocol::DeAllocate (Ipv6EndPoint *endPoint)
290 uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
292 const uint8_t payload[8])
294 NS_LOG_FUNCTION (
this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
295 << payloadSource << payloadDestination);
297 src = payload[0] << 8;
299 dst = payload[2] << 8;
302 Ipv4EndPoint *endPoint = m_endPoints->SimpleLookup (payloadSource, src, payloadDestination, dst);
305 endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
309 NS_LOG_DEBUG (
"no endpoint found source=" << payloadSource <<
310 ", destination="<<payloadDestination<<
311 ", src=" << src <<
", dst=" << dst);
317 uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
319 const uint8_t payload[8])
321 NS_LOG_FUNCTION (
this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
322 << payloadSource << payloadDestination);
324 src = payload[0] << 8;
326 dst = payload[2] << 8;
332 endPoint->
ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
336 NS_LOG_DEBUG (
"no endpoint found source=" << payloadSource <<
337 ", destination="<<payloadDestination<<
338 ", src=" << src <<
", dst=" << dst);
342 enum IpL4Protocol::RxStatus
361 <<
" flags "<< std::hex << (int)tcpHeader.
GetFlags () << std::dec
362 <<
" data size " << packet->
GetSize ());
367 return IpL4Protocol::RX_CSUM_FAILED;
370 NS_LOG_LOGIC (
"TcpL4Protocol "<<
this<<
" received a packet");
371 Ipv4EndPointDemux::EndPoints endPoints =
374 if (endPoints.empty ())
376 if (this->GetObject<Ipv6L3Protocol> () != 0)
378 NS_LOG_LOGIC (
" No Ipv4 endpoints matched on TcpL4Protocol, trying Ipv6 "<<
this);
385 return (this->
Receive (packet, ipv6Header, fakeInterface));
388 NS_LOG_LOGIC (
" No endpoints matched on TcpL4Protocol "<<
this);
389 std::ostringstream oss;
390 oss<<
" destination IP: ";
397 if (!(tcpHeader.
GetFlags () & TcpHeader::RST))
402 if (tcpHeader.
GetFlags () & TcpHeader::ACK)
406 header.SetSequenceNumber (header.GetAckNumber ());
410 header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
417 return IpL4Protocol::RX_ENDPOINT_CLOSED;
421 return IpL4Protocol::RX_ENDPOINT_CLOSED;
424 NS_ASSERT_MSG (endPoints.size () == 1,
"Demux returned more than one endpoint");
425 NS_LOG_LOGIC (
"TcpL4Protocol "<<
this<<
" forwarding up to endpoint/socket");
426 (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.
GetSourcePort (),
428 return IpL4Protocol::RX_OK;
431 enum IpL4Protocol::RxStatus
453 <<
" receiving seq " << tcpHeader.GetSequenceNumber ()
454 <<
" ack " << tcpHeader.GetAckNumber ()
455 <<
" flags "<< std::hex << (int)tcpHeader.GetFlags () << std::dec
456 <<
" data size " << packet->
GetSize ());
458 if(!tcpHeader.IsChecksumOk ())
461 return IpL4Protocol::RX_CSUM_FAILED;
464 NS_LOG_LOGIC (
"TcpL4Protocol "<<
this<<
" received a packet");
465 Ipv6EndPointDemux::EndPoints endPoints =
468 if (endPoints.empty ())
470 NS_LOG_LOGIC (
" No IPv6 endpoints matched on TcpL4Protocol "<<
this);
471 std::ostringstream oss;
472 oss<<
" destination IP: ";
474 oss<<
" destination port: "<< tcpHeader.GetDestinationPort ()<<
" source IP: ";
476 oss<<
" source port: "<<tcpHeader.GetSourcePort ();
479 if (!(tcpHeader.GetFlags () & TcpHeader::RST))
482 Ptr<Packet> rstPacket = Create<Packet> ();
484 if (tcpHeader.GetFlags () & TcpHeader::ACK)
487 header.SetFlags (TcpHeader::RST);
488 header.SetSequenceNumber (header.GetAckNumber ());
492 header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
493 header.SetSequenceNumber (SequenceNumber32 (0));
494 header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
496 header.SetSourcePort (tcpHeader.GetDestinationPort ());
497 header.SetDestinationPort (tcpHeader.GetSourcePort ());
499 return IpL4Protocol::RX_ENDPOINT_CLOSED;
503 return IpL4Protocol::RX_ENDPOINT_CLOSED;
506 NS_ASSERT_MSG (endPoints.size () == 1,
"Demux returned more than one endpoint");
507 NS_LOG_LOGIC (
"TcpL4Protocol "<<
this<<
" forwarding up to endpoint/socket");
508 (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort ());
509 return IpL4Protocol::RX_OK;
517 NS_LOG_FUNCTION (
this << packet << saddr << daddr << sport << dport << oif);
529 tcpHeader.
SetFlags (TcpHeader::ACK);
540 Socket::SocketErrno errno_;
543 if (ipv4->GetRoutingProtocol () != 0)
545 route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
552 ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
561 NS_LOG_FUNCTION (
this << packet << saddr << daddr << sport << dport << oif);
573 tcpHeader.
SetFlags (TcpHeader::ACK);
578 Ptr<Ipv6L3Protocol> ipv6 = m_node->
GetObject<Ipv6L3Protocol> ();
582 header.SetDestinationAddress (daddr);
583 header.SetNextHeader (PROT_NUMBER);
584 Socket::SocketErrno errno_;
585 Ptr<Ipv6Route> route;
586 Ptr<NetDevice> oif (0);
587 if (ipv6->GetRoutingProtocol () != 0)
589 route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
596 ipv6->Send (packet, saddr, daddr, PROT_NUMBER, route);
601 TcpL4Protocol::SendPacket (Ptr<Packet> packet,
const TcpHeader &outgoing,
602 Ipv4Address saddr, Ipv4Address daddr, Ptr<NetDevice> oif)
605 <<
" sending seq " << outgoing.GetSequenceNumber ()
606 <<
" ack " << outgoing.GetAckNumber ()
607 <<
" flags " << std::hex << (int)outgoing.GetFlags () << std::dec
608 <<
" data size " << packet->GetSize ());
612 TcpHeader outgoingHeader = outgoing;
613 outgoingHeader.SetLength (5);
617 outgoingHeader.EnableChecksums ();
619 outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
621 packet->AddHeader (outgoingHeader);
628 header.SetDestination (daddr);
629 header.SetProtocol (PROT_NUMBER);
630 Socket::SocketErrno errno_;
631 Ptr<Ipv4Route> route;
632 if (ipv4->GetRoutingProtocol () != 0)
634 route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
641 m_downTarget (packet, saddr, daddr, PROT_NUMBER, route);
644 NS_FATAL_ERROR (
"Trying to use Tcp on a node without an Ipv4 interface");
648 TcpL4Protocol::SendPacket (Ptr<Packet> packet,
const TcpHeader &outgoing,
649 Ipv6Address saddr, Ipv6Address daddr, Ptr<NetDevice> oif)
652 <<
" sending seq " << outgoing.GetSequenceNumber ()
653 <<
" ack " << outgoing.GetAckNumber ()
654 <<
" flags " << std::hex << (int)outgoing.GetFlags () << std::dec
655 <<
" data size " << packet->GetSize ());
659 if (daddr.IsIpv4MappedAddress ())
661 return (SendPacket (packet, outgoing, saddr.GetIpv4MappedAddress(), daddr.GetIpv4MappedAddress(), oif));
663 TcpHeader outgoingHeader = outgoing;
664 outgoingHeader.SetLength (5);
668 outgoingHeader.EnableChecksums ();
670 outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
672 packet->AddHeader (outgoingHeader);
674 Ptr<Ipv6L3Protocol> ipv6 = m_node->
GetObject<Ipv6L3Protocol> ();
678 header.SetDestinationAddress (daddr);
679 header.SetSourceAddress (saddr);
680 header.SetNextHeader (PROT_NUMBER);
681 Socket::SocketErrno errno_;
682 Ptr<Ipv6Route> route;
683 if (ipv6->GetRoutingProtocol () != 0)
685 route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
692 m_downTarget6 (packet, saddr, daddr, PROT_NUMBER, route);
695 NS_FATAL_ERROR (
"Trying to use Tcp on a node without an Ipv6 interface");
701 m_downTarget = callback;
713 m_downTarget6 = callback;
716 IpL4Protocol::DownTargetCallback6
717 TcpL4Protocol::GetDownTarget6 (
void)
const
719 return m_downTarget6;
Ptr< Socket > CreateSocket(void)
#define NS_LOG_FUNCTION(parameters)
virtual void DoDispose(void)
void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers...
IPv6 layer implementation.
EndPoints Lookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport, Ptr< Ipv6Interface > incomingInterface)
lookup for a match with all the parameters.
static bool ChecksumEnabled(void)
void Send(Ptr< Packet > packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport, uint16_t dport, Ptr< NetDevice > oif=0)
Send a packet via TCP.
#define NS_LOG_COMPONENT_DEFINE(name)
virtual void ReceiveIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo, Ipv4Address payloadSource, Ipv4Address payloadDestination, const uint8_t payload[8])
Receive an ICMP packet.
void SetTypeId(TypeId tid)
uint32_t GetSize(void) const
virtual void DoDispose(void)
#define NS_LOG_FUNCTION_NOARGS()
#define NS_FATAL_ERROR(msg)
fatal error handling
virtual void NotifyNewAggregate()
Demultiplexes packets to various transport layer endpoints.
Ptr< Object > Create(void) const
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)
Receive a packet up the protocol stack.
TcpL4Protocol()
Constructor.
Base class for all RTT Estimators.
virtual IpL4Protocol::DownTargetCallback GetDownTarget(void) const
Ipv6EndPoint * Allocate(void)
Allocate a Ipv6EndPoint.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
void Print(std::ostream &os) const
Print this address to the given output stream.
A base class for implementation of a stream socket using TCP.
void AggregateObject(Ptr< Object > other)
#define NS_LOG_LOGIC(msg)
void DeAllocate(Ipv6EndPoint *endPoint)
Remove a end point.
virtual void NotifyNewAggregate(void)
Access to the Ipv4 forwarding table, interfaces, and configuration.
uint32_t PeekHeader(Header &header) const
virtual int GetProtocolNumber(void) const
virtual void SetNode(Ptr< Node > node)
Ipv6EndPoint * SimpleLookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
Simple lookup for a four-tuple match.
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
#define NS_ASSERT_MSG(condition, message)
Describes an IPv6 address.
instantiate subclasses of ns3::Object.
Ipv4 addresses are stored in host order in this class.
Demultiplexor for end points.
#define NS_LOG_DEBUG(msg)
An IPv6 end point, four tuples identification.
virtual void SetDownTarget(IpL4Protocol::DownTargetCallback cb)
void ForwardIcmp(Ipv6Address src, uint8_t ttl, uint8_t type, uint8_t code, uint32_t info)
Function called from an L4Protocol implementation to notify an endpoint of an icmp message reception...
#define NS_LOG_ERROR(msg)
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
Ptr< T > GetObject(void) const
a unique identifier for an interface.
void AddHeader(const Header &header)
A representation of an internet endpoint/connection.