src/internet-stack/nsc-tcp-l4-protocol.cc
author Florian Westphal <fw@strlen.de>
Wed Jul 15 18:46:14 2009 +0200 (2009-07-15)
changeset 4685 ae536d9e0d6d
parent 4669 8aaa5e83939e
permissions -rw-r--r--
nsc: move nsc glue code from nsc-tcp-l4-protocol to node/nsc-glue.cc.

known problems:
- sim_interface.h is duplicated
- nsc-glue.cc adds hooks in node.cc, "hijacks" incoming packets
- nsc-glue exports NSCs INetStack (instead of wrapping it completely)
- nsc-tcp-l4-protocol and nsc-tcp-socket-impl make calls into nsc-glue
- nsc-tcp-socket-impl should really be "nsc-socket-core" (or something
like that)

needs fixing on nsc side:
- no support for multiple interfaces yet (also not yet supported
on nsc side)
- nsc initialisation still tied to IP (Adding an Interface and assigning the
IP address is a single step; it should be separate)

maybe there is more.

There is a NSC_NEXT define in nsc-glue.h, its main purpose is to flag
the places where the NSC API needs to be adapted to support multiple
interfaces in nsc.
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * This program is free software; you can redistribute it and/or modify
     4  * it under the terms of the GNU General Public License version 2 as
     5  * published by the Free Software Foundation;
     6  *
     7  * This program is distributed in the hope that it will be useful,
     8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  * GNU General Public License for more details.
    11  *
    12  * You should have received a copy of the GNU General Public License
    13  * along with this program; if not, write to the Free Software
    14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    15  *
    16  * based on earlier integration work by Tom Henderson and Sam Jansen.
    17  * 2008 Florian Westphal <fw@strlen.de>
    18  */
    19 
    20 #include "ns3/assert.h"
    21 #include "ns3/log.h"
    22 
    23 #include "ns3/packet.h"
    24 #include "ns3/node.h"
    25 #include "ns3/ipv4-route.h"
    26 
    27 #include "ns3/object-vector.h"
    28 #include "ns3/string.h"
    29 #include "tcp-header.h"
    30 #include "ipv4-end-point-demux.h"
    31 #include "ipv4-end-point.h"
    32 #include "ipv4-l3-protocol.h"
    33 #include "nsc-tcp-l4-protocol.h"
    34 
    35 #include "nsc-tcp-socket-factory-impl.h"
    36 
    37 #include "tcp-typedefs.h"
    38 
    39 #include <vector>
    40 #include <sstream>
    41 #include <dlfcn.h>
    42 #include <iomanip>
    43 
    44 #include <netinet/in.h>
    45 #include <arpa/inet.h>
    46 
    47 NS_LOG_COMPONENT_DEFINE ("NscTcpL4Protocol");
    48 
    49 namespace ns3 {
    50 
    51 NS_OBJECT_ENSURE_REGISTERED (NscTcpL4Protocol);
    52 
    53 /* see http://www.iana.org/assignments/protocol-numbers */
    54 const uint8_t NscTcpL4Protocol::PROT_NUMBER = 6;
    55 
    56 ObjectFactory
    57 NscTcpL4Protocol::GetDefaultRttEstimatorFactory (void)
    58 {
    59   ObjectFactory factory;
    60   factory.SetTypeId (RttMeanDeviation::GetTypeId ());
    61   return factory;
    62 }
    63 
    64 TypeId 
    65 NscTcpL4Protocol::GetTypeId (void)
    66 {
    67   static TypeId tid = TypeId ("ns3::NscTcpL4Protocol")
    68     .SetParent<Ipv4L4Protocol> ()
    69     .AddConstructor<NscTcpL4Protocol>()
    70     .AddAttribute ("RttEstimatorFactory",
    71                    "How RttEstimator objects are created.",
    72                    ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
    73                    MakeObjectFactoryAccessor (&NscTcpL4Protocol::m_rttFactory),
    74                    MakeObjectFactoryChecker ())
    75     .AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
    76                    ObjectVectorValue (),
    77                    MakeObjectVectorAccessor (&NscTcpL4Protocol::m_sockets),
    78                    MakeObjectVectorChecker<NscTcpSocketImpl> ())
    79     .AddAttribute ("Library",
    80                    "Set the linux library to be used to create the stack",
    81                    TypeId::ATTR_GET|TypeId::ATTR_CONSTRUCT,
    82                    StringValue("liblinux2.6.26.so"),
    83                    MakeStringAccessor (&NscTcpL4Protocol::GetNscLibrary,&NscTcpL4Protocol::SetNscLibrary),
    84                    MakeStringChecker ())
    85     ;
    86   return tid;
    87 }
    88 
    89 NscTcpL4Protocol::NscTcpL4Protocol ()
    90   : m_endPoints (new Ipv4EndPointDemux ())
    91 {
    92   NS_LOG_LOGIC("Made a NscTcpL4Protocol "<<this);
    93 }
    94 
    95 void
    96 NscTcpL4Protocol::SetNscLibrary(const std::string &soname)
    97 {    
    98   if (soname!="")
    99     {
   100       m_nscLibrary = soname;
   101     }
   102 }
   103 
   104 std::string 
   105 NscTcpL4Protocol::GetNscLibrary () const
   106 {
   107   return m_nscLibrary;
   108 }
   109 
   110 
   111 void
   112 NscTcpL4Protocol::SetNode (Ptr<Node> node)
   113 {
   114   m_node = node;
   115   m_node->SetNscLibrary (m_nscLibrary);
   116   m_node->RegisterNscWakeupCallback (MakeCallback (&NscTcpL4Protocol::Wakeup , this));
   117 }
   118 
   119 void
   120 NscTcpL4Protocol::NotifyNewAggregate ()
   121 { 
   122   if (m_node == 0)
   123     {
   124       Ptr<Node>node = this->GetObject<Node> ();
   125       if (node != 0)
   126         {
   127           Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
   128           if (ipv4 != 0)
   129             {
   130               this->SetNode (node);
   131               ipv4->Insert (this);
   132               Ptr<NscTcpSocketFactoryImpl> tcpFactory = CreateObject<NscTcpSocketFactoryImpl> ();
   133               tcpFactory->SetTcp (this);
   134               node->AggregateObject (tcpFactory);
   135             }
   136         }
   137     }
   138   Object::NotifyNewAggregate ();
   139 }
   140 
   141 int 
   142 NscTcpL4Protocol::GetProtocolNumber (void) const
   143 {
   144   return PROT_NUMBER;
   145 }
   146 int 
   147 NscTcpL4Protocol::GetVersion (void) const
   148 {
   149   return 2;
   150 }
   151 
   152 void
   153 NscTcpL4Protocol::DoDispose (void)
   154 {
   155   NS_LOG_FUNCTION (this);
   156 
   157   for (std::vector<Ptr<NscTcpSocketImpl> >::iterator i = m_sockets.begin (); i != m_sockets.end (); i++)
   158     {
   159       *i = 0;
   160     }
   161   m_sockets.clear ();
   162 
   163 
   164   if (m_endPoints != 0)
   165     {
   166       delete m_endPoints;
   167       m_endPoints = 0;
   168     }
   169   m_node = 0;
   170   Ipv4L4Protocol::DoDispose ();
   171 }
   172 
   173 Ptr<Socket>
   174 NscTcpL4Protocol::CreateSocket (void)
   175 {
   176   NS_LOG_FUNCTION (this);
   177 
   178   Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
   179   Ptr<NscTcpSocketImpl> socket = CreateObject<NscTcpSocketImpl> ();
   180   socket->SetNode (m_node);
   181   socket->SetTcp (this);
   182   socket->SetRtt (rtt);
   183   m_sockets.push_back (socket);
   184   return socket;
   185 }
   186 
   187 Ipv4EndPoint *
   188 NscTcpL4Protocol::Allocate (void)
   189 {
   190   NS_LOG_FUNCTION (this);
   191   return m_endPoints->Allocate ();
   192 }
   193 
   194 Ipv4EndPoint *
   195 NscTcpL4Protocol::Allocate (Ipv4Address address)
   196 {
   197   NS_LOG_FUNCTION (this << address);
   198   return m_endPoints->Allocate (address);
   199 }
   200 
   201 Ipv4EndPoint *
   202 NscTcpL4Protocol::Allocate (uint16_t port)
   203 {
   204   NS_LOG_FUNCTION (this << port);
   205   return m_endPoints->Allocate (port);
   206 }
   207 
   208 Ipv4EndPoint *
   209 NscTcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
   210 {
   211   NS_LOG_FUNCTION (this << address << port);
   212   return m_endPoints->Allocate (address, port);
   213 }
   214 
   215 Ipv4EndPoint *
   216 NscTcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
   217                          Ipv4Address peerAddress, uint16_t peerPort)
   218 {
   219   NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
   220   return m_endPoints->Allocate (localAddress, localPort,
   221                                 peerAddress, peerPort);
   222 }
   223 
   224 void 
   225 NscTcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
   226 {
   227   NS_LOG_FUNCTION (this << endPoint);
   228   m_endPoints->DeAllocate (endPoint);
   229 }
   230 
   231 void NscTcpL4Protocol::Wakeup()
   232 {
   233   // TODO
   234   // this should schedule a timer to read from all tcp sockets now... this is
   235   // an indication that data might be waiting on the socket
   236 
   237   Ipv4EndPointDemux::EndPoints endPoints = m_endPoints->GetAllEndPoints ();
   238   for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
   239        endPoint != endPoints.end (); endPoint++) {
   240           // NSC HACK: (ab)use TcpSocket::ForwardUp for signalling
   241           (*endPoint)->ForwardUp (NULL, Ipv4Address(), 0);
   242   }
   243 }
   244 
   245 Ipv4L4Protocol::RxStatus
   246 NscTcpL4Protocol::Receive (Ptr<Packet> p,
   247                        Ipv4Address const &source,
   248                        Ipv4Address const &destination,
   249                        Ptr<Ipv4Interface> incomingInterface)
   250 { // STUB, RX happens in node/node.cc if NSC is in use.
   251   return Ipv4L4Protocol::RX_OK;
   252 }
   253 
   254 }; // namespace ns3
   255