--- a/RELEASE_NOTES Fri Mar 23 23:51:29 2012 -0700
+++ b/RELEASE_NOTES Wed Mar 21 18:51:55 2012 +0100
@@ -32,6 +32,7 @@
- bug 1357 - IPv6 fragmentation fails due to checks about malformed extensions
- bug 1378 - UdpEchoClient::SetFill () does not set packet size correctly
- bug 1351 and 1333 - TCP not able to take RTT samples on long delay network
+ - bug 1362 - ICMPv6 does not forward ICMPs to upper layers (and minor fixes to ICMPv6)
Known issues
------------
--- a/src/internet/model/icmpv6-l4-protocol.cc Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/icmpv6-l4-protocol.cc Wed Mar 21 18:51:55 2012 +0100
@@ -18,6 +18,7 @@
* Author: Sebastien Vincent <[email protected]>
* David Gross <[email protected]>
* Mehdi Benamor <[email protected]>
+ * Tommaso Pecorella <[email protected]>
*/
#include "ns3/log.h"
@@ -34,8 +35,7 @@
#include "icmpv6-l4-protocol.h"
#include "ndisc-cache.h"
-namespace ns3
-{
+namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (Icmpv6L4Protocol);
@@ -97,7 +97,7 @@
cache = 0;
}
m_cacheList.clear ();
- m_downTarget.Nullify();
+ m_downTarget.Nullify ();
m_node = 0;
IpL4Protocol::DoDispose ();
@@ -114,11 +114,11 @@
Ptr<Ipv6L3Protocol> ipv6 = this->GetObject<Ipv6L3Protocol> ();
if (ipv6 != 0)
{
- this->SetNode (node);
+ SetNode (node);
ipv6->Insert (this);
Ptr<Ipv6RawSocketFactoryImpl> rawFactory = CreateObject<Ipv6RawSocketFactoryImpl> ();
ipv6->AggregateObject (rawFactory);
- this->SetDownTarget6 (MakeCallback (&Ipv6L3Protocol::Send, ipv6));
+ SetDownTarget6 (MakeCallback (&Ipv6L3Protocol::Send, ipv6));
}
}
}
@@ -162,9 +162,9 @@
NS_ASSERT (ipv6);
- if(!m_alwaysDad)
+ if (!m_alwaysDad)
{
- return;
+ return;
}
/* TODO : disable multicast loopback to prevent NS probing to be received by the sender */
@@ -192,7 +192,7 @@
uint8_t type;
p->CopyData (&type, sizeof(type));
- switch (type)
+ switch (type)
{
case Icmpv6Header::ICMPV6_ND_ROUTER_SOLICITATION:
if (ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())))
@@ -219,14 +219,21 @@
HandleEchoRequest (p, src, dst, interface);
break;
case Icmpv6Header::ICMPV6_ECHO_REPLY:
+ // EchoReply does not contain any info about L4
+ // so we can not forward it up.
+ // TODO: implement request / reply consistency check.
break;
case Icmpv6Header::ICMPV6_ERROR_DESTINATION_UNREACHABLE:
+ HandleDestinationUnreachable (p, src, dst, interface);
break;
case Icmpv6Header::ICMPV6_ERROR_PACKET_TOO_BIG:
+ HandlePacketTooBig (p, src, dst, interface);
break;
case Icmpv6Header::ICMPV6_ERROR_TIME_EXCEEDED:
+ HandleTimeExceeded (p, src, dst, interface);
break;
case Icmpv6Header::ICMPV6_ERROR_PARAMETER_ERROR:
+ HandleParameterError (p, src, dst, interface);
break;
default:
NS_LOG_LOGIC ("Unknown ICMPv6 message type=" << type);
@@ -236,6 +243,24 @@
return IpL4Protocol::RX_OK;
}
+void Icmpv6L4Protocol::Forward (Ipv6Address source, Icmpv6Header icmp,
+ uint32_t info, Ipv6Header ipHeader,
+ const uint8_t payload[8])
+{
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+
+ // TODO assuming the ICMP is carrying a extensionless IP packet
+
+ uint8_t nextHeader = ipHeader.GetNextHeader ();
+
+ Ptr<IpL4Protocol> l4 = ipv6->GetProtocol (nextHeader);
+ if (l4 != 0)
+ {
+ l4->ReceiveIcmp (source, ipHeader.GetHopLimit (), icmp.GetType (), icmp.GetCode (),
+ info, ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress (), payload);
+ }
+}
+
void Icmpv6L4Protocol::HandleEchoRequest (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
{
NS_LOG_FUNCTION (this << packet << src << dst << interface);
@@ -253,7 +278,7 @@
}
void Icmpv6L4Protocol::HandleRA (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
-{
+{
NS_LOG_FUNCTION (this << packet << src << dst << interface);
Ptr<Packet> p = packet->Copy ();
Icmpv6RA raHeader;
@@ -276,7 +301,7 @@
{
case Icmpv6Header::ICMPV6_OPT_PREFIX:
p->RemoveHeader (prefixHdr);
- ipv6->AddAutoconfiguredAddress (ipv6->GetInterfaceForDevice (interface->GetDevice ()), prefixHdr.GetPrefix (), prefixHdr.GetPrefixLength (),
+ ipv6->AddAutoconfiguredAddress (ipv6->GetInterfaceForDevice (interface->GetDevice ()), prefixHdr.GetPrefix (), prefixHdr.GetPrefixLength (),
prefixHdr.GetFlags (), prefixHdr.GetValidTime (), prefixHdr.GetPreferredTime (), src);
break;
case Icmpv6Header::ICMPV6_OPT_MTU:
@@ -312,7 +337,7 @@
NdiscCache::Entry* entry = 0;
Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
- /* check if we have this address in our cache */
+ /* check if we have this address in our cache */
entry = cache->Lookup (src);
if (!entry)
@@ -329,11 +354,11 @@
if (entry->IsIncomplete ())
{
entry->StopRetransmitTimer ();
- // mark it to reachable
+ // mark it to reachable
waiting = entry->MarkReachable (lla.GetAddress ());
entry->StopReachableTimer ();
entry->StartReachableTimer ();
- // send out waiting packet
+ // send out waiting packet
for (std::list<Ptr<Packet> >::const_iterator it = waiting.begin (); it != waiting.end (); it++)
{
cache->GetInterface ()->Send (*it, src);
@@ -342,7 +367,7 @@
}
else
{
- if (entry->GetMacAddress ()!=lla.GetAddress ())
+ if (entry->GetMacAddress () != lla.GetAddress ())
{
entry->SetMacAddress (lla.GetAddress ());
entry->MarkStale ();
@@ -497,7 +522,7 @@
hardwareAddress = interface->GetDevice ()->GetAddress ();
Ptr<Packet> p = ForgeNA (target.IsLinkLocal () ? interface->GetLinkLocalAddress ().GetAddress () : ifaddr.GetAddress (), src.IsAny () ? Ipv6Address::GetAllNodesMulticast () : src, &hardwareAddress, flags );
- interface->Send (p, src.IsAny () ? Ipv6Address::GetAllNodesMulticast () : src);
+ interface->Send (p, src.IsAny () ? Ipv6Address::GetAllNodesMulticast () : src);
/* not a NS for us discard it */
}
@@ -633,7 +658,7 @@
entry->StopDelayTimer ();
/* if the Flag O is clear and mac address differs from the cache */
- if (!naHeader.GetFlagO () && lla.GetAddress ()!=entry->GetMacAddress ())
+ if (!naHeader.GetFlagO () && lla.GetAddress () != entry->GetMacAddress ())
{
if (entry->IsReachable ())
{
@@ -656,7 +681,7 @@
waiting = entry->MarkReachable (lla.GetAddress ());
for (std::list<Ptr<Packet> >::const_iterator it = waiting.begin (); it != waiting.end (); it++)
{
- cache->GetInterface ()->Send (*it, src);
+ cache->GetInterface ()->Send (*it, src);
}
entry->ClearWaitingPacket ();
}
@@ -668,7 +693,7 @@
entry->StopReachableTimer ();
entry->StartReachableTimer ();
}
- else if (lla.GetAddress ()!=entry->GetMacAddress ())
+ else if (lla.GetAddress () != entry->GetMacAddress ())
{
entry->MarkStale ();
}
@@ -723,7 +748,7 @@
if (entry->IsIncomplete () || entry->GetMacAddress () != llOptionHeader.GetAddress ())
{
/* update entry to STALE */
- if (entry->GetMacAddress ()!=llOptionHeader.GetAddress ())
+ if (entry->GetMacAddress () != llOptionHeader.GetAddress ())
{
entry->SetMacAddress (llOptionHeader.GetAddress ());
entry->MarkStale ();
@@ -750,6 +775,73 @@
}
}
+void Icmpv6L4Protocol::HandleDestinationUnreachable (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << *p << src << dst);
+ Ptr<Packet> pkt = p->Copy ();
+
+ Icmpv6DestinationUnreachable unreach;
+ pkt->RemoveHeader (unreach);
+ Ptr<Packet> origPkt = unreach.GetPacket ();
+
+ Ipv6Header ipHeader;
+ if ( origPkt->GetSerializedSize () > ipHeader.GetSerializedSize () )
+ {
+ origPkt->RemoveHeader (ipHeader);
+ uint8_t payload[8];
+ origPkt->CopyData (payload, 8);
+ Forward (src, unreach, unreach.GetCode (), ipHeader, payload);
+ }
+}
+
+void Icmpv6L4Protocol::HandleTimeExceeded (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << *p << src << dst);
+ Ptr<Packet> pkt = p->Copy ();
+
+ Icmpv6TimeExceeded timeexceeded;
+ pkt->RemoveHeader (timeexceeded);
+ Ptr<Packet> origPkt = timeexceeded.GetPacket ();
+ Ipv6Header ipHeader;
+ uint8_t payload[8];
+ origPkt->RemoveHeader (ipHeader);
+ origPkt->CopyData (payload, 8);
+
+ Forward (src, timeexceeded, timeexceeded.GetCode (), ipHeader, payload);
+}
+
+void Icmpv6L4Protocol::HandlePacketTooBig (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << *p << src << dst);
+ Ptr<Packet> pkt = p->Copy ();
+
+ Icmpv6TooBig tooBig;
+ pkt->RemoveHeader (tooBig);
+ Ptr<Packet> origPkt = tooBig.GetPacket ();
+
+ Ipv6Header ipHeader;
+ origPkt->RemoveHeader (ipHeader);
+ uint8_t payload[8];
+ origPkt->CopyData (payload, 8);
+ Forward (src, tooBig, tooBig.GetMtu (), ipHeader, payload);
+}
+
+void Icmpv6L4Protocol::HandleParameterError (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << *p << src << dst);
+ Ptr<Packet> pkt = p->Copy ();
+
+ Icmpv6ParameterError paramErr;
+ pkt->RemoveHeader (paramErr);
+ Ptr<Packet> origPkt = paramErr.GetPacket ();
+
+ Ipv6Header ipHeader;
+ origPkt->RemoveHeader (ipHeader);
+ uint8_t payload[8];
+ origPkt->CopyData (payload, 8);
+ Forward (src, paramErr, paramErr.GetCode (), ipHeader, payload);
+}
+
void Icmpv6L4Protocol::SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
{
NS_LOG_FUNCTION (this << packet << src << dst << (uint32_t)ttl);
@@ -851,7 +943,7 @@
dst = Ipv6Address::GetAllNodesMulticast ();
}
- NS_LOG_LOGIC ("Send NS ( from " << src << " to " << dst << " target " << target <<")");
+ NS_LOG_LOGIC ("Send NS ( from " << src << " to " << dst << " target " << target << ")");
p->AddHeader (llOption);
ns.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + ns.GetSerializedSize (), PROT_NUMBER);
@@ -930,7 +1022,7 @@
void Icmpv6L4Protocol::SendErrorTimeExceeded (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code)
{
- NS_LOG_FUNCTION (this<< malformedPacket << dst << code);
+ NS_LOG_FUNCTION (this << malformedPacket << dst << code);
Ptr<Packet> p = Create<Packet> ();
uint32_t malformedPacketSize = malformedPacket->GetSize ();
Icmpv6TimeExceeded header;
@@ -938,7 +1030,7 @@
NS_LOG_LOGIC ("Send Time Exceeded ( to " << dst << " code " << (uint32_t)code << " )");
/* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
- if (malformedPacketSize <= 1280 - 48)
+ if (malformedPacketSize <= 1280 - 48)
{
header.SetPacket (malformedPacket);
}
@@ -962,7 +1054,7 @@
NS_LOG_LOGIC ("Send Parameter Error ( to " << dst << " code " << (uint32_t)code << " )");
/* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
- if (malformedPacketSize <= 1280 -48 )
+ if (malformedPacketSize <= 1280 - 48 )
{
header.SetPacket (malformedPacket);
}
@@ -992,7 +1084,7 @@
if ((redirectedPacketSize % 8) != 0)
{
Ptr<Packet> pad = Create<Packet> (8 - (redirectedPacketSize % 8));
- redirectedPacket->AddAtEnd (pad);
+ redirectedPacket->AddAtEnd (pad);
}
if (redirHardwareTarget.GetLength ())
@@ -1081,7 +1173,7 @@
dst = Ipv6Address::GetAllNodesMulticast ();
}
- NS_LOG_LOGIC ("Send NS ( from " << src << " to " << dst << " target " << target <<")");
+ NS_LOG_LOGIC ("Send NS ( from " << src << " to " << dst << " target " << target << ")");
p->AddHeader (llOption);
ns.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + ns.GetSerializedSize (), PROT_NUMBER);
@@ -1196,7 +1288,7 @@
else
{
/* find source address that match destination */
- addr = cache->GetInterface ()->GetAddressMatchingDestination (dst).GetAddress ();
+ addr = cache->GetInterface ()->GetAddressMatchingDestination (dst).GetAddress ();
}
SendNS (addr, Ipv6Address::MakeSolicitedAddress (dst), dst, cache->GetDevice ()->GetAddress ());
@@ -1229,7 +1321,7 @@
}
}
- /* for the moment, this function is always called, if we was victim of a DAD the address is INVALID
+ /* for the moment, this function is always called, if we was victim of a DAD the address is INVALID
* and we do not set it to PREFERRED
*/
if (found && ifaddr.GetState () != Ipv6InterfaceAddress::INVALID)
@@ -1242,9 +1334,9 @@
*/
Ptr<Ipv6> ipv6 = icmpv6->m_node->GetObject<Ipv6> ();
- if (!ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())) && addr.IsLinkLocal ())
+ if (!ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())) && addr.IsLinkLocal ())
{
- /* XXX because all nodes start at the same time, there will be many of RS arround 1 second of simulation time
+ /* XXX because all nodes start at the same time, there will be many of RS arround 1 second of simulation time
* TODO Add random delays before sending RS
*/
Simulator::Schedule (Seconds (0.0), &Icmpv6L4Protocol::SendRS, PeekPointer (icmpv6), ifaddr.GetAddress (), Ipv6Address::GetAllRoutersMulticast (), interface->GetDevice ()->GetAddress ());
--- a/src/internet/model/icmpv6-l4-protocol.h Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/icmpv6-l4-protocol.h Wed Mar 21 18:51:55 2012 +0100
@@ -29,8 +29,7 @@
#include "icmpv6-header.h"
#include "ip-l4-protocol.h"
-namespace ns3
-{
+namespace ns3 {
class NetDevice;
class Node;
@@ -194,7 +193,7 @@
* \brief Send a packet via ICMPv6.
* \param packet the packet to send
* \param dst destination address
- * \param icmpv6Hdr ICMPv6 header (needed to calculate checksum
+ * \param icmpv6Hdr ICMPv6 header (needed to calculate checksum
* after source address is determined by routing stuff
* \param ttl next hop limit
*/
@@ -202,8 +201,8 @@
/**
* \brief Do the Duplication Address Detection (DAD).
- * It consists in sending a NS with our IPv6 as target. If
- * we received a NA with matched target address, we could not use
+ * It consists in sending a NS with our IPv6 as target. If
+ * we received a NA with matched target address, we could not use
* the address, else the address pass from TENTATIVE to PERMANENT.
*
* \param target target address
@@ -325,13 +324,20 @@
/**
* \brief Receive method.
* \param p the packet
- * \param src source address
- * \param dst destination address
+ * \param header the IPv4 header
* \param interface the interface from which the packet is coming
*/
virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
Ipv4Header const &header,
Ptr<Ipv4Interface> interface);
+
+ /**
+ * \brief Receive method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
Ipv6Address &src, Ipv6Address &dst,
Ptr<Ipv6Interface> interface);
@@ -396,7 +402,6 @@
virtual void DoDispose ();
private:
-
typedef std::list<Ptr<NdiscCache> > CacheList;
/**
@@ -415,6 +420,18 @@
bool m_alwaysDad;
/**
+ * \brief Notify an ICMPv6 reception to upper layers (if requested).
+ * \param source the ICMP source
+ * \param icmp the ICMP header
+ * \param info information about the ICMP
+ * \param ipHeader the IP header carried by the ICMP
+ * \param payload the data carried by the ICMP
+ */
+ void Forward (Ipv6Address source, Icmpv6Header icmp,
+ uint32_t info, Ipv6Header ipHeader,
+ const uint8_t payload[8]);
+
+ /**
* \brief Receive Neighbor Solicitation method.
* \param p the packet
* \param src source address
@@ -469,6 +486,42 @@
void HandleRedirection (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
/**
+ * \brief Receive Destination Unreachable method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleDestinationUnreachable (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Receive Time Exceeded method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleTimeExceeded (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Receive Packet Too Big method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandlePacketTooBig (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Receive Parameter Error method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleParameterError (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
* \brief Link layer address option processing.
* \param lla LLA option
* \param src source address
--- a/src/internet/model/ipv6-end-point-demux.cc Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-end-point-demux.cc Wed Mar 21 18:51:55 2012 +0100
@@ -22,13 +22,14 @@
#include "ipv6-end-point.h"
#include "ns3/log.h"
-namespace ns3
-{
+namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("Ipv6EndPointDemux");
Ipv6EndPointDemux::Ipv6EndPointDemux ()
- : m_ephemeral (49152)
+ : m_ephemeral (49152),
+ m_portFirst (49152),
+ m_portLast (65535)
{
NS_LOG_FUNCTION_NOARGS ();
}
@@ -36,7 +37,7 @@
Ipv6EndPointDemux::~Ipv6EndPointDemux ()
{
NS_LOG_FUNCTION_NOARGS ();
- for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
Ipv6EndPoint *endPoint = *i;
delete endPoint;
@@ -47,9 +48,9 @@
bool Ipv6EndPointDemux::LookupPortLocal (uint16_t port)
{
NS_LOG_FUNCTION (this << port);
- for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
- if ((*i)->GetLocalPort () == port)
+ if ((*i)->GetLocalPort () == port)
{
return true;
}
@@ -60,10 +61,10 @@
bool Ipv6EndPointDemux::LookupLocal (Ipv6Address addr, uint16_t port)
{
NS_LOG_FUNCTION (this << addr << port);
- for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
- if ((*i)->GetLocalPort () == port &&
- (*i)->GetLocalAddress () == addr)
+ if ((*i)->GetLocalPort () == port
+ && (*i)->GetLocalAddress () == addr)
{
return true;
}
@@ -75,7 +76,7 @@
{
NS_LOG_FUNCTION_NOARGS ();
uint16_t port = AllocateEphemeralPort ();
- if (port == 0)
+ if (port == 0)
{
NS_LOG_WARN ("Ephemeral port allocation failed.");
return 0;
@@ -90,7 +91,7 @@
{
NS_LOG_FUNCTION (this << address);
uint16_t port = AllocateEphemeralPort ();
- if (port == 0)
+ if (port == 0)
{
NS_LOG_WARN ("Ephemeral port allocation failed.");
return 0;
@@ -111,7 +112,7 @@
Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address address, uint16_t port)
{
NS_LOG_FUNCTION (this << address << port);
- if (LookupLocal (address, port))
+ if (LookupLocal (address, port))
{
NS_LOG_WARN ("Duplicate address/port; failing.");
return 0;
@@ -126,12 +127,12 @@
Ipv6Address peerAddress, uint16_t peerPort)
{
NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
- for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
- if ((*i)->GetLocalPort () == localPort &&
- (*i)->GetLocalAddress () == localAddress &&
- (*i)->GetPeerPort () == peerPort &&
- (*i)->GetPeerAddress () == peerAddress)
+ if ((*i)->GetLocalPort () == localPort
+ && (*i)->GetLocalAddress () == localAddress
+ && (*i)->GetPeerPort () == peerPort
+ && (*i)->GetPeerAddress () == peerAddress)
{
NS_LOG_WARN ("No way we can allocate this end-point.");
/* no way we can allocate this end-point. */
@@ -150,7 +151,7 @@
void Ipv6EndPointDemux::DeAllocate (Ipv6EndPoint *endPoint)
{
NS_LOG_FUNCTION_NOARGS ();
- for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
if (*i == endPoint)
{
@@ -166,7 +167,7 @@
* Otherwise, if we find a generic match, we return it.
* Otherwise, we return 0.
*/
-Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::Lookup (Ipv6Address daddr, uint16_t dport,
+Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::Lookup (Ipv6Address daddr, uint16_t dport,
Ipv6Address saddr, uint16_t sport,
Ptr<Ipv6Interface> incomingInterface)
{
@@ -178,14 +179,14 @@
EndPoints retval4; /* Exact match on all 4 */
NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
- for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
Ipv6EndPoint* endP = *i;
NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
<< " daddr=" << endP->GetLocalAddress ()
<< " sport=" << endP->GetPeerPort ()
<< " saddr=" << endP->GetPeerAddress ());
- if (endP->GetLocalPort () != dport)
+ if (endP->GetLocalPort () != dport)
{
NS_LOG_LOGIC ("Skipping endpoint " << &endP
<< " because endpoint dport "
@@ -203,7 +204,9 @@
/* if no match here, keep looking */
if (!(localAddressMatchesExact || localAddressMatchesWildCard))
- continue;
+ {
+ continue;
+ }
bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
bool remotePeerMatchesWildCard = endP->GetPeerPort () == 0;
bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
@@ -212,41 +215,54 @@
/* If remote does not match either with exact or wildcard,i
skip this one */
if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
- continue;
+ {
+ continue;
+ }
if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
- continue;
+ {
+ continue;
+ }
/* Now figure out which return list to add this one to */
- if (localAddressMatchesWildCard &&
- remotePeerMatchesWildCard &&
- remoteAddressMatchesWildCard)
+ if (localAddressMatchesWildCard
+ && remotePeerMatchesWildCard
+ && remoteAddressMatchesWildCard)
{ /* Only local port matches exactly */
retval1.push_back (endP);
}
- if ((localAddressMatchesExact || (localAddressMatchesAllRouters))&&
- remotePeerMatchesWildCard &&
- remoteAddressMatchesWildCard)
+ if ((localAddressMatchesExact || (localAddressMatchesAllRouters))
+ && remotePeerMatchesWildCard
+ && remoteAddressMatchesWildCard)
{ /* Only local port and local address matches exactly */
retval2.push_back (endP);
}
- if (localAddressMatchesWildCard &&
- remotePeerMatchesExact &&
- remoteAddressMatchesExact)
+ if (localAddressMatchesWildCard
+ && remotePeerMatchesExact
+ && remoteAddressMatchesExact)
{ /* All but local address */
retval3.push_back (endP);
}
- if (localAddressMatchesExact &&
- remotePeerMatchesExact &&
- remoteAddressMatchesExact)
+ if (localAddressMatchesExact
+ && remotePeerMatchesExact
+ && remoteAddressMatchesExact)
{ /* All 4 match */
retval4.push_back (endP);
}
}
/* Here we find the most exact match */
- if (!retval4.empty ()) return retval4;
- if (!retval3.empty ()) return retval3;
- if (!retval2.empty ()) return retval2;
+ if (!retval4.empty ())
+ {
+ return retval4;
+ }
+ if (!retval3.empty ())
+ {
+ return retval3;
+ }
+ if (!retval2.empty ())
+ {
+ return retval2;
+ }
return retval1; /* might be empty if no matches */
}
@@ -264,8 +280,8 @@
continue;
}
- if ((*i)->GetLocalAddress () == dst && (*i)->GetPeerPort () == sport &&
- (*i)->GetPeerAddress () == src)
+ if ((*i)->GetLocalAddress () == dst && (*i)->GetPeerPort () == sport
+ && (*i)->GetPeerAddress () == src)
{
/* this is an exact match. */
return *i;
@@ -294,19 +310,22 @@
{
NS_LOG_FUNCTION_NOARGS ();
uint16_t port = m_ephemeral;
- do
+ int count = m_portLast - m_portFirst;
+ do
{
- port++;
- if (port == 65535)
+ if (count-- < 0)
{
- port = 49152;
+ return 0;
}
- if (!LookupPortLocal (port))
+ ++port;
+ if (port < m_portFirst || port > m_portLast)
{
- return port;
+ port = m_portFirst;
}
- } while (port != m_ephemeral);
- return 0;
+ }
+ while (LookupPortLocal (port));
+ m_ephemeral = port;
+ return port;
}
Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::GetEndPoints () const
--- a/src/internet/model/ipv6-end-point-demux.h Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-end-point-demux.h Wed Mar 21 18:51:55 2012 +0100
@@ -26,8 +26,7 @@
#include "ns3/ipv6-address.h"
#include "ipv6-interface.h"
-namespace ns3
-{
+namespace ns3 {
class Ipv6EndPoint;
@@ -91,21 +90,21 @@
* \brief Allocate a Ipv6EndPoint.
* \return an empty Ipv6EndPoint instance
*/
- Ipv6EndPoint *Allocate (void);
+ Ipv6EndPoint * Allocate (void);
/**
* \brief Allocate a Ipv6EndPoint.
* \param address IPv6 address
* \return an Ipv6EndPoint instance
*/
- Ipv6EndPoint *Allocate (Ipv6Address address);
+ Ipv6EndPoint * Allocate (Ipv6Address address);
/**
* \brief Allocate a Ipv6EndPoint.
* \param port local port
* \return an Ipv6EndPoint instance
*/
- Ipv6EndPoint *Allocate (uint16_t port);
+ Ipv6EndPoint * Allocate (uint16_t port);
/**
* \brief Allocate a Ipv6EndPoint.
@@ -113,7 +112,7 @@
* \param port local port
* \return an Ipv6EndPoint instance
*/
- Ipv6EndPoint *Allocate (Ipv6Address address, uint16_t port);
+ Ipv6EndPoint * Allocate (Ipv6Address address, uint16_t port);
/**
* \brief Allocate a Ipv6EndPoint.
@@ -123,7 +122,7 @@
* \param peerPort peer port
* \return an Ipv6EndPoint instance
*/
- Ipv6EndPoint *Allocate (Ipv6Address localAddress, uint16_t localPort, Ipv6Address peerAddress, uint16_t peerPort);
+ Ipv6EndPoint * Allocate (Ipv6Address localAddress, uint16_t localPort, Ipv6Address peerAddress, uint16_t peerPort);
/**
* \brief Remove a end point.
@@ -150,6 +149,16 @@
uint16_t m_ephemeral;
/**
+ * \brief The first ephemeral port.
+ */
+ uint16_t m_portFirst;
+
+ /**
+ * \brief The last ephemeral port.
+ */
+ uint16_t m_portLast;
+
+ /**
* \brief A list of IPv6 end points.
*/
EndPoints m_endPoints;
--- a/src/internet/model/ipv6-extension.cc Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-extension.cc Wed Mar 21 18:51:55 2012 +0100
@@ -43,8 +43,7 @@
NS_LOG_COMPONENT_DEFINE ("Ipv6Extension");
-namespace ns3
-{
+namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (Ipv6Extension);
@@ -338,14 +337,17 @@
std::pair<Ipv6Address, uint32_t> fragmentsId = std::make_pair<Ipv6Address, uint32_t> (src, identification);
Ptr<Fragments> fragments;
+ Ipv6Header ipHeader = ipv6Header;
+ ipHeader.SetNextHeader (fragmentHeader.GetNextHeader ());
+
MapFragments_t::iterator it = m_fragments.find (fragmentsId);
if (it == m_fragments.end ())
{
fragments = Create<Fragments> ();
m_fragments.insert (std::make_pair (fragmentsId, fragments));
- EventId timeout = Simulator::Schedule (Seconds(60),
+ EventId timeout = Simulator::Schedule (Seconds (60),
&Ipv6ExtensionFragment::HandleFragmentsTimeout, this,
- fragmentsId, fragments, ipv6Header);
+ fragmentsId, fragments, ipHeader);
fragments->SetTimeoutEventId (timeout);
}
else
@@ -365,11 +367,11 @@
if (fragments->IsEntire ())
{
packet = fragments->GetPacket ();
- fragments->CancelTimeout();
- m_fragments.erase(fragmentsId);
+ fragments->CancelTimeout ();
+ m_fragments.erase (fragmentsId);
isDropped = false;
}
- else
+ else
{
// the fragment is not "dropped", but Ipv6L3Protocol::LocalDeliver must stop processing it.
isDropped = true;
@@ -406,9 +408,9 @@
Ptr<Ipv6Extension> extension = extensionDemux->GetExtension (nextHeader);
uint8_t extensionHeaderLength;
- while (moreHeader)
+ while (moreHeader)
{
- if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+ if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
{
Ipv6ExtensionHopByHopHeader *hopbyhopHeader = new Ipv6ExtensionHopByHopHeader ();
p->RemoveHeader (*hopbyhopHeader);
@@ -429,7 +431,7 @@
unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP));
unfragmentablePartSize += extensionHeaderLength;
}
- else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
+ else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
{
uint8_t buf[2];
p->CopyData (buf, sizeof(buf));
@@ -453,7 +455,7 @@
unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (routingHeader, Ipv6Header::IPV6_EXT_ROUTING));
unfragmentablePartSize += extensionHeaderLength;
}
- else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
+ else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
{
Ipv6ExtensionDestinationHeader *destinationHeader = new Ipv6ExtensionDestinationHeader ();
p->RemoveHeader (*destinationHeader);
@@ -463,7 +465,7 @@
uint8_t type;
p->CopyData (&type, sizeof(type));
- if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
+ if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
|| (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
{
moreHeader = false;
@@ -486,14 +488,14 @@
uint32_t identification = (uint32_t) uvar.GetValue (0, (uint32_t)-1);
uint16_t offset = 0;
- do
+ do
{
if (p->GetSize () > offset + maxFragmentablePartSize)
{
moreFragment = true;
currentFragmentablePartSize = maxFragmentablePartSize;
}
- else
+ else
{
moreFragment = false;
currentFragmentablePartSize = p->GetSize () - offset;
@@ -516,15 +518,15 @@
{
if (it->second == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
{
- fragment->AddHeader (*dynamic_cast<Ipv6ExtensionHopByHopHeader *>(it->first));
+ fragment->AddHeader (*dynamic_cast<Ipv6ExtensionHopByHopHeader *> (it->first));
}
else if (it->second == Ipv6Header::IPV6_EXT_ROUTING)
{
- fragment->AddHeader (*dynamic_cast<Ipv6ExtensionLooseRoutingHeader *>(it->first));
+ fragment->AddHeader (*dynamic_cast<Ipv6ExtensionLooseRoutingHeader *> (it->first));
}
else if (it->second == Ipv6Header::IPV6_EXT_DESTINATION)
{
- fragment->AddHeader (*dynamic_cast<Ipv6ExtensionDestinationHeader *>(it->first));
+ fragment->AddHeader (*dynamic_cast<Ipv6ExtensionDestinationHeader *> (it->first));
}
}
@@ -534,7 +536,8 @@
std::ostringstream oss;
fragment->Print (oss);
listFragments.push_back (fragment);
- } while (moreFragment);
+ }
+ while (moreFragment);
for (std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
{
@@ -549,17 +552,19 @@
{
Ptr<Packet> packet = fragments->GetPartialPacket ();
+ packet->AddHeader (ipHeader);
+
// if we have at least 8 bytes, we can send an ICMP.
if ( packet->GetSize () > 8 )
{
- Ptr<Icmpv6L4Protocol> icmp = GetNode()->GetObject<Icmpv6L4Protocol> ();
+ Ptr<Icmpv6L4Protocol> icmp = GetNode ()->GetObject<Icmpv6L4Protocol> ();
icmp->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_FRAGTIME);
}
m_dropTrace (packet);
// clear the buffers
- m_fragments.erase(fragmentsId);
+ m_fragments.erase (fragmentsId);
}
Ipv6ExtensionFragment::Fragments::Fragments ()
@@ -591,7 +596,7 @@
m_fragments.insert (it, std::make_pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
}
-void Ipv6ExtensionFragment::Fragments::SetUnfragmentablePart (Ptr<Packet> unfragmentablePart)
+void Ipv6ExtensionFragment::Fragments::SetUnfragmentablePart (Ptr<Packet> unfragmentablePart)
{
m_unfragmentable = unfragmentablePart;
}
@@ -661,14 +666,14 @@
void Ipv6ExtensionFragment::Fragments::SetTimeoutEventId (EventId event)
{
- m_timeoutEventId = event;
- return;
+ m_timeoutEventId = event;
+ return;
}
-void Ipv6ExtensionFragment::Fragments::CancelTimeout()
+void Ipv6ExtensionFragment::Fragments::CancelTimeout ()
{
- m_timeoutEventId.Cancel ();
- return;
+ m_timeoutEventId.Cancel ();
+ return;
}
@@ -727,7 +732,7 @@
if (nextHeader)
{
- *nextHeader = routingNextHeader;
+ *nextHeader = routingNextHeader;
}
Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
@@ -918,7 +923,7 @@
nextAddressIndex = nbAddress - segmentsLeft;
nextAddress = routingHeader.GetRouterAddress (nextAddressIndex);
- if (nextAddress.IsMulticast () || destAddress.IsMulticast ())
+ if (nextAddress.IsMulticast () || destAddress.IsMulticast ())
{
m_dropTrace (packet);
isDropped = true;
@@ -941,10 +946,10 @@
ipv6header.SetHopLimit (hopLimit - 1);
p->AddHeader (routingHeader);
- /* short-circuiting routing stuff
- *
+ /* short-circuiting routing stuff
+ *
* If we process this option,
- * the packet was for us so we resend it to
+ * the packet was for us so we resend it to
* the new destination (modified in the header above).
*/
@@ -966,7 +971,7 @@
}
/* as we directly send packet, mark it as dropped */
- isDropped = true;
+ isDropped = true;
return routingHeader.GetSerializedSize ();
}
--- a/src/internet/model/ipv6-extension.h Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-extension.h Wed Mar 21 18:51:55 2012 +0100
@@ -35,8 +35,7 @@
#include "ns3/traced-callback.h"
-namespace ns3
-{
+namespace ns3 {
/**
* \class Ipv6Extension
@@ -309,7 +308,7 @@
/**
* \brief If all fragments have been added.
- * \returns true if the packet is entire
+ * \returns true if the packet is entire
*/
bool IsEntire () const;
--- a/src/internet/model/ipv6-l3-protocol.cc Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-l3-protocol.cc Wed Mar 21 18:51:55 2012 +0100
@@ -41,8 +41,7 @@
#include "icmpv6-l4-protocol.h"
#include "ndisc-cache.h"
-namespace ns3
-{
+namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (Ipv6L3Protocol);
@@ -130,7 +129,7 @@
m_routingProtocol->SetIpv6 (this);
}
-Ptr<Ipv6RoutingProtocol> Ipv6L3Protocol::GetRoutingProtocol () const
+Ptr<Ipv6RoutingProtocol> Ipv6L3Protocol::GetRoutingProtocol () const
{
NS_LOG_FUNCTION_NOARGS ();
return m_routingProtocol;
@@ -175,7 +174,7 @@
return 0;
}
-uint32_t Ipv6L3Protocol::GetNInterfaces () const
+uint32_t Ipv6L3Protocol::GetNInterfaces () const
{
NS_LOG_FUNCTION_NOARGS ();
return m_nInterfaces;
@@ -183,7 +182,7 @@
int32_t Ipv6L3Protocol::GetInterfaceForAddress (Ipv6Address address) const
{
- NS_LOG_FUNCTION (this << address);
+ NS_LOG_FUNCTION (this << address);
int32_t index = 0;
for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
@@ -193,7 +192,7 @@
for (j = 0; j < max; j++)
{
- if ((*it)->GetAddress (j).GetAddress () == address)
+ if ((*it)->GetAddress (j).GetAddress () == address)
{
return index;
}
@@ -252,7 +251,7 @@
Address addr = GetInterface (interface)->GetDevice ()->GetAddress ();
- if (flags & (1<< 6)) /* auto flag */
+ if (flags & (1 << 6)) /* auto flag */
{
/* XXX : add other L2 address case */
if (Mac48Address::IsMatchingType (addr))
@@ -282,7 +281,7 @@
AddAddress (interface, address);
/* add default router
- * if a previous default route exists, the new ones is simply added
+ * if a previous default route exists, the new ones is simply added
*/
GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
@@ -304,7 +303,7 @@
for (i = 0; i < max; i++)
{
- if (iface->GetAddress (i).GetAddress () == toFound)
+ if (iface->GetAddress (i).GetAddress () == toFound)
{
RemoveAddress (interface, i);
break;
@@ -369,14 +368,14 @@
return false;
}
-void Ipv6L3Protocol::SetMetric (uint32_t i, uint16_t metric)
+void Ipv6L3Protocol::SetMetric (uint32_t i, uint16_t metric)
{
NS_LOG_FUNCTION (this << i << metric);
Ptr<Ipv6Interface> interface = GetInterface (i);
interface->SetMetric (metric);
}
-uint16_t Ipv6L3Protocol::GetMetric (uint32_t i) const
+uint16_t Ipv6L3Protocol::GetMetric (uint32_t i) const
{
NS_LOG_FUNCTION (this << i);
Ptr<Ipv6Interface> interface = GetInterface (i);
@@ -635,12 +634,12 @@
hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl);
//for link-local traffic, we need to determine the interface
- if (source.IsLinkLocal () ||
- destination.IsLinkLocal () ||
- destination.IsAllNodesMulticast () ||
- destination.IsAllRoutersMulticast () ||
- destination.IsAllHostsMulticast () ||
- destination.IsSolicitedMulticast ())
+ if (source.IsLinkLocal ()
+ || destination.IsLinkLocal ()
+ || destination.IsAllNodesMulticast ()
+ || destination.IsAllRoutersMulticast ()
+ || destination.IsAllHostsMulticast ()
+ || destination.IsSolicitedMulticast ())
{
int32_t index = GetInterfaceForAddress (source);
NS_ASSERT (index >= 0);
@@ -707,7 +706,7 @@
socket->ForwardUp (packet, hdr, device);
}
- Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
+ Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
Ptr<Ipv6Extension> ipv6Extension = 0;
uint8_t nextHeader = hdr.GetNextHeader ();
bool isDropped = false;
@@ -763,6 +762,12 @@
// Router => drop
if (m_ipForward)
{
+ Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
+ if ( icmpv6 )
+ {
+ packet->AddHeader(ipHeader);
+ icmpv6->SendErrorTooBig (packet, ipHeader.GetSourceAddress (), dev->GetMtu ());
+ }
return;
}
@@ -771,7 +776,7 @@
packet->AddHeader (ipHeader);
// To get specific method GetFragments from Ipv6ExtensionFragmentation
- Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *>(PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
+ Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *> (PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
ipv6Fragment->GetFragments (packet, outInterface->GetDevice ()->GetMtu (), fragments);
}
@@ -858,8 +863,8 @@
NS_LOG_WARN ("TTL exceeded. Drop.");
m_dropTrace (ipHeader, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), 0);
// Do not reply to ICMPv6 or to multicast IPv6 address
- if (ipHeader.GetNextHeader () != Icmpv6L4Protocol::PROT_NUMBER &&
- ipHeader.GetDestinationAddress ().IsMulticast () == false)
+ if (ipHeader.GetNextHeader () != Icmpv6L4Protocol::PROT_NUMBER
+ && ipHeader.GetDestinationAddress ().IsMulticast () == false)
{
packet->AddHeader (ipHeader);
GetIcmpv6 ()->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_HOPLIMIT);
@@ -869,12 +874,12 @@
/* ICMPv6 Redirect */
- /* if we forward to a machine on the same network as the source,
- * we send him an ICMPv6 redirect message to notify him that a short route
+ /* if we forward to a machine on the same network as the source,
+ * we send him an ICMPv6 redirect message to notify him that a short route
* exists.
*/
- if ((!rtentry->GetGateway ().IsAny () && rtentry->GetGateway ().CombinePrefix (Ipv6Prefix (64)) == header.GetSourceAddress ().CombinePrefix (Ipv6Prefix (64))) ||
- (rtentry->GetDestination ().CombinePrefix (Ipv6Prefix (64)) == header.GetSourceAddress ().CombinePrefix (Ipv6Prefix (64))))
+ if ((!rtentry->GetGateway ().IsAny () && rtentry->GetGateway ().CombinePrefix (Ipv6Prefix (64)) == header.GetSourceAddress ().CombinePrefix (Ipv6Prefix (64)))
+ || (rtentry->GetDestination ().CombinePrefix (Ipv6Prefix (64)) == header.GetSourceAddress ().CombinePrefix (Ipv6Prefix (64))))
{
NS_LOG_LOGIC ("ICMPv6 redirect!");
Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
@@ -940,8 +945,8 @@
{
NS_LOG_FUNCTION (this << packet << ip << iif);
Ptr<Packet> p = packet->Copy ();
- Ptr<IpL4Protocol> protocol = 0;
- Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
+ Ptr<IpL4Protocol> protocol = 0;
+ Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
Ptr<Ipv6Extension> ipv6Extension = 0;
Ipv6Address src = ip.GetSourceAddress ();
Ipv6Address dst = ip.GetDestinationAddress ();
@@ -961,7 +966,8 @@
}
/* process all the extensions found and the layer 4 protocol */
- do {
+ do
+ {
/* it return 0 for non-extension (i.e. layer 4 protocol) */
ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
@@ -1030,7 +1036,8 @@
}
}
}
- } while (ipv6Extension);
+ }
+ while (ipv6Extension);
}
void Ipv6L3Protocol::RouteInputError (Ptr<const Packet> p, const Ipv6Header& ipHeader, Socket::SocketErrno sockErrno)
--- a/src/internet/model/ipv6-list-routing.cc Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-list-routing.cc Wed Mar 21 18:51:55 2012 +0100
@@ -41,13 +41,13 @@
}
-Ipv6ListRouting::Ipv6ListRouting ()
+Ipv6ListRouting::Ipv6ListRouting ()
: m_ipv6 (0)
{
NS_LOG_FUNCTION_NOARGS ();
}
-Ipv6ListRouting::~Ipv6ListRouting ()
+Ipv6ListRouting::~Ipv6ListRouting ()
{
NS_LOG_FUNCTION_NOARGS ();
}
@@ -94,9 +94,9 @@
}
// Patterned after Linux ip_route_input and ip_route_input_slow
-bool
-Ipv6ListRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+bool
+Ipv6ListRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
LocalDeliverCallback lcb, ErrorCallback ecb)
{
bool retVal = false;
@@ -104,9 +104,9 @@
NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject<Node> ()->GetId ());
NS_ASSERT (m_ipv6 != 0);
- // Check if input device supports IP
+ // Check if input device supports IP
NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
- uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
+ uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
Ipv6Address dst = header.GetDestinationAddress ();
// Multicast recognition; handle local delivery here
@@ -171,7 +171,7 @@
lcb (p, header, iif);
return true;
}
- NS_LOG_LOGIC ("Address "<< addr << " not a match");
+ NS_LOG_LOGIC ("Address " << addr << " not a match");
}
}
// Check if input device supports IP forwarding
@@ -196,7 +196,7 @@
return retVal;
}
-void
+void
Ipv6ListRouting::NotifyInterfaceUp (uint32_t interface)
{
NS_LOG_FUNCTION (this << interface);
@@ -208,7 +208,7 @@
(*rprotoIter).second->NotifyInterfaceUp (interface);
}
}
-void
+void
Ipv6ListRouting::NotifyInterfaceDown (uint32_t interface)
{
NS_LOG_FUNCTION (this << interface);
@@ -220,7 +220,7 @@
(*rprotoIter).second->NotifyInterfaceDown (interface);
}
}
-void
+void
Ipv6ListRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
{
NS_LOG_FUNCTION (this << interface << address);
@@ -232,7 +232,7 @@
(*rprotoIter).second->NotifyAddAddress (interface, address);
}
}
-void
+void
Ipv6ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
{
NS_LOG_FUNCTION (this << interface << address);
@@ -269,7 +269,7 @@
}
}
-void
+void
Ipv6ListRouting::SetIpv6 (Ptr<Ipv6> ipv6)
{
NS_LOG_FUNCTION (this << ipv6);
@@ -296,14 +296,14 @@
}
}
-uint32_t
+uint32_t
Ipv6ListRouting::GetNRoutingProtocols (void) const
{
NS_LOG_FUNCTION (this);
- return m_routingProtocols.size ();
+ return m_routingProtocols.size ();
}
-Ptr<Ipv6RoutingProtocol>
+Ptr<Ipv6RoutingProtocol>
Ipv6ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
{
NS_LOG_FUNCTION (index);
@@ -324,7 +324,7 @@
return 0;
}
-bool
+bool
Ipv6ListRouting::Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b)
{
return a.first > b.first;
--- a/src/internet/model/ipv6-list-routing.h Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-list-routing.h Wed Mar 21 18:51:55 2012 +0100
@@ -25,7 +25,7 @@
namespace ns3 {
/**
- * \ingroup internet
+ * \ingroup internet
* \defgroup ipv6ListRouting Ipv6 List Routing
*/
@@ -34,15 +34,15 @@
* \class Ipv6ListRouting
* \brief Hold list of Ipv6RoutingProtocol objects.
*
- * This class is a specialization of Ipv6RoutingProtocol that allows
- * other instances of Ipv6RoutingProtocol to be inserted in a
+ * This class is a specialization of Ipv6RoutingProtocol that allows
+ * other instances of Ipv6RoutingProtocol to be inserted in a
* prioritized list. Routing protocols in the list are consulted one
* by one, from highest to lowest priority, until a routing protocol
* is found that will take the packet (this corresponds to a non-zero
* return value to RouteOutput, or a return value of true to RouteInput).
- * The order by which routing protocols with the same priority value
+ * The order by which routing protocols with the same priority value
* are consulted is undefined.
- *
+ *
*/
class Ipv6ListRouting : public Ipv6RoutingProtocol
{
@@ -78,7 +78,7 @@
virtual uint32_t GetNRoutingProtocols (void) const;
/**
- * \brief Get pointer to routing protocol stored at index,
+ * \brief Get pointer to routing protocol stored at index,
*
* The first protocol (index 0) the highest priority, the next one (index 1)
* the second highest priority, and so on. The priority parameter is an
@@ -86,7 +86,7 @@
* \param index index of protocol to return
* \param priority output parameter, set to the priority of the protocol
* being returned
- * \return pointer to routing protocol indexed by
+ * \return pointer to routing protocol indexed by
*/
virtual Ptr<Ipv6RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
@@ -108,7 +108,7 @@
/**
* \brief Dispose this object.
*/
- void DoDispose (void);
+ virtual void DoDispose (void);
private:
typedef std::pair<int16_t, Ptr<Ipv6RoutingProtocol> > Ipv6RoutingProtocolEntry;
--- a/src/internet/model/ipv6-static-routing.cc Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-static-routing.cc Wed Mar 21 18:51:55 2012 +0100
@@ -26,8 +26,7 @@
#include "ipv6-static-routing.h"
#include "ipv6-routing-table-entry.h"
-namespace ns3
-{
+namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
NS_OBJECT_ENSURE_REGISTERED (Ipv6StaticRouting);
@@ -56,7 +55,7 @@
{
NS_LOG_FUNCTION (this << ipv6);
NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
- uint32_t i = 0;
+ uint32_t i = 0;
m_ipv6 = ipv6;
for (i = 0; i < m_ipv6->GetNInterfaces (); i++)
@@ -164,9 +163,9 @@
for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
{
Ipv6MulticastRoutingTableEntry *route = *i;
- if (origin == route->GetOrigin () &&
- group == route->GetGroup () &&
- inputInterface == route->GetInputInterface ())
+ if (origin == route->GetOrigin ()
+ && group == route->GetGroup ()
+ && inputInterface == route->GetInputInterface ())
{
delete *i;
m_multicastRoutes.erase (i);
@@ -222,8 +221,8 @@
uint32_t shortestMetric = 0xffffffff;
/* when sending on link-local multicast, there have to be interface specified */
- if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast () ||
- dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
+ if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast ()
+ || dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
{
NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
rtentry = Create<Ipv6Route> ();
@@ -294,7 +293,7 @@
}
}
- if(rtentry)
+ if (rtentry)
{
NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
}
@@ -364,7 +363,7 @@
}
}
return mrtentry;
- }
+ }
}
}
return mrtentry;
@@ -474,8 +473,8 @@
for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
{
Ipv6RoutingTableEntry* rtentry = it->first;
- if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex &&
- rtentry->GetPrefixToUse () == prefixToUse)
+ if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex
+ && rtentry->GetPrefixToUse () == prefixToUse)
{
delete it->first;
m_networkRoutes.erase (it);
@@ -568,7 +567,7 @@
lcb (p, header, iif);
return true;
}
- NS_LOG_LOGIC ("Address "<< addr << " not a match");
+ NS_LOG_LOGIC ("Address " << addr << " not a match");
}
}
// Check if input device supports IP forwarding
@@ -599,8 +598,8 @@
{
for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
{
- if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address () &&
- m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
+ if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address ()
+ && m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
{
if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
{
@@ -670,10 +669,10 @@
{
Ipv6RoutingTableEntry route = GetRoute (j);
- if (route.GetInterface () == interface &&
- route.IsNetwork () &&
- route.GetDestNetwork () == networkAddress &&
- route.GetDestNetworkPrefix () == networkMask)
+ if (route.GetInterface () == interface
+ && route.IsNetwork ()
+ && route.GetDestNetwork () == networkAddress
+ && route.GetDestNetworkPrefix () == networkMask)
{
RemoveRoute (j);
}
@@ -716,7 +715,7 @@
{
delete j->first;
m_networkRoutes.erase (j);
- }
+ }
}
}
else
@@ -736,7 +735,7 @@
if (dest == Ipv6Address::GetAllNodesMulticast () || dest == Ipv6Address::GetAllRoutersMulticast () || dest == Ipv6Address::GetAllHostsMulticast ())
{
- return ret;
+ return ret;
}
/* useally IPv6 interfaces have one link-local address and one global address */
--- a/src/internet/model/ipv6-static-routing.h Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/ipv6-static-routing.h Wed Mar 21 18:51:55 2012 +0100
@@ -31,8 +31,7 @@
#include "ns3/ipv6-header.h"
#include "ns3/ipv6-routing-protocol.h"
-namespace ns3
-{
+namespace ns3 {
class Packet;
class NetDevice;
@@ -241,7 +240,7 @@
/**
* \brief Dispose this object.
*/
- void DoDispose ();
+ virtual void DoDispose ();
private:
typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> > NetworkRoutes;
--- a/src/internet/model/tcp-socket-base.cc Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/model/tcp-socket-base.cc Wed Mar 21 18:51:55 2012 +0100
@@ -105,7 +105,8 @@
m_node (0),
m_tcp (0),
m_rtt (0),
- m_nextTxSequence (0), // Change this for non-zero initial sequence number
+ m_nextTxSequence (0),
+ // Change this for non-zero initial sequence number
m_highTxMark (0),
m_rxBuffer (0),
m_txBuffer (0),
@@ -116,14 +117,16 @@
m_shutdownSend (false),
m_shutdownRecv (false),
m_connected (false),
- m_segmentSize (0), // For attribute initialization consistency (quiet valgrind)
+ m_segmentSize (0),
+ // For attribute initialization consistency (quiet valgrind)
m_rWnd (0)
{
NS_LOG_FUNCTION (this);
}
TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
- : TcpSocket (sock), //copy object::m_tid and socket::callbacks
+ : TcpSocket (sock),
+ //copy object::m_tid and socket::callbacks
m_dupAckCount (sock.m_dupAckCount),
m_delAckCount (0),
m_delAckMaxCount (sock.m_delAckMaxCount),
@@ -246,10 +249,9 @@
int
TcpSocketBase::Bind (void)
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
m_endPoint = m_tcp->Allocate ();
- m_endPoint6 = m_tcp->Allocate6 ();
- if (0 == m_endPoint || 0 == m_endPoint6)
+ if (0 == m_endPoint)
{
m_errno = ERROR_ADDRNOTAVAIL;
return -1;
@@ -261,7 +263,15 @@
int
TcpSocketBase::Bind6 (void)
{
- return Bind ();
+ NS_LOG_FUNCTION (this);
+ m_endPoint6 = m_tcp->Allocate6 ();
+ if (0 == m_endPoint6)
+ {
+ m_errno = ERROR_ADDRNOTAVAIL;
+ return -1;
+ }
+ m_tcp->m_sockets.push_back (this);
+ return SetupCallback ();
}
/** Inherit from Socket class: Bind socket (with specific address) to an end-point in TcpL4Protocol */
@@ -341,7 +351,7 @@
NS_LOG_FUNCTION (this << address);
// If haven't do so, Bind() this socket first
- if (InetSocketAddress::IsMatchingType (address))
+ if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
{
if (m_endPoint == 0)
{
@@ -362,7 +372,7 @@
return -1;
}
}
- else if (Inet6SocketAddress::IsMatchingType (address) )
+ else if (Inet6SocketAddress::IsMatchingType (address) && m_endPoint == 0)
{
// If we are operating on a v4-mapped address, translate the address to
// a v4 address and re-call this function
@@ -371,7 +381,7 @@
if (v6Addr.IsIpv4MappedAddress () == true)
{
Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
- return Connect(InetSocketAddress(v4Addr, transport.GetPort ()));
+ return Connect (InetSocketAddress (v4Addr, transport.GetPort ()));
}
if (m_endPoint6 == 0)
@@ -629,7 +639,7 @@
}
if (m_endPoint != 0)
{
- m_endPoint->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp, Ptr<TcpSocketBase> (this)));
+ m_endPoint->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp, Ptr<TcpSocketBase> (this)));
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr<TcpSocketBase> (this)));
}
if (m_endPoint6 != 0)
@@ -712,8 +722,14 @@
{
NS_LOG_FUNCTION (this);
- if (!m_closeNotified) NotifyNormalClose ();
- if (m_state != TIME_WAIT) DeallocateEndPoint ();
+ if (!m_closeNotified)
+ {
+ NotifyNormalClose ();
+ }
+ if (m_state != TIME_WAIT)
+ {
+ DeallocateEndPoint ();
+ }
m_closeNotified = true;
NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
CancelAllTimers ();
@@ -734,7 +750,7 @@
{ // In LAST_ACK and CLOSING states, it only wait for an ACK and the
// sequence number must equals to m_rxBuffer.NextRxSequence ()
return (m_rxBuffer.NextRxSequence () != head);
- };
+ }
// In all other cases, check if the sequence number is in range
return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
@@ -775,7 +791,7 @@
TcpHeader tcpHeader;
packet->RemoveHeader (tcpHeader);
if (tcpHeader.GetFlags () & TcpHeader::ACK)
- {
+ {
EstimateRtt (tcpHeader);
}
ReadOptions (tcpHeader);
@@ -789,12 +805,12 @@
m_rWnd = tcpHeader.GetWindowSize ();
// Discard fully out of range data packets
- if (packet->GetSize () &&
- OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
+ if (packet->GetSize ()
+ && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
{
NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
" received packet of seq [" << tcpHeader.GetSequenceNumber () <<
- ":" << tcpHeader.GetSequenceNumber () + packet->GetSize() <<
+ ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
m_rxBuffer.MaxRxSequence () << ")");
// Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
@@ -884,12 +900,12 @@
m_rWnd = tcpHeader.GetWindowSize ();
// Discard fully out of range packets
- if (packet->GetSize () &&
- OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
+ if (packet->GetSize ()
+ && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
{
NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
" received packet of seq [" << tcpHeader.GetSequenceNumber () <<
- ":" << tcpHeader.GetSequenceNumber () + packet->GetSize() <<
+ ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
m_rxBuffer.MaxRxSequence () << ")");
// Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
@@ -1045,11 +1061,17 @@
// Fork a socket if received a SYN. Do nothing otherwise.
// C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
- if (tcpflags != TcpHeader::SYN) return;
+ if (tcpflags != TcpHeader::SYN)
+ {
+ return;
+ }
// Call socket's notify function to let the server app know we got a SYN
// If the server app refuses the connection, do nothing
- if (!NotifyConnectionRequest (fromAddress)) return;
+ if (!NotifyConnectionRequest (fromAddress))
+ {
+ return;
+ }
// Clone the socket, simulate fork
Ptr<TcpSocketBase> newSock = Fork ();
NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
@@ -1108,7 +1130,7 @@
{ // Other in-sequence input
if (tcpflags != TcpHeader::RST)
{ // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
- NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t>(tcpflags) << std::dec << " received. Reset packet is sent.");
+ NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
SendRST ();
}
CloseAndNotify ();
@@ -1125,9 +1147,9 @@
// Extract the flags. PSH and URG are not honoured.
uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
- if (tcpflags == 0 ||
- (tcpflags == TcpHeader::ACK
- && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
+ if (tcpflags == 0
+ || (tcpflags == TcpHeader::ACK
+ && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
{ // If it is bare data, accept it and move to ESTABLISHED state. This is
// possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
// handshake is completed nicely.
@@ -1221,8 +1243,8 @@
else if (tcpflags == TcpHeader::ACK)
{ // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
ReceivedAck (packet, tcpHeader);
- if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0 &&
- tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
+ if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
+ && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
{ // This ACK corresponds to the FIN sent
NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
m_state = FIN_WAIT_2;
@@ -1258,8 +1280,8 @@
{
NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
m_state = CLOSING;
- if (m_txBuffer.Size () == 0 &&
- tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
+ if (m_txBuffer.Size () == 0
+ && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
{ // This ACK corresponds to the FIN sent
TimeWait ();
}
@@ -1267,9 +1289,12 @@
else if (m_state == FIN_WAIT_2)
{
TimeWait ();
- };
+ }
SendEmptyPacket (TcpHeader::ACK);
- if (!m_shutdownRecv) NotifyDataRecv ();
+ if (!m_shutdownRecv)
+ {
+ NotifyDataRecv ();
+ }
}
}
@@ -1348,11 +1373,11 @@
NS_LOG_FUNCTION (this << tcpHeader);
// Ignore all out of range packets
- if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence () ||
- tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
+ if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
+ || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
{
return;
- };
+ }
// For any case, remember the FIN position in rx buffer first
m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
@@ -1365,7 +1390,7 @@
if (!m_rxBuffer.Finished ())
{
return;
- };
+ }
// Simultaneous close: Application invoked Close() when we are processing this FIN packet
if (m_state == FIN_WAIT_1)
@@ -1770,8 +1795,11 @@
TcpSocketBase::SendPendingData (bool withAck)
{
NS_LOG_FUNCTION (this << withAck);
- if (m_txBuffer.Size () == 0) return false; // Nothing to send
+ if (m_txBuffer.Size () == 0)
+ {
+ return false; // Nothing to send
+ }
if (m_endPoint == 0 && m_endPoint6 == 0)
{
NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
@@ -1802,8 +1830,8 @@
}
// Nagle's algorithm (RFC896): Hold off sending if there is unacked data
// in the buffer and the amount of data to send is less than one segment
- if (!m_noDelay && UnAckDataCount () > 0 &&
- m_txBuffer.SizeFromSequence (m_nextTxSequence) < m_segmentSize)
+ if (!m_noDelay && UnAckDataCount () > 0
+ && m_txBuffer.SizeFromSequence (m_nextTxSequence) < m_segmentSize)
{
NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
break;
@@ -1893,7 +1921,10 @@
// Notify app to receive if necessary
if (expectedSeq < m_rxBuffer.NextRxSequence ())
{ // NextRxSeq advanced, we have something to send to the app
- if (!m_shutdownRecv) NotifyDataRecv ();
+ if (!m_shutdownRecv)
+ {
+ NotifyDataRecv ();
+ }
// Handle exceptions
if (m_closeNotified)
{
@@ -1916,7 +1947,7 @@
// (which should be ignored) is handled by m_rtt. Once timestamp option
// is implemented, this function would be more elaborated.
m_lastRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
-};
+}
// Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
// when the three-way handshake completed. This cancels retransmission timer
@@ -1979,9 +2010,15 @@
NS_LOG_FUNCTION (this);
NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
// If erroneous timeout in closed/timed-wait state, just return
- if (m_state == CLOSED || m_state == TIME_WAIT) return;
+ if (m_state == CLOSED || m_state == TIME_WAIT)
+ {
+ return;
+ }
// If all data are received (non-closing socket and nothing to send), just return
- if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
+ if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark)
+ {
+ return;
+ }
Retransmit ();
}
@@ -2112,7 +2149,7 @@
CancelAllTimers ();
// Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
// according to RFC793, p.28
- m_timewaitEvent = Simulator::Schedule (Seconds (2*m_msl),
+ m_timewaitEvent = Simulator::Schedule (Seconds (2 * m_msl),
&TcpSocketBase::CloseAndNotify, this);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/test/ipv6-fragmentation-test.cc Wed Mar 21 18:51:55 2012 +0100
@@ -0,0 +1,430 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Universita' di Firenze, Italy
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Tommaso Pecorella <[email protected]>
+ */
+/**
+ * This is the test code for ipv6-l3protocol.cc (only the fragmentation and reassembly part).
+ */
+#define NS3_LOG_ENABLE 1
+
+#include "ns3/test.h"
+#include "ns3/config.h"
+#include "ns3/uinteger.h"
+#include "ns3/socket-factory.h"
+#include "ns3/ipv4-raw-socket-factory.h"
+#include "ns3/ipv6-raw-socket-factory.h"
+#include "ns3/udp-socket-factory.h"
+#include "ns3/simulator.h"
+#include "error-channel.h"
+#include "error-net-device.h"
+#include "ns3/drop-tail-queue.h"
+#include "ns3/socket.h"
+#include "ns3/udp-socket.h"
+
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/boolean.h"
+
+#include "ns3/ipv6-static-routing.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/inet6-socket-address.h"
+#
+#include "ns3/arp-l3-protocol.h"
+#include "ns3/ipv4-l3-protocol.h"
+#include "ns3/icmpv4-l4-protocol.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/ipv4-static-routing.h"
+#include "ns3/udp-l4-protocol.h"
+
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/icmpv6-l4-protocol.h"
+
+#include <string>
+#include <limits>
+#include <netinet/in.h>
+
+namespace ns3 {
+
+class UdpSocketImpl;
+
+static void
+AddInternetStack (Ptr<Node> node)
+{
+ //IPV6
+ Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
+
+ //Routing for Ipv6
+ Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting> ();
+ ipv6->SetRoutingProtocol (ipv6Routing);
+ Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting> ();
+ ipv6Routing->AddRoutingProtocol (ipv6staticRouting, 0);
+ node->AggregateObject (ipv6);
+
+ //ICMPv6
+ Ptr<Icmpv6L4Protocol> icmp6 = CreateObject<Icmpv6L4Protocol> ();
+ node->AggregateObject (icmp6);
+
+ //Ipv6 Extensions
+ ipv6->RegisterExtensions ();
+ ipv6->RegisterOptions ();
+
+ //UDP
+ Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
+ node->AggregateObject (udp);
+}
+
+
+class Ipv6FragmentationTest : public TestCase
+{
+ Ptr<Packet> m_sentPacketClient;
+ Ptr<Packet> m_receivedPacketClient;
+ Ptr<Packet> m_receivedPacketServer;
+
+
+ Ptr<Socket> m_socketServer;
+ Ptr<Socket> m_socketClient;
+ uint32_t m_dataSize;
+ uint8_t *m_data;
+ uint32_t m_size;
+ uint8_t m_icmpType;
+ uint8_t m_icmpCode;
+
+public:
+ virtual void DoRun (void);
+ Ipv6FragmentationTest ();
+ ~Ipv6FragmentationTest ();
+
+ // server part
+ void StartServer (Ptr<Node> ServerNode);
+ void HandleReadServer (Ptr<Socket> socket);
+
+ // client part
+ void StartClient (Ptr<Node> ClientNode);
+ void HandleReadClient (Ptr<Socket> socket);
+ void HandleReadIcmpClient (Ipv6Address icmpSource, uint8_t icmpTtl, uint8_t icmpType,
+ uint8_t icmpCode,uint32_t icmpInfo);
+
+ void SetFill (uint8_t *fill, uint32_t fillSize, uint32_t dataSize);
+ Ptr<Packet> SendClient (void);
+
+};
+
+
+Ipv6FragmentationTest::Ipv6FragmentationTest ()
+ : TestCase ("Verify the IPv6 layer 3 protocol fragmentation and reassembly")
+{
+ m_socketServer = 0;
+ m_data = 0;
+ m_dataSize = 0;
+}
+
+Ipv6FragmentationTest::~Ipv6FragmentationTest ()
+{
+ if ( m_data )
+ {
+ delete[] m_data;
+ }
+ m_data = 0;
+ m_dataSize = 0;
+}
+
+
+void
+Ipv6FragmentationTest::StartServer (Ptr<Node> ServerNode)
+{
+
+ if (m_socketServer == 0)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ m_socketServer = Socket::CreateSocket (ServerNode, tid);
+ Inet6SocketAddress local = Inet6SocketAddress (Ipv6Address ("2001::1"), 9);
+ m_socketServer->Bind (local);
+ Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket> (m_socketServer);
+ }
+
+ m_socketServer->SetRecvCallback (MakeCallback (&Ipv6FragmentationTest::HandleReadServer, this));
+}
+
+void
+Ipv6FragmentationTest::HandleReadServer (Ptr<Socket> socket)
+{
+ Ptr<Packet> packet;
+ Address from;
+ while ((packet = socket->RecvFrom (from)))
+ {
+ if (Inet6SocketAddress::IsMatchingType (from))
+ {
+ packet->RemoveAllPacketTags ();
+ packet->RemoveAllByteTags ();
+
+ m_receivedPacketServer = packet->Copy ();
+ }
+ }
+}
+
+void
+Ipv6FragmentationTest::StartClient (Ptr<Node> ClientNode)
+{
+
+ if (m_socketClient == 0)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ m_socketClient = Socket::CreateSocket (ClientNode, tid);
+ m_socketClient->Bind (Inet6SocketAddress (Ipv6Address::GetAny (), 9));
+ m_socketClient->Connect (Inet6SocketAddress (Ipv6Address ("2001::1"), 9));
+ CallbackValue cbValue = MakeCallback (&Ipv6FragmentationTest::HandleReadIcmpClient, this);
+ m_socketClient->SetAttribute ("IcmpCallback6", cbValue);
+ }
+
+ m_socketClient->SetRecvCallback (MakeCallback (&Ipv6FragmentationTest::HandleReadClient, this));
+}
+
+void
+Ipv6FragmentationTest::HandleReadClient (Ptr<Socket> socket)
+{
+ Ptr<Packet> packet;
+ Address from;
+ while ((packet = socket->RecvFrom (from)))
+ {
+ if (Inet6SocketAddress::IsMatchingType (from))
+ {
+ m_receivedPacketClient = packet->Copy ();
+ }
+ }
+}
+
+void
+Ipv6FragmentationTest::HandleReadIcmpClient (Ipv6Address icmpSource,
+ uint8_t icmpTtl, uint8_t icmpType,
+ uint8_t icmpCode, uint32_t icmpInfo)
+{
+ m_icmpType = icmpType;
+ m_icmpCode = icmpCode;
+}
+
+void
+Ipv6FragmentationTest::SetFill (uint8_t *fill, uint32_t fillSize, uint32_t dataSize)
+{
+ if (dataSize != m_dataSize)
+ {
+ delete [] m_data;
+ m_data = new uint8_t [dataSize];
+ m_dataSize = dataSize;
+ }
+
+ if (fillSize >= dataSize)
+ {
+ memcpy (m_data, fill, dataSize);
+ return;
+ }
+
+ uint32_t filled = 0;
+ while (filled + fillSize < dataSize)
+ {
+ memcpy (&m_data[filled], fill, fillSize);
+ filled += fillSize;
+ }
+
+ memcpy (&m_data[filled], fill, dataSize - filled);
+
+ m_size = dataSize;
+}
+
+Ptr<Packet> Ipv6FragmentationTest::SendClient (void)
+{
+ Ptr<Packet> p;
+ if (m_dataSize)
+ {
+ p = Create<Packet> (m_data, m_dataSize);
+ }
+ else
+ {
+ p = Create<Packet> (m_size);
+ }
+ m_socketClient->Send (p);
+
+ return p;
+}
+
+void
+Ipv6FragmentationTest::DoRun (void)
+{
+ // set the arp cache to something quite high
+ // we shouldn't need because the NetDevice used doesn't need arp, but still
+ // Config::SetDefault ("ns3::ArpCache::PendingQueueSize", UintegerValue (100));
+// LogComponentEnable ("ErrorNetDevice", LOG_LEVEL_ALL);
+// LogComponentEnableAll(LOG_LEVEL_ALL);
+// Create topology
+
+ // Receiver Node
+ Ptr<Node> serverNode = CreateObject<Node> ();
+ AddInternetStack (serverNode);
+ Ptr<ErrorNetDevice> serverDev;
+ Ptr<BinaryErrorModel> serverDevErrorModel = CreateObject<BinaryErrorModel> ();
+ {
+ serverDev = CreateObject<ErrorNetDevice> ();
+ serverDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
+ serverDev->SetMtu (1500);
+ serverDev->SetReceiveErrorModel (serverDevErrorModel);
+ serverDevErrorModel->Disable ();
+ serverNode->AddDevice (serverDev);
+ Ptr<Ipv6> ipv6 = serverNode->GetObject<Ipv6> ();
+ uint32_t netdev_idx = ipv6->AddInterface (serverDev);
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001::1"), Ipv6Prefix (32));
+ ipv6->AddAddress (netdev_idx, ipv6Addr);
+ ipv6->SetUp (netdev_idx);
+ }
+ StartServer (serverNode);
+
+ // Sender Node
+ Ptr<Node> clientNode = CreateObject<Node> ();
+ AddInternetStack (clientNode);
+ Ptr<ErrorNetDevice> clientDev;
+ Ptr<BinaryErrorModel> clientDevErrorModel = CreateObject<BinaryErrorModel> ();
+ {
+ clientDev = CreateObject<ErrorNetDevice> ();
+ clientDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
+ clientDev->SetMtu (1000);
+ clientDev->SetReceiveErrorModel (clientDevErrorModel);
+ clientDevErrorModel->Disable ();
+ clientNode->AddDevice (clientDev);
+ Ptr<Ipv6> ipv6 = clientNode->GetObject<Ipv6> ();
+ uint32_t netdev_idx = ipv6->AddInterface (clientDev);
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001::2"), Ipv6Prefix (32));
+ ipv6->AddAddress (netdev_idx, ipv6Addr);
+ ipv6->SetUp (netdev_idx);
+ }
+ StartClient (clientNode);
+
+ // link the two nodes
+ Ptr<ErrorChannel> channel = CreateObject<ErrorChannel> ();
+ serverDev->SetChannel (channel);
+ clientDev->SetChannel (channel);
+ channel->SetJumpingTime (Seconds (0.5));
+
+
+ // some small packets, some rather big ones
+ uint32_t packetSizes[5] = {1000, 2000, 5000, 10000, 65000};
+
+ // using the alphabet
+ uint8_t fillData[78];
+ for ( uint32_t k = 48; k <= 125; k++ )
+ {
+ fillData[k - 48] = k;
+ }
+
+ // First test: normal channel, no errors, no delays
+ for ( int i = 0; i < 5; i++)
+ {
+ uint32_t packetSize = packetSizes[i];
+
+ SetFill (fillData, 78, packetSize);
+
+ m_receivedPacketServer = Create<Packet> ();
+ Simulator::ScheduleWithContext (m_socketClient->GetNode ()->GetId (), Seconds (0),
+ &Ipv6FragmentationTest::SendClient, this);
+ Simulator::Run ();
+
+ uint8_t recvBuffer[65000];
+
+ uint16_t recvSize = m_receivedPacketServer->GetSize ();
+
+ NS_TEST_EXPECT_MSG_EQ (recvSize, packetSizes[i],
+ "Packet size not correct: recvSize: " << recvSize << " packetSizes[" << i << "]: " << packetSizes[i] );
+
+ m_receivedPacketServer->CopyData (recvBuffer, 65000);
+ NS_TEST_EXPECT_MSG_EQ (memcmp (m_data, recvBuffer, m_receivedPacketServer->GetSize ()),
+ 0, "Packet content differs");
+ }
+
+ // Second test: normal channel, no errors, delays each 2 packets.
+ // Each other fragment will arrive out-of-order.
+ // The packets should be received correctly since reassembly will reorder the fragments.
+ channel->SetJumpingMode (true);
+ for ( int i = 0; i < 5; i++)
+ {
+ uint32_t packetSize = packetSizes[i];
+
+ SetFill (fillData, 78, packetSize);
+
+ m_receivedPacketServer = Create<Packet> ();
+ Simulator::ScheduleWithContext (m_socketClient->GetNode ()->GetId (), Seconds (0),
+ &Ipv6FragmentationTest::SendClient, this);
+ Simulator::Run ();
+
+ uint8_t recvBuffer[65000];
+
+ uint16_t recvSize = m_receivedPacketServer->GetSize ();
+
+ NS_TEST_EXPECT_MSG_EQ (recvSize, packetSizes[i],
+ "Packet size not correct: recvSize: " << recvSize << " packetSizes[" << i << "]: " << packetSizes[i] );
+
+ m_receivedPacketServer->CopyData (recvBuffer, 65000);
+ NS_TEST_EXPECT_MSG_EQ (memcmp (m_data, recvBuffer, m_receivedPacketServer->GetSize ()),
+ 0, "Packet content differs");
+ }
+ channel->SetJumpingMode (false);
+
+ // Third test: normal channel, some errors, no delays.
+ // The reassembly procedure should fire a timeout after 30 seconds (as specified in the RFCs).
+ // Upon the timeout, the fragments received so far are discarded and an ICMP should be sent back
+ // to the sender (if the first fragment has been received).
+ // In this test case the first fragment is received, so we do expect an ICMP.
+ // Client -> Server : errors enabled
+ // Server -> Client : errors disabled (we want to have back the ICMP)
+ clientDevErrorModel->Disable ();
+ serverDevErrorModel->Enable ();
+ for ( int i = 1; i < 5; i++)
+ {
+ uint32_t packetSize = packetSizes[i];
+
+ SetFill (fillData, 78, packetSize);
+
+ // reset the model, we want to receive the very first fragment.
+ serverDevErrorModel->Reset ();
+
+ m_receivedPacketServer = Create<Packet> ();
+ m_icmpType = 0;
+ m_icmpCode = 0;
+ Simulator::ScheduleWithContext (m_socketClient->GetNode ()->GetId (), Seconds (0),
+ &Ipv6FragmentationTest::SendClient, this);
+ Simulator::Run ();
+
+ uint16_t recvSize = m_receivedPacketServer->GetSize ();
+
+ NS_TEST_EXPECT_MSG_EQ ((recvSize == 0), true, "Server got a packet, something wrong");
+ NS_TEST_EXPECT_MSG_EQ ((m_icmpType == Icmpv6Header::ICMPV6_ERROR_TIME_EXCEEDED)
+ && (m_icmpCode == Icmpv6Header::ICMPV6_FRAGTIME),
+ true, "Client did not receive ICMPv6::TIME_EXCEEDED " << int(m_icmpType) << int(m_icmpCode) );
+ }
+
+
+ Simulator::Destroy ();
+}
+//-----------------------------------------------------------------------------
+class Ipv6FragmentationTestSuite : public TestSuite
+{
+public:
+ Ipv6FragmentationTestSuite () : TestSuite ("ipv6-fragmentation", UNIT)
+ {
+ AddTestCase (new Ipv6FragmentationTest);
+ }
+} g_ipv6fragmentationTestSuite;
+
+}; // namespace ns3
--- a/src/internet/wscript Fri Mar 23 23:51:29 2012 -0700
+++ b/src/internet/wscript Wed Mar 21 18:51:55 2012 +0100
@@ -206,6 +206,7 @@
'test/udp-test.cc',
'test/ipv6-address-generator-test-suite.cc',
'test/ipv6-dual-stack-test-suite.cc',
+ 'test/ipv6-fragmentation-test.cc',
]
headers = bld.new_task_gen(features=['ns3header'])