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