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.