nsc: core files.
authorFlorian Westphal <fw@strlen.de>
Fri Aug 29 23:08:18 2008 +0200 (17 months ago)
changeset 3599e6374560e19e
parent 3598 4631eaaf84c4
child 3600 9e5eaef3e082
nsc: core files.

This adds the core network simulation cradle support
code.
src/internet-stack/nsc-sysctl.cc
src/internet-stack/nsc-sysctl.h
src/internet-stack/nsc-tcp-l4-protocol.cc
src/internet-stack/nsc-tcp-l4-protocol.h
src/internet-stack/nsc-tcp-socket-factory-impl.cc
src/internet-stack/nsc-tcp-socket-factory-impl.h
src/internet-stack/nsc-tcp-socket-impl.cc
src/internet-stack/nsc-tcp-socket-impl.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/internet-stack/nsc-sysctl.cc	Fri Aug 29 23:08:18 2008 +0200
     1.3 @@ -0,0 +1,154 @@
     1.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     1.5 +/*
     1.6 + * This program is free software; you can redistribute it and/or modify
     1.7 + * it under the terms of the GNU General Public License version 2 as
     1.8 + * published by the Free Software Foundation;
     1.9 + *
    1.10 + * This program is distributed in the hope that it will be useful,
    1.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.13 + * GNU General Public License for more details.
    1.14 + *
    1.15 + * You should have received a copy of the GNU General Public License
    1.16 + * along with this program; if not, write to the Free Software
    1.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.18 + *
    1.19 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    1.20 + */
    1.21 +
    1.22 +#include "ns3/string.h"
    1.23 +#include "nsc-sysctl.h"
    1.24 +
    1.25 +#include "nsc/sim/sim_interface.h"
    1.26 +
    1.27 +namespace ns3 {
    1.28 +
    1.29 +class NscStackStringAccessor : public AttributeAccessor
    1.30 +{
    1.31 +  public:
    1.32 +  NscStackStringAccessor (std::string name) : m_name (name) {}
    1.33 +
    1.34 +  virtual bool Set (ObjectBase * object, const AttributeValue &val) const;
    1.35 +  virtual bool Get (const ObjectBase * object, AttributeValue &val) const;
    1.36 +  virtual bool HasGetter (void) const;
    1.37 +  virtual bool HasSetter (void) const;
    1.38 +  private:
    1.39 +  std::string m_name;
    1.40 +};
    1.41 +
    1.42 +bool NscStackStringAccessor::HasGetter(void) const
    1.43 +{
    1.44 +  return true;
    1.45 +}
    1.46 +
    1.47 +bool NscStackStringAccessor::HasSetter(void) const
    1.48 +{
    1.49 +  return true;
    1.50 +}
    1.51 +
    1.52 +
    1.53 +bool NscStackStringAccessor::Set (ObjectBase * object, const AttributeValue & val) const
    1.54 +{
    1.55 +  const StringValue *value = dynamic_cast<const StringValue *> (&val);
    1.56 +  if (value == 0)
    1.57 +    {
    1.58 +      return false;
    1.59 +    }
    1.60 +  Ns3NscStack *obj = dynamic_cast<Ns3NscStack *> (object);
    1.61 +  if (obj == 0)
    1.62 +    {
    1.63 +      return false;
    1.64 +    }
    1.65 +  obj->Set (m_name, value->Get ());
    1.66 +  return true;
    1.67 +}
    1.68 +
    1.69 +bool NscStackStringAccessor::Get (const ObjectBase * object, AttributeValue &val) const
    1.70 +{
    1.71 +  StringValue *value = dynamic_cast<StringValue *> (&val);
    1.72 +  if (value == 0)
    1.73 +    {
    1.74 +      return false;
    1.75 +    }
    1.76 +  const Ns3NscStack *obj = dynamic_cast<const Ns3NscStack *> (object);
    1.77 +  if (obj == 0)
    1.78 +    {
    1.79 +      return false;
    1.80 +    }
    1.81 +  value->Set (obj->Get (m_name));
    1.82 +  return true;
    1.83 +}
    1.84 +
    1.85 +
    1.86 +TypeId
    1.87 +Ns3NscStack::GetInstanceTypeId (void) const
    1.88 +{
    1.89 +  if (m_stack == 0)
    1.90 +    {
    1.91 +      // if we have no stack, we are a normal NscStack without any attributes.
    1.92 +      return GetTypeId ();
    1.93 +    }
    1.94 +  std::string name = "ns3::Ns3NscStack<";
    1.95 +  name += m_stack->get_name ();
    1.96 +  name += ">";
    1.97 +  TypeId tid;
    1.98 +  if (TypeId::LookupByNameFailSafe (name, &tid))
    1.99 +    {
   1.100 +      // if the relevant TypeId has already been registered, no need to do it again.
   1.101 +      return tid;
   1.102 +    }
   1.103 +  else
   1.104 +    {
   1.105 +      // Now, we register a new TypeId for this stack which will look
   1.106 +      // like a subclass of the Ns3NscStack. The class Ns3NscStack is effectively
   1.107 +      // mutating into a subclass of itself from the point of view of the TypeId
   1.108 +      // system _here_
   1.109 +      tid = TypeId (name.c_str ());
   1.110 +      tid.SetParent<Ns3NscStack> ();
   1.111 +      char buf[256];
   1.112 +      for (int i=0; m_stack->sysctl_getnum(i, buf, sizeof(buf)) > 0 ;i++)
   1.113 +        {
   1.114 +          char value[256];
   1.115 +          if (m_stack->sysctl_get (buf, value, sizeof(value)) > 0)
   1.116 +            {
   1.117 +              tid.AddAttribute (buf, "Help text",
   1.118 +                                StringValue (value),
   1.119 +                                Create<NscStackStringAccessor> (buf),
   1.120 +                                MakeStringChecker ());
   1.121 +            }
   1.122 +        }
   1.123 +      return tid;
   1.124 +    }
   1.125 +}
   1.126 +
   1.127 +std::string
   1.128 +Ns3NscStack::Get (std::string name) const
   1.129 +{
   1.130 +  char buf[512];
   1.131 +  if (m_stack->sysctl_get (name.c_str (), buf, sizeof(buf)) <= 0)
   1.132 +    { // name.c_str () is not a valid sysctl name, or internal NSC error (eg. error converting value)
   1.133 +      return NULL;
   1.134 +    }
   1.135 +  return std::string(buf);
   1.136 +}
   1.137 +
   1.138 +void
   1.139 +Ns3NscStack::Set (std::string name, std::string value)
   1.140 +{
   1.141 +  int ret = m_stack->sysctl_set (name.c_str (), value.c_str ());
   1.142 +  if (ret < 0)
   1.143 +    {
   1.144 +      NS_FATAL_ERROR ("setting " << name << " to " << value << "failed (retval " << ret << ")");
   1.145 +    }
   1.146 +}
   1.147 +
   1.148 +TypeId
   1.149 +Ns3NscStack::Ns3NscStack::GetTypeId (void)
   1.150 +{
   1.151 +  static TypeId tid = TypeId ("ns3::Ns3NscStack")
   1.152 +  .SetParent<Object> ()
   1.153 +  ;
   1.154 +  return tid;
   1.155 +}
   1.156 +
   1.157 +} // namespace ns3
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/internet-stack/nsc-sysctl.h	Fri Aug 29 23:08:18 2008 +0200
     2.3 @@ -0,0 +1,44 @@
     2.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     2.5 +/*
     2.6 + * This program is free software; you can redistribute it and/or modify
     2.7 + * it under the terms of the GNU General Public License version 2 as
     2.8 + * published by the Free Software Foundation;
     2.9 + *
    2.10 + * This program is distributed in the hope that it will be useful,
    2.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.13 + * GNU General Public License for more details.
    2.14 + *
    2.15 + * You should have received a copy of the GNU General Public License
    2.16 + * along with this program; if not, write to the Free Software
    2.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.18 + *
    2.19 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    2.20 + */
    2.21 +
    2.22 +#include <string>
    2.23 +
    2.24 +#include "ns3/attribute.h"
    2.25 +#include "ns3/object.h"
    2.26 +
    2.27 +struct INetStack;
    2.28 +
    2.29 +namespace ns3 {
    2.30 +
    2.31 +// This object represents the underlying nsc stack,
    2.32 +// which is aggregated to a Node object, and which provides access to the
    2.33 +// sysctls of the nsc stack through attributes.
    2.34 +class Ns3NscStack : public Object
    2.35 +{
    2.36 +public:
    2.37 +  static TypeId GetTypeId (void);
    2.38 +  virtual TypeId GetInstanceTypeId (void) const;
    2.39 +  void SetStack (INetStack *stack) {m_stack = stack;}
    2.40 +
    2.41 +private:
    2.42 +  friend class NscStackStringAccessor;
    2.43 +  void Set (std::string name, std::string value);
    2.44 +  std::string Get (std::string name) const;
    2.45 +  INetStack *m_stack;
    2.46 +};
    2.47 +} // namespace ns3
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/internet-stack/nsc-tcp-l4-protocol.cc	Fri Aug 29 23:08:18 2008 +0200
     3.3 @@ -0,0 +1,368 @@
     3.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     3.5 +/*
     3.6 + * This program is free software; you can redistribute it and/or modify
     3.7 + * it under the terms of the GNU General Public License version 2 as
     3.8 + * published by the Free Software Foundation;
     3.9 + *
    3.10 + * This program is distributed in the hope that it will be useful,
    3.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.13 + * GNU General Public License for more details.
    3.14 + *
    3.15 + * You should have received a copy of the GNU General Public License
    3.16 + * along with this program; if not, write to the Free Software
    3.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.18 + *
    3.19 + * based on earlier integration work by Tom Henderson and Sam Jansen.
    3.20 + * 2008 Florian Westphal <fw@strlen.de>
    3.21 + */
    3.22 +
    3.23 +#include "ns3/assert.h"
    3.24 +#include "ns3/log.h"
    3.25 +#include "ns3/nstime.h"
    3.26 +
    3.27 +#include "ns3/packet.h"
    3.28 +#include "ns3/node.h"
    3.29 +
    3.30 +#include "tcp-header.h"
    3.31 +#include "ipv4-end-point-demux.h"
    3.32 +#include "ipv4-end-point.h"
    3.33 +#include "ipv4-l3-protocol.h"
    3.34 +#include "nsc-tcp-l4-protocol.h"
    3.35 +#include "nsc-tcp-socket-impl.h"
    3.36 +#include "nsc-sysctl.h"
    3.37 +
    3.38 +#include "tcp-typedefs.h"
    3.39 +
    3.40 +#include <vector>
    3.41 +#include <sstream>
    3.42 +#include <dlfcn.h>
    3.43 +#include <iomanip>
    3.44 +
    3.45 +#include <netinet/ip.h>
    3.46 +#include <netinet/tcp.h>
    3.47 +
    3.48 +NS_LOG_COMPONENT_DEFINE ("NscTcpL4Protocol");
    3.49 +
    3.50 +namespace ns3 {
    3.51 +
    3.52 +NS_OBJECT_ENSURE_REGISTERED (NscTcpL4Protocol);
    3.53 +
    3.54 +/* see http://www.iana.org/assignments/protocol-numbers */
    3.55 +const uint8_t NscTcpL4Protocol::PROT_NUMBER = 6;
    3.56 +
    3.57 +ObjectFactory
    3.58 +NscTcpL4Protocol::GetDefaultRttEstimatorFactory (void)
    3.59 +{
    3.60 +  ObjectFactory factory;
    3.61 +  factory.SetTypeId (RttMeanDeviation::GetTypeId ());
    3.62 +  return factory;
    3.63 +}
    3.64 +
    3.65 +TypeId 
    3.66 +NscTcpL4Protocol::GetTypeId (void)
    3.67 +{
    3.68 +  static TypeId tid = TypeId ("ns3::NscTcpL4Protocol")
    3.69 +    .SetParent<Ipv4L4Protocol> ()
    3.70 +
    3.71 +    .AddAttribute ("RttEstimatorFactory",
    3.72 +                   "How RttEstimator objects are created.",
    3.73 +                   ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
    3.74 +                   MakeObjectFactoryAccessor (&NscTcpL4Protocol::m_rttFactory),
    3.75 +                   MakeObjectFactoryChecker ())
    3.76 +    ;
    3.77 +  return tid;
    3.78 +}
    3.79 +
    3.80 +int external_rand()
    3.81 +{
    3.82 +    return 1; // TODO
    3.83 +}
    3.84 +
    3.85 +NscTcpL4Protocol::NscTcpL4Protocol ()
    3.86 +  : m_endPoints (new Ipv4EndPointDemux ()),
    3.87 +    m_nscStack (0),
    3.88 +    m_nscInterfacesSetUp(false),
    3.89 +    m_softTimer (Timer::CANCEL_ON_DESTROY)
    3.90 +{
    3.91 +  m_dlopenHandle = NULL;
    3.92 +  NS_LOG_FUNCTION_NOARGS ();
    3.93 +  NS_LOG_LOGIC("Made a NscTcpL4Protocol "<<this);
    3.94 +}
    3.95 +
    3.96 +NscTcpL4Protocol::~NscTcpL4Protocol ()
    3.97 +{
    3.98 +  NS_LOG_FUNCTION_NOARGS ();
    3.99 +  dlclose(m_dlopenHandle);
   3.100 +}
   3.101 +
   3.102 +void
   3.103 +NscTcpL4Protocol::SetNscLibrary(const std::string &soname)
   3.104 +{
   3.105 +  NS_ASSERT(!m_dlopenHandle);
   3.106 +  m_dlopenHandle = dlopen(soname.c_str (), RTLD_NOW);
   3.107 +  if (m_dlopenHandle == NULL)
   3.108 +    NS_FATAL_ERROR (dlerror());
   3.109 +}
   3.110 +
   3.111 +void 
   3.112 +NscTcpL4Protocol::SetNode (Ptr<Node> node)
   3.113 +{
   3.114 +  m_node = node;
   3.115 +
   3.116 +  if (m_nscStack)
   3.117 +    { // stack has already been loaded...
   3.118 +      return;
   3.119 +    }
   3.120 +
   3.121 +  NS_ASSERT(m_dlopenHandle);
   3.122 +
   3.123 +  FCreateStack create = (FCreateStack)dlsym(m_dlopenHandle, "nsc_create_stack");
   3.124 +  NS_ASSERT(create);
   3.125 +  m_nscStack = create(this, this, external_rand);
   3.126 +  int hzval = m_nscStack->get_hz();
   3.127 +
   3.128 +  NS_ASSERT(hzval > 0);
   3.129 +
   3.130 +  m_softTimer.SetFunction (&NscTcpL4Protocol::SoftInterrupt, this);
   3.131 +  m_softTimer.SetDelay (MilliSeconds (1000/hzval));
   3.132 +  m_nscStack->init(hzval);
   3.133 +  // This enables stack and NSC debug messages
   3.134 +  // m_nscStack->set_diagnostic(1000);
   3.135 +
   3.136 +  Ptr<Ns3NscStack> nscStack = Create<Ns3NscStack> ();
   3.137 +  nscStack->SetStack (m_nscStack);
   3.138 +  node->AggregateObject (nscStack);
   3.139 +
   3.140 +  m_softTimer.Schedule ();
   3.141 +}
   3.142 +
   3.143 +int 
   3.144 +NscTcpL4Protocol::GetProtocolNumber (void) const
   3.145 +{
   3.146 +  return PROT_NUMBER;
   3.147 +}
   3.148 +int 
   3.149 +NscTcpL4Protocol::GetVersion (void) const
   3.150 +{
   3.151 +  return 2;
   3.152 +}
   3.153 +
   3.154 +void
   3.155 +NscTcpL4Protocol::DoDispose (void)
   3.156 +{
   3.157 +  NS_LOG_FUNCTION_NOARGS ();
   3.158 +  if (m_endPoints != 0)
   3.159 +    {
   3.160 +      delete m_endPoints;
   3.161 +      m_endPoints = 0;
   3.162 +    }
   3.163 +  m_node = 0;
   3.164 +  Ipv4L4Protocol::DoDispose ();
   3.165 +}
   3.166 +
   3.167 +Ptr<Socket>
   3.168 +NscTcpL4Protocol::CreateSocket (void)
   3.169 +{
   3.170 +  NS_LOG_FUNCTION_NOARGS ();
   3.171 +  if (!m_nscInterfacesSetUp)
   3.172 +  {
   3.173 +    Ptr<Ipv4> ip = m_node->GetObject<Ipv4> ();
   3.174 +
   3.175 +    const uint32_t nInterfaces = ip->GetNInterfaces ();
   3.176 +    // start from 1, ignore the loopback interface (HACK)
   3.177 +
   3.178 +    NS_ASSERT_MSG (nInterfaces <= 2, "nsc does not support multiple interfaces per node");
   3.179 +
   3.180 +    for (uint32_t i = 1; i < nInterfaces; i++)
   3.181 +    {
   3.182 +      Ipv4Address addr = ip->GetAddress(i);
   3.183 +      Ipv4Mask mask = ip->GetNetworkMask(i);
   3.184 +      uint16_t mtu = ip->GetMtu (i);
   3.185 +
   3.186 +      std::ostringstream addrOss, maskOss;
   3.187 +
   3.188 +      addr.Print(addrOss);
   3.189 +      mask.Print(maskOss);
   3.190 +
   3.191 +      NS_LOG_LOGIC ("if_attach " << addrOss.str().c_str() << " " << maskOss.str().c_str() << " " << mtu);
   3.192 +
   3.193 +      std::string addrStr = addrOss.str();
   3.194 +      std::string maskStr = maskOss.str();
   3.195 +      const char* addrCStr = addrStr.c_str();
   3.196 +      const char* maskCStr = maskStr.c_str();
   3.197 +      m_nscStack->if_attach(addrCStr, maskCStr, mtu);
   3.198 +
   3.199 +      if (i == 1)
   3.200 +      {
   3.201 +        // We need to come up with a default gateway here. Can't guarantee this to be
   3.202 +        // correct really...
   3.203 +
   3.204 +        uint8_t addrBytes[4];
   3.205 +        addr.Serialize(addrBytes);
   3.206 +
   3.207 +        // XXX: this is all a bit of a horrible hack
   3.208 +        //
   3.209 +        // Just increment the last octet, this gives a decent chance of this being
   3.210 +        // 'enough'.
   3.211 +        //
   3.212 +        // All we need is another address on the same network as the interface. This
   3.213 +        // will force the stack to output the packet out of the network interface.
   3.214 +        addrBytes[3]++;
   3.215 +        addr.Deserialize(addrBytes);
   3.216 +        addrOss.str("");
   3.217 +        addr.Print(addrOss);
   3.218 +        m_nscStack->add_default_gateway(addrOss.str().c_str());
   3.219 +      }
   3.220 +    }
   3.221 +    m_nscInterfacesSetUp = true;
   3.222 +  }
   3.223 +
   3.224 +  Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
   3.225 +  Ptr<NscTcpSocketImpl> socket = CreateObject<NscTcpSocketImpl> ();
   3.226 +  socket->SetNode (m_node);
   3.227 +  socket->SetTcp (this);
   3.228 +  socket->SetRtt (rtt);
   3.229 +  return socket;
   3.230 +}
   3.231 +
   3.232 +Ipv4EndPoint *
   3.233 +NscTcpL4Protocol::Allocate (void)
   3.234 +{
   3.235 +  NS_LOG_FUNCTION_NOARGS ();
   3.236 +  return m_endPoints->Allocate ();
   3.237 +}
   3.238 +
   3.239 +Ipv4EndPoint *
   3.240 +NscTcpL4Protocol::Allocate (Ipv4Address address)
   3.241 +{
   3.242 +  NS_LOG_FUNCTION (this << address);
   3.243 +  return m_endPoints->Allocate (address);
   3.244 +}
   3.245 +
   3.246 +Ipv4EndPoint *
   3.247 +NscTcpL4Protocol::Allocate (uint16_t port)
   3.248 +{
   3.249 +  NS_LOG_FUNCTION (this << port);
   3.250 +  return m_endPoints->Allocate (port);
   3.251 +}
   3.252 +
   3.253 +Ipv4EndPoint *
   3.254 +NscTcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
   3.255 +{
   3.256 +  NS_LOG_FUNCTION (this << address << port);
   3.257 +  return m_endPoints->Allocate (address, port);
   3.258 +}
   3.259 +
   3.260 +Ipv4EndPoint *
   3.261 +NscTcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
   3.262 +                         Ipv4Address peerAddress, uint16_t peerPort)
   3.263 +{
   3.264 +  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
   3.265 +  return m_endPoints->Allocate (localAddress, localPort,
   3.266 +                                peerAddress, peerPort);
   3.267 +}
   3.268 +
   3.269 +void 
   3.270 +NscTcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
   3.271 +{
   3.272 +  NS_LOG_FUNCTION (this << endPoint);
   3.273 +  // NSC m_endPoints->DeAllocate (endPoint);
   3.274 +}
   3.275 +
   3.276 +void
   3.277 +NscTcpL4Protocol::Receive (Ptr<Packet> packet,
   3.278 +             Ipv4Address const &source,
   3.279 +             Ipv4Address const &destination,
   3.280 +             Ptr<Ipv4Interface> incomingInterface)
   3.281 +{
   3.282 +  NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface);
   3.283 +  Ipv4Header ipHeader;
   3.284 +  uint32_t packetSize = packet->GetSize();
   3.285 +
   3.286 +  // The way things work at the moment, the IP header has been removed
   3.287 +  // by the ns-3 IPv4 processing code. However, the NSC stack expects
   3.288 +  // a complete IP packet, so we add the IP header back.
   3.289 +  // Since the original header is already gone, we create a new one
   3.290 +  // based on the information we have.
   3.291 +  ipHeader.SetSource (source);
   3.292 +  ipHeader.SetDestination (destination);
   3.293 +  ipHeader.SetProtocol (PROT_NUMBER);
   3.294 +  ipHeader.SetPayloadSize (packetSize);
   3.295 +  ipHeader.SetTtl (1);
   3.296 +  // all NSC stacks check the IP checksum
   3.297 +  ipHeader.EnableChecksum ();
   3.298 +
   3.299 +  packet->AddHeader(ipHeader);
   3.300 +  packetSize = packet->GetSize();
   3.301 +
   3.302 +  const uint8_t *data = const_cast<uint8_t *>(packet->PeekData());
   3.303 +
   3.304 +  // deliver complete packet to the NSC network stack
   3.305 +  m_nscStack->if_receive_packet(0, data, packetSize);
   3.306 +  wakeup ();
   3.307 +}
   3.308 +
   3.309 +void NscTcpL4Protocol::SoftInterrupt (void)
   3.310 +{
   3.311 +  NS_LOG_FUNCTION_NOARGS ();
   3.312 +  m_nscStack->timer_interrupt ();
   3.313 +  m_nscStack->increment_ticks ();
   3.314 +  m_softTimer.Schedule ();
   3.315 +}
   3.316 +
   3.317 +void NscTcpL4Protocol::send_callback(const void* data, int datalen)
   3.318 +{
   3.319 +  Ptr<Packet> p;
   3.320 +
   3.321 +  NS_ASSERT(datalen > (int)sizeof(struct iphdr));
   3.322 +
   3.323 +  const uint8_t *rawdata = reinterpret_cast<const uint8_t *>(data);
   3.324 +  rawdata += sizeof(struct iphdr);
   3.325 +
   3.326 +  const struct iphdr *ipHdr = reinterpret_cast<const struct iphdr *>(data);
   3.327 +
   3.328 +  // create packet, without IP header. The TCP header is not touched.
   3.329 +  // Not using the IP header makes integration easier, but it destroys
   3.330 +  // eg. ECN.
   3.331 +  p = Create<Packet> (rawdata, datalen - sizeof(struct iphdr));
   3.332 +
   3.333 +  Ipv4Address saddr(ntohl(ipHdr->saddr));
   3.334 +  Ipv4Address daddr(ntohl(ipHdr->daddr));
   3.335 +
   3.336 +  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
   3.337 +  if (ipv4 != 0)
   3.338 +    {
   3.339 +      ipv4->Send (p, saddr, daddr, PROT_NUMBER);
   3.340 +    }
   3.341 +  m_nscStack->if_send_finish(0);
   3.342 +}
   3.343 +
   3.344 +void NscTcpL4Protocol::wakeup()
   3.345 +{
   3.346 +  // TODO
   3.347 +  // this should schedule a timer to read from all tcp sockets now... this is
   3.348 +  // an indication that data might be waiting on the socket
   3.349 +
   3.350 +  Ipv4EndPointDemux::EndPoints endPoints = m_endPoints->GetAllEndPoints ();
   3.351 +  for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
   3.352 +       endPoint != endPoints.end (); endPoint++) {
   3.353 +          // NSC HACK: (ab)use TcpSocket::ForwardUp for signalling
   3.354 +          (*endPoint)->ForwardUp (NULL, Ipv4Address(), 0);
   3.355 +  }
   3.356 +}
   3.357 +
   3.358 +void NscTcpL4Protocol::gettime(unsigned int* sec, unsigned int* usec)
   3.359 +{
   3.360 +  // Only used by the Linux network stack, e.g. during ISN generation
   3.361 +  // and in the kernel rng initialization routine. Also used in Linux
   3.362 +  // printk output.
   3.363 +  Time t = Simulator::Now ();
   3.364 +  int64_t us = t.GetMicroSeconds ();
   3.365 +  *sec = us / (1000*1000);
   3.366 +  *usec = us - *sec * (1000*1000);
   3.367 +}
   3.368 +
   3.369 +
   3.370 +}; // namespace ns3
   3.371 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/internet-stack/nsc-tcp-l4-protocol.h	Fri Aug 29 23:08:18 2008 +0200
     4.3 @@ -0,0 +1,121 @@
     4.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     4.5 +/*
     4.6 + * This program is free software; you can redistribute it and/or modify
     4.7 + * it under the terms of the GNU General Public License version 2 as
     4.8 + * published by the Free Software Foundation;
     4.9 + *
    4.10 + * This program is distributed in the hope that it will be useful,
    4.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.13 + * GNU General Public License for more details.
    4.14 + *
    4.15 + * You should have received a copy of the GNU General Public License
    4.16 + * along with this program; if not, write to the Free Software
    4.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.18 + */
    4.19 +
    4.20 +#ifndef NSC_TCP_L4_PROTOCOL_H
    4.21 +#define NSC_TCP_L4_PROTOCOL_H
    4.22 +
    4.23 +#include <stdint.h>
    4.24 +
    4.25 +#include "ns3/packet.h"
    4.26 +#include "ns3/ipv4-address.h"
    4.27 +#include "ns3/ptr.h"
    4.28 +#include "ns3/object-factory.h"
    4.29 +#include "ipv4-end-point-demux.h"
    4.30 +#include "ipv4-l4-protocol.h"
    4.31 +#include "ipv4-interface.h"
    4.32 +
    4.33 +#include "tcp-header.h"
    4.34 +
    4.35 +#include "ns3/timer.h"
    4.36 +#include "nsc/sim/sim_interface.h"
    4.37 +
    4.38 +namespace ns3 {
    4.39 +
    4.40 +class Node;
    4.41 +class Socket;
    4.42 +class TcpHeader;
    4.43 +/**
    4.44 + * \brief Nsc wrapper glue.
    4.45 + */
    4.46 +class NscTcpL4Protocol : public Ipv4L4Protocol, ISendCallback, IInterruptCallback {
    4.47 +public:
    4.48 +  static const uint8_t PROT_NUMBER;
    4.49 +  static TypeId GetTypeId (void);
    4.50 +  /**
    4.51 +   * \brief Constructor
    4.52 +   */
    4.53 +  NscTcpL4Protocol ();
    4.54 +  virtual ~NscTcpL4Protocol ();
    4.55 +
    4.56 +  void SetNode (Ptr<Node> node);
    4.57 +  void SetNscLibrary(const std::string &lib);
    4.58 +
    4.59 +  virtual int GetProtocolNumber (void) const;
    4.60 +  virtual int GetVersion (void) const;
    4.61 +
    4.62 +  /**
    4.63 +   * \return A smart Socket pointer to a NscTcpSocketImpl, allocated by this instance
    4.64 +   * of the TCP protocol
    4.65 +   */
    4.66 +  Ptr<Socket> CreateSocket (void);
    4.67 +
    4.68 +  Ipv4EndPoint *Allocate (void);
    4.69 +  Ipv4EndPoint *Allocate (Ipv4Address address);
    4.70 +  Ipv4EndPoint *Allocate (uint16_t port);
    4.71 +  Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
    4.72 +  Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
    4.73 +                          Ipv4Address peerAddress, uint16_t peerPort);
    4.74 +
    4.75 +  void DeAllocate (Ipv4EndPoint *endPoint);
    4.76 +
    4.77 +  /**
    4.78 +   * \brief Recieve a packet up the protocol stack
    4.79 +   * \param p The Packet to dump the contents into
    4.80 +   * \param source The source's Ipv4Address
    4.81 +   * \param destination The destinations Ipv4Address
    4.82 +   * \param incomingInterface The Ipv4Interface it was received on
    4.83 +   */
    4.84 +  virtual void Receive (Ptr<Packet> p,
    4.85 +                       Ipv4Address const &source,
    4.86 +                       Ipv4Address const &destination,
    4.87 +                       Ptr<Ipv4Interface> incomingInterface);
    4.88 +
    4.89 +  // NSC callbacks.
    4.90 +  // NSC invokes these hooks to interact with the simulator.
    4.91 +  // In any case, these methods are only to be called by NSC.
    4.92 +  //
    4.93 +  // send_callback is invoked by NSCs 'ethernet driver' to re-inject
    4.94 +  // a packet (i.e. an octet soup consisting of an IP Header, TCP Header
    4.95 +  // and user payload, if any), into ns-3.
    4.96 +  virtual void send_callback(const void *data, int datalen);
    4.97 +  // This is called by the NSC stack whenever something of interest
    4.98 +  // has happened, e.g. when data arrives on a socket, a listen socket
    4.99 +  // has a new connection pending, etc.
   4.100 +  virtual void wakeup();
   4.101 +  // This is called by the Linux stack RNG initialization.
   4.102 +  // Its also used by the cradle code to add a timestamp to
   4.103 +  // printk/printf/debug output.
   4.104 +  virtual void gettime(unsigned int *, unsigned int *);
   4.105 +
   4.106 +protected:
   4.107 +  virtual void DoDispose (void);
   4.108 +private:
   4.109 +  Ptr<Node> m_node;
   4.110 +  Ipv4EndPointDemux *m_endPoints;
   4.111 +  ObjectFactory m_rttFactory;
   4.112 +private:
   4.113 +  void SoftInterrupt (void);
   4.114 +  static ObjectFactory GetDefaultRttEstimatorFactory (void);
   4.115 +  friend class NscTcpSocketImpl;
   4.116 +  INetStack* m_nscStack;
   4.117 +  void *m_dlopenHandle;
   4.118 +  bool m_nscInterfacesSetUp;
   4.119 +  Timer m_softTimer;
   4.120 +};
   4.121 +
   4.122 +}; // namespace ns3
   4.123 +
   4.124 +#endif /* NSC_TCP_L4_PROTOCOL_H */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/internet-stack/nsc-tcp-socket-factory-impl.cc	Fri Aug 29 23:08:18 2008 +0200
     5.3 @@ -0,0 +1,50 @@
     5.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     5.5 +/*
     5.6 + * This program is free software; you can redistribute it and/or modify
     5.7 + * it under the terms of the GNU General Public License version 2 as
     5.8 + * published by the Free Software Foundation;
     5.9 + *
    5.10 + * This program is distributed in the hope that it will be useful,
    5.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.13 + * GNU General Public License for more details.
    5.14 + *
    5.15 + * You should have received a copy of the GNU General Public License
    5.16 + * along with this program; if not, write to the Free Software
    5.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.18 + */
    5.19 +#include "nsc-tcp-socket-factory-impl.h"
    5.20 +#include "nsc-tcp-l4-protocol.h"
    5.21 +#include "ns3/socket.h"
    5.22 +#include "ns3/assert.h"
    5.23 +
    5.24 +namespace ns3 {
    5.25 +
    5.26 +NscTcpSocketFactoryImpl::NscTcpSocketFactoryImpl ()
    5.27 +  : m_tcp (0)
    5.28 +{}
    5.29 +NscTcpSocketFactoryImpl::~NscTcpSocketFactoryImpl ()
    5.30 +{
    5.31 +  NS_ASSERT (m_tcp == 0);
    5.32 +}
    5.33 +
    5.34 +void 
    5.35 +NscTcpSocketFactoryImpl::SetTcp (Ptr<NscTcpL4Protocol> tcp)
    5.36 +{
    5.37 +  m_tcp = tcp;
    5.38 +}
    5.39 +
    5.40 +Ptr<Socket>
    5.41 +NscTcpSocketFactoryImpl::CreateSocket (void)
    5.42 +{
    5.43 +  return m_tcp->CreateSocket ();
    5.44 +}
    5.45 +
    5.46 +void 
    5.47 +NscTcpSocketFactoryImpl::DoDispose (void)
    5.48 +{
    5.49 +  m_tcp = 0;
    5.50 +  TcpSocketFactory::DoDispose ();
    5.51 +}
    5.52 +
    5.53 +} // namespace ns3
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/internet-stack/nsc-tcp-socket-factory-impl.h	Fri Aug 29 23:08:18 2008 +0200
     6.3 @@ -0,0 +1,44 @@
     6.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     6.5 +/*
     6.6 + * This program is free software; you can redistribute it and/or modify
     6.7 + * it under the terms of the GNU General Public License version 2 as
     6.8 + * published by the Free Software Foundation;
     6.9 + *
    6.10 + * This program is distributed in the hope that it will be useful,
    6.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.13 + * GNU General Public License for more details.
    6.14 + *
    6.15 + * You should have received a copy of the GNU General Public License
    6.16 + * along with this program; if not, write to the Free Software
    6.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.18 + */
    6.19 +#ifndef NSC_TCP_SOCKET_FACTORY_IMPL_H
    6.20 +#define NSC_TCP_SOCKET_FACTORY_IMPL_H
    6.21 +
    6.22 +#include "ns3/tcp-socket-factory.h"
    6.23 +#include "ns3/ptr.h"
    6.24 +
    6.25 +namespace ns3 {
    6.26 +
    6.27 +class NscTcpL4Protocol;
    6.28 +
    6.29 +class NscTcpSocketFactoryImpl : public TcpSocketFactory
    6.30 +{
    6.31 +public:
    6.32 +  NscTcpSocketFactoryImpl ();
    6.33 +  virtual ~NscTcpSocketFactoryImpl ();
    6.34 +
    6.35 +  void SetTcp (Ptr<NscTcpL4Protocol> tcp);
    6.36 +
    6.37 +  virtual Ptr<Socket> CreateSocket (void);
    6.38 +
    6.39 +protected:
    6.40 +  virtual void DoDispose (void);
    6.41 +private:
    6.42 +  Ptr<NscTcpL4Protocol> m_tcp;
    6.43 +};
    6.44 +
    6.45 +} // namespace ns3
    6.46 +
    6.47 +#endif /* NSC_TCP_SOCKET_FACTORY_IMPL_H */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/internet-stack/nsc-tcp-socket-impl.cc	Fri Aug 29 23:08:18 2008 +0200
     7.3 @@ -0,0 +1,842 @@
     7.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     7.5 +/*
     7.6 + * This program is free software; you can redistribute it and/or modify
     7.7 + * it under the terms of the GNU General Public License version 2 as
     7.8 + * published by the Free Software Foundation;
     7.9 + *
    7.10 + * This program is distributed in the hope that it will be useful,
    7.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.13 + * GNU General Public License for more details.
    7.14 + *
    7.15 + * You should have received a copy of the GNU General Public License
    7.16 + * along with this program; if not, write to the Free Software
    7.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.18 + *
    7.19 + * based on tcp-socket-impl.cc, Author: Raj Bhattacharjea <raj.b@gatech.edu>
    7.20 + * Author: Florian Westphal <fw@strlen.de>
    7.21 + */
    7.22 +
    7.23 +#include "ns3/node.h"
    7.24 +#include "ns3/inet-socket-address.h"
    7.25 +#include "ns3/log.h"
    7.26 +#include "ns3/ipv4.h"
    7.27 +#include "ipv4-end-point.h"
    7.28 +#include "ipv4-l4-demux.h"
    7.29 +#include "nsc-tcp-l4-protocol.h"
    7.30 +#include "nsc-tcp-socket-impl.h"
    7.31 +#include "ns3/simulation-singleton.h"
    7.32 +#include "tcp-typedefs.h"
    7.33 +#include "ns3/simulator.h"
    7.34 +#include "ns3/packet.h"
    7.35 +#include "ns3/uinteger.h"
    7.36 +#include "ns3/trace-source-accessor.h"
    7.37 +
    7.38 +#include <algorithm>
    7.39 +
    7.40 +#include <sys/socket.h>
    7.41 +#include <netinet/in.h>
    7.42 +#include <arpa/inet.h>
    7.43 +#include <netinet/ip.h>
    7.44 +#include <netinet/tcp.h>
    7.45 +
    7.46 +#include "nsc/sim/sim_errno.h"
    7.47 +
    7.48 +NS_LOG_COMPONENT_DEFINE ("NscTcpSocketImpl");
    7.49 +
    7.50 +using namespace std;
    7.51 +
    7.52 +namespace ns3 {
    7.53 +
    7.54 +NS_OBJECT_ENSURE_REGISTERED (NscTcpSocketImpl);
    7.55 +
    7.56 +TypeId
    7.57 +NscTcpSocketImpl::GetTypeId ()
    7.58 +{
    7.59 +  static TypeId tid = TypeId("ns3::NscTcpSocketImpl")
    7.60 +    .SetParent<TcpSocket> ()
    7.61 +    .AddTraceSource ("CongestionWindow",
    7.62 +                     "The TCP connection's congestion window",
    7.63 +                     MakeTraceSourceAccessor (&NscTcpSocketImpl::m_cWnd))
    7.64 +    ;
    7.65 +  return tid;
    7.66 +}
    7.67 +
    7.68 +  NscTcpSocketImpl::NscTcpSocketImpl ()
    7.69 +  : m_endPoint (0),
    7.70 +    m_node (0),
    7.71 +    m_tcp (0),
    7.72 +    m_peerAddress ("0.0.0.0", 0),
    7.73 +    m_errno (ERROR_NOTERROR),
    7.74 +    m_shutdownSend (false),
    7.75 +    m_shutdownRecv (false),
    7.76 +    m_connected (false),
    7.77 +    m_state (CLOSED),
    7.78 +    m_closeOnEmpty (false),
    7.79 +    m_txBufferSize (0),
    7.80 +    m_rtt (0),
    7.81 +    m_lastMeasuredRtt (Seconds(0.0))
    7.82 +{
    7.83 +  NS_LOG_FUNCTION (this);
    7.84 +}
    7.85 +
    7.86 +NscTcpSocketImpl::NscTcpSocketImpl(const NscTcpSocketImpl& sock)
    7.87 +  : TcpSocket(sock), //copy the base class callbacks
    7.88 +    m_delAckMaxCount (sock.m_delAckMaxCount),
    7.89 +    m_delAckTimeout (sock.m_delAckTimeout),
    7.90 +    m_endPoint (0),
    7.91 +    m_node (sock.m_node),
    7.92 +    m_tcp (sock.m_tcp),
    7.93 +    m_remoteAddress (sock.m_remoteAddress),
    7.94 +    m_remotePort (sock.m_remotePort),
    7.95 +    m_localAddress (sock.m_localAddress),
    7.96 +    m_localPort (sock.m_localPort),
    7.97 +    m_peerAddress (sock.m_peerAddress),
    7.98 +    m_errno (sock.m_errno),
    7.99 +    m_shutdownSend (sock.m_shutdownSend),
   7.100 +    m_shutdownRecv (sock.m_shutdownRecv),
   7.101 +    m_connected (sock.m_connected),
   7.102 +    m_state (sock.m_state),
   7.103 +    m_closeOnEmpty (sock.m_closeOnEmpty),
   7.104 +    m_segmentSize (sock.m_segmentSize),
   7.105 +    m_rxWindowSize (sock.m_rxWindowSize),
   7.106 +    m_advertisedWindowSize (sock.m_advertisedWindowSize),
   7.107 +    m_cWnd (sock.m_cWnd),
   7.108 +    m_ssThresh (sock.m_ssThresh),
   7.109 +    m_initialCWnd (sock.m_initialCWnd),
   7.110 +    m_rtt (0),
   7.111 +    m_lastMeasuredRtt (Seconds(0.0)),
   7.112 +    m_cnTimeout (sock.m_cnTimeout),
   7.113 +    m_cnCount (sock.m_cnCount),
   7.114 +    m_rxAvailable (0),
   7.115 +    m_nscTcpSocket (0),
   7.116 +    m_sndBufSize (sock.m_sndBufSize)
   7.117 +{
   7.118 +  NS_LOG_FUNCTION_NOARGS ();
   7.119 +  NS_LOG_LOGIC("Invoked the copy constructor");
   7.120 +  //copy the pending data if necessary
   7.121 +  if(!sock.m_txBuffer.empty () )
   7.122 +    {
   7.123 +      m_txBuffer = sock.m_txBuffer;
   7.124 +    }
   7.125 +  //copy the rtt if necessary
   7.126 +  if (sock.m_rtt)
   7.127 +    {
   7.128 +      m_rtt = sock.m_rtt->Copy();
   7.129 +    }
   7.130 +  //can't "copy" the endpoint just yes, must do this when we know the peer info
   7.131 +  //too; this is in SYN_ACK_TX
   7.132 +}
   7.133 +
   7.134 +NscTcpSocketImpl::~NscTcpSocketImpl ()
   7.135 +{
   7.136 +  NS_LOG_FUNCTION(this);
   7.137 +  m_node = 0;
   7.138 +  if (m_endPoint != 0)
   7.139 +    {
   7.140 +      NS_ASSERT (m_tcp != 0);
   7.141 +      /**
   7.142 +       * Note that this piece of code is a bit tricky:
   7.143 +       * when DeAllocate is called, it will call into
   7.144 +       * Ipv4EndPointDemux::Deallocate which triggers
   7.145 +       * a delete of the associated endPoint which triggers
   7.146 +       * in turn a call to the method ::Destroy below
   7.147 +       * will will zero the m_endPoint field.
   7.148 +       */
   7.149 +      NS_ASSERT (m_endPoint != 0);
   7.150 +      m_tcp->DeAllocate (m_endPoint);
   7.151 +      NS_ASSERT (m_endPoint == 0);
   7.152 +    }
   7.153 +  m_tcp = 0;
   7.154 +}
   7.155 +
   7.156 +void
   7.157 +NscTcpSocketImpl::SetNode (Ptr<Node> node)
   7.158 +{
   7.159 +  m_node = node;
   7.160 +  // Initialize some variables 
   7.161 +  m_cWnd = m_initialCWnd * m_segmentSize;
   7.162 +  m_rxWindowSize = m_advertisedWindowSize;
   7.163 +}
   7.164 +
   7.165 +void 
   7.166 +NscTcpSocketImpl::SetTcp (Ptr<NscTcpL4Protocol> tcp)
   7.167 +{
   7.168 +  m_nscTcpSocket = tcp->m_nscStack->new_tcp_socket();
   7.169 +  m_tcp = tcp;
   7.170 +}
   7.171 +void 
   7.172 +NscTcpSocketImpl::SetRtt (Ptr<RttEstimator> rtt)
   7.173 +{
   7.174 +  m_rtt = rtt;
   7.175 +}
   7.176 +
   7.177 +
   7.178 +enum Socket::SocketErrno
   7.179 +NscTcpSocketImpl::GetErrno (void) const
   7.180 +{
   7.181 +  NS_LOG_FUNCTION_NOARGS ();
   7.182 +  return m_errno;
   7.183 +}
   7.184 +
   7.185 +Ptr<Node>
   7.186 +NscTcpSocketImpl::GetNode (void) const
   7.187 +{
   7.188 +  NS_LOG_FUNCTION_NOARGS ();
   7.189 +  return m_node;
   7.190 +}
   7.191 +
   7.192 +void 
   7.193 +NscTcpSocketImpl::Destroy (void)
   7.194 +{
   7.195 +  NS_LOG_FUNCTION_NOARGS ();
   7.196 +  m_node = 0;
   7.197 +  m_endPoint = 0;
   7.198 +  m_tcp = 0;
   7.199 +}
   7.200 +int
   7.201 +NscTcpSocketImpl::FinishBind (void)
   7.202 +{
   7.203 +  NS_LOG_FUNCTION_NOARGS ();
   7.204 +  if (m_endPoint == 0)
   7.205 +    {
   7.206 +      return -1;
   7.207 +    }
   7.208 +  m_endPoint->SetRxCallback (MakeCallback (&NscTcpSocketImpl::ForwardUp, Ptr<NscTcpSocketImpl>(this)));
   7.209 +  m_endPoint->SetDestroyCallback (MakeCallback (&NscTcpSocketImpl::Destroy, Ptr<NscTcpSocketImpl>(this)));
   7.210 +  m_localAddress = m_endPoint->GetLocalAddress ();
   7.211 +  m_localPort = m_endPoint->GetLocalPort ();
   7.212 +  return 0;
   7.213 +}
   7.214 +
   7.215 +int
   7.216 +NscTcpSocketImpl::Bind (void)
   7.217 +{
   7.218 +  NS_LOG_FUNCTION_NOARGS ();
   7.219 +  m_endPoint = m_tcp->Allocate ();
   7.220 +  return FinishBind ();
   7.221 +}
   7.222 +int 
   7.223 +NscTcpSocketImpl::Bind (const Address &address)
   7.224 +{
   7.225 +  NS_LOG_FUNCTION (this<<address);
   7.226 +  if (!InetSocketAddress::IsMatchingType (address))
   7.227 +    {
   7.228 +      return ERROR_INVAL;
   7.229 +    }
   7.230 +  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   7.231 +  Ipv4Address ipv4 = transport.GetIpv4 ();
   7.232 +  uint16_t port = transport.GetPort ();
   7.233 +  if (ipv4 == Ipv4Address::GetAny () && port == 0)
   7.234 +    {
   7.235 +      m_endPoint = m_tcp->Allocate ();
   7.236 +      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
   7.237 +    }
   7.238 +  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
   7.239 +    {
   7.240 +      m_endPoint = m_tcp->Allocate (port);
   7.241 +      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
   7.242 +    }
   7.243 +  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
   7.244 +    {
   7.245 +      m_endPoint = m_tcp->Allocate (ipv4);
   7.246 +      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
   7.247 +    }
   7.248 +  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
   7.249 +    {
   7.250 +      m_endPoint = m_tcp->Allocate (ipv4, port);
   7.251 +      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
   7.252 +    }
   7.253 +
   7.254 +  m_localPort = port;
   7.255 +  return FinishBind ();
   7.256 +}
   7.257 +
   7.258 +int 
   7.259 +NscTcpSocketImpl::ShutdownSend (void)
   7.260 +{
   7.261 +  NS_LOG_FUNCTION_NOARGS ();
   7.262 +  m_shutdownSend = true;
   7.263 +  return 0;
   7.264 +}
   7.265 +int 
   7.266 +NscTcpSocketImpl::ShutdownRecv (void)
   7.267 +{
   7.268 +  NS_LOG_FUNCTION_NOARGS ();
   7.269 +  m_shutdownRecv = false;
   7.270 +  return 0;
   7.271 +}
   7.272 +
   7.273 +int
   7.274 +NscTcpSocketImpl::Close (void)
   7.275 +{
   7.276 +  NS_LOG_FUNCTION (this << m_state);
   7.277 +
   7.278 +  if (m_state == CLOSED)
   7.279 +    {
   7.280 +      return -1;
   7.281 +    }
   7.282 +  if (!m_txBuffer.empty ())
   7.283 +    { // App close with pending data must wait until all data transmitted
   7.284 +      m_closeOnEmpty = true;
   7.285 +      NS_LOG_LOGIC("Socket " << this << 
   7.286 +                   " deferring close, state " << m_state);
   7.287 +      return 0;
   7.288 +    }
   7.289 +
   7.290 +  m_nscTcpSocket->disconnect();
   7.291 +  m_state = CLOSED;
   7.292 +  ShutdownSend ();
   7.293 +  return 0;
   7.294 +}
   7.295 +
   7.296 +int
   7.297 +NscTcpSocketImpl::Connect (const Address & address)
   7.298 +{
   7.299 +  NS_LOG_FUNCTION (this << address);
   7.300 +  if (m_endPoint == 0)
   7.301 +    {
   7.302 +      if (Bind () == -1)
   7.303 +        {
   7.304 +          NS_ASSERT (m_endPoint == 0);
   7.305 +          return -1;
   7.306 +        }
   7.307 +      NS_ASSERT (m_endPoint != 0);
   7.308 +    }
   7.309 +  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   7.310 +  m_remoteAddress = transport.GetIpv4 ();
   7.311 +  m_remotePort = transport.GetPort ();
   7.312 +
   7.313 +  struct in_addr remoteAddr;
   7.314 +  uint32_t addr32;
   7.315 +
   7.316 +  m_remoteAddress.Serialize((uint8_t*)&addr32);
   7.317 +  remoteAddr.s_addr = addr32;
   7.318 +
   7.319 +  m_nscTcpSocket->connect(inet_ntoa(remoteAddr), m_remotePort);
   7.320 +  m_state = SYN_SENT;
   7.321 +  return 0;
   7.322 +}
   7.323 +
   7.324 +int
   7.325 +NscTcpSocketImpl::Send (const Ptr<Packet> p, uint32_t flags)
   7.326 +{
   7.327 +  NS_LOG_FUNCTION (this << p);
   7.328 +
   7.329 +  NS_ASSERT (p->GetSize () > 0);
   7.330 +  if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
   7.331 +  {
   7.332 +    if (p->GetSize () > GetTxAvailable ())
   7.333 +    {
   7.334 +      m_errno = ERROR_MSGSIZE;
   7.335 +      return -1;
   7.336 +    }
   7.337 +
   7.338 +    bool txEmpty = m_txBuffer.empty();
   7.339 +    if (m_state == ESTABLISHED)
   7.340 +      {
   7.341 +        if (txEmpty)
   7.342 +          {
   7.343 +            m_txBuffer.push(p);
   7.344 +            m_txBufferSize += p->GetSize ();
   7.345 +          }
   7.346 +        if (!SendPendingData())
   7.347 +          {
   7.348 +             if (m_errno == ERROR_AGAIN)
   7.349 +               {
   7.350 +                 return txEmpty ? p->GetSize () : -1;
   7.351 +               }
   7.352 +             if (txEmpty)
   7.353 +               {
   7.354 +                  m_txBuffer.pop ();
   7.355 +                  m_txBufferSize = 0;
   7.356 +               }
   7.357 +             return -1;
   7.358 +          }
   7.359 +      }
   7.360 +      else
   7.361 +      {  // SYN_SET -- Queue Data
   7.362 +         m_txBuffer.push(p);
   7.363 +         m_txBufferSize += p->GetSize ();
   7.364 +      }
   7.365 +    return p->GetSize ();
   7.366 +  }
   7.367 +  else
   7.368 +  {
   7.369 +    m_errno = ERROR_NOTCONN;
   7.370 +    return -1;
   7.371 +  }
   7.372 +}
   7.373 +
   7.374 +int
   7.375 +NscTcpSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
   7.376 +{
   7.377 +  NS_LOG_FUNCTION (this << address << p);
   7.378 +  if (!m_connected)
   7.379 +    {
   7.380 +      m_errno = ERROR_NOTCONN;
   7.381 +      return -1;
   7.382 +    }
   7.383 +  else
   7.384 +    {
   7.385 +      return Send (p, flags); //drop the address according to BSD manpages
   7.386 +    }
   7.387 +}
   7.388 +
   7.389 +uint32_t
   7.390 +NscTcpSocketImpl::GetTxAvailable (void) const
   7.391 +{
   7.392 +  NS_LOG_FUNCTION_NOARGS ();
   7.393 +  if (m_txBufferSize != 0)
   7.394 +    {
   7.395 +      NS_ASSERT (m_txBufferSize <= m_sndBufSize);
   7.396 +      return m_sndBufSize - m_txBufferSize;
   7.397 +    }
   7.398 +  else
   7.399 +    {
   7.400 +      return m_sndBufSize;
   7.401 +    }
   7.402 +}
   7.403 +
   7.404 +int
   7.405 +NscTcpSocketImpl::Listen (uint32_t q)
   7.406 +{
   7.407 +  NS_LOG_FUNCTION (this << q);
   7.408 +  m_nscTcpSocket->listen(m_localPort);
   7.409 +  m_state = LISTEN;
   7.410 +  return 0;
   7.411 +}
   7.412 +
   7.413 +
   7.414 +void
   7.415 +NscTcpSocketImpl::NSCWakeup ()
   7.416 +{
   7.417 +  switch (m_state) {
   7.418 +  case SYN_SENT:
   7.419 +      if (!m_nscTcpSocket->is_connected())
   7.420 +          break;
   7.421 +      m_state = ESTABLISHED;
   7.422 +      Simulator::ScheduleNow(&NscTcpSocketImpl::ConnectionSucceeded, this);
   7.423 +      // fall through to schedule read/write events
   7.424 +  case ESTABLISHED:
   7.425 +      if (!m_txBuffer.empty ())
   7.426 +          Simulator::ScheduleNow(&NscTcpSocketImpl::SendPendingData, this);
   7.427 +      Simulator::ScheduleNow(&NscTcpSocketImpl::ReadPendingData, this);
   7.428 +      break;
   7.429 +  case LISTEN:
   7.430 +      Simulator::ScheduleNow(&NscTcpSocketImpl::Accept, this);
   7.431 +      break;
   7.432 +  case CLOSED: break;
   7.433 +  default:
   7.434 +      NS_LOG_DEBUG (this << " invalid state: " << m_state);
   7.435 +  }
   7.436 +}
   7.437 +
   7.438 +Ptr<Packet>
   7.439 +NscTcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
   7.440 +{
   7.441 +  NS_LOG_FUNCTION_NOARGS ();
   7.442 +  if (m_deliveryQueue.empty() )
   7.443 +    {
   7.444 +      return 0;
   7.445 +    }
   7.446 +  Ptr<Packet> p = m_deliveryQueue.front ();
   7.447 +  if (p->GetSize () <= maxSize)
   7.448 +    {
   7.449 +      m_deliveryQueue.pop ();
   7.450 +      m_rxAvailable -= p->GetSize ();
   7.451 +    }
   7.452 +  else
   7.453 +    {
   7.454 +      p = 0;
   7.455 +    }
   7.456 +  return p;
   7.457 +}
   7.458 +
   7.459 +Ptr<Packet>
   7.460 +NscTcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
   7.461 +  Address &fromAddress)
   7.462 +{
   7.463 +  NS_LOG_FUNCTION (this << maxSize << flags);
   7.464 +  Ptr<Packet> packet = Recv (maxSize, flags);
   7.465 +  if (packet != 0)
   7.466 +    {
   7.467 +      SocketAddressTag tag;
   7.468 +      bool found;
   7.469 +      found = packet->FindFirstMatchingTag (tag);
   7.470 +      NS_ASSERT (found);
   7.471 +      fromAddress = tag.GetAddress ();
   7.472 +    }
   7.473 +  return packet;
   7.474 +}
   7.475 +
   7.476 +uint32_t
   7.477 +NscTcpSocketImpl::GetRxAvailable (void) const
   7.478 +{
   7.479 +  NS_LOG_FUNCTION_NOARGS ();
   7.480 +  // We separately maintain this state to avoid walking the queue 
   7.481 +  // every time this might be called
   7.482 +  return m_rxAvailable;
   7.483 +}
   7.484 +
   7.485 +void
   7.486 +NscTcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
   7.487 +{
   7.488 +  NSCWakeup();
   7.489 +}
   7.490 +
   7.491 +void NscTcpSocketImpl::CompleteFork(void)
   7.492 +{
   7.493 +  // The address pairs (m_localAddress, m_localPort, m_remoteAddress, m_remotePort)
   7.494 +  // are bogus, but this isn't important at the moment, because
   7.495 +  // address <-> Socket handling is done by NSC internally.
   7.496 +  // We only need to add the new ns-3 socket to the list of sockets, so
   7.497 +  // we use plain Allocate() instead of Allocate(m_localAddress, ... )
   7.498 +  uint8_t buf[4];
   7.499 +  int port;
   7.500 +  size_t buflen = sizeof(buf);
   7.501 +
   7.502 +  if (0 == m_nscTcpSocket->getpeername((void *) buf, &buflen, &port)) {
   7.503 +    m_remotePort = ntohs(port);
   7.504 +    m_remoteAddress = m_remoteAddress.Deserialize(buf);
   7.505 +    m_peerAddress = InetSocketAddress(m_remoteAddress, m_remotePort);
   7.506 +  }
   7.507 +
   7.508 +  m_endPoint = m_tcp->Allocate ();
   7.509 +
   7.510 +  //the cloned socket with be in listen state, so manually change state
   7.511 +  NS_ASSERT(m_state == LISTEN);
   7.512 +  m_state = ESTABLISHED;
   7.513 +
   7.514 +  buflen = sizeof(buf);
   7.515 +  if (0 == m_nscTcpSocket->getsockname((void *) &buf, &buflen, &port))
   7.516 +    m_localAddress = m_localAddress.Deserialize(buf);
   7.517 +
   7.518 +  NS_LOG_LOGIC ("NscTcpSocketImpl " << this << " accepted connection from " 
   7.519 +                 << m_remoteAddress << ":" << m_remotePort
   7.520 +                 << " to " << m_localAddress << ":" << m_localPort);
   7.521 +  //equivalent to FinishBind
   7.522 +  m_endPoint->SetRxCallback (MakeCallback (&NscTcpSocketImpl::ForwardUp, Ptr<NscTcpSocketImpl>(this)));
   7.523 +  m_endPoint->SetDestroyCallback (MakeCallback (&NscTcpSocketImpl::Destroy, Ptr<NscTcpSocketImpl>(this)));
   7.524 +
   7.525 +  NotifyNewConnectionCreated (this, m_peerAddress);
   7.526 +}
   7.527 +
   7.528 +void NscTcpSocketImpl::ConnectionSucceeded()
   7.529 +{ // We would preferred to have scheduled an event directly to
   7.530 +  // NotifyConnectionSucceeded, but (sigh) these are protected
   7.531 +  // and we can get the address of it :(
   7.532 +
   7.533 +  uint8_t buf[4];
   7.534 +  int port;
   7.535 +  size_t buflen = sizeof(buf);
   7.536 +  if (0 == m_nscTcpSocket->getsockname((void *) &buf, &buflen, &port)) {
   7.537 +    m_localAddress = m_localAddress.Deserialize(buf);
   7.538 +    m_localPort = ntohs(port);
   7.539 +  }
   7.540 +
   7.541 +  NS_LOG_LOGIC ("NscTcpSocketImpl " << this << " connected to "
   7.542 +                 << m_remoteAddress << ":" << m_remotePort
   7.543 +                 << " from " << m_localAddress << ":" << m_localPort);
   7.544 +  NotifyConnectionSucceeded();
   7.545 +}
   7.546 +
   7.547 +
   7.548 +bool NscTcpSocketImpl::Accept (void)
   7.549 +{
   7.550 +  if (m_state == CLOSED)
   7.551 +    {  // Happens if application closes listening socket after Accept() was scheduled.
   7.552 +      return false;
   7.553 +    }
   7.554 +  NS_ASSERT (m_state == LISTEN);
   7.555 +
   7.556 +  if (!m_nscTcpSocket->is_listening())
   7.557 +    {
   7.558 +      return false;
   7.559 +    }
   7.560 +  INetStreamSocket *newsock;
   7.561 +  int res = m_nscTcpSocket->accept(&newsock);
   7.562 +  if (res != 0)
   7.563 +    {
   7.564 +      return false;
   7.565 +    }
   7.566 +// We could obtain a fromAddress using getpeername, but we've already
   7.567 +// finished the tcp handshake here, i.e. this is a new connection
   7.568 +// and not a connection request.
   7.569 +// if (!NotifyConnectionRequest(fromAddress))
   7.570 +//   return true;
   7.571 +
   7.572 +  // Clone the socket
   7.573 +  Ptr<NscTcpSocketImpl> newSock = Copy ();
   7.574 +  newSock->m_nscTcpSocket = newsock;
   7.575 +  NS_LOG_LOGIC ("Cloned a NscTcpSocketImpl " << newSock);
   7.576 +
   7.577 +  Simulator::ScheduleNow (&NscTcpSocketImpl::CompleteFork, newSock);
   7.578 +  return true;
   7.579 +}
   7.580 +
   7.581 +bool NscTcpSocketImpl::ReadPendingData (void)
   7.582 +{
   7.583 +  if (m_state != ESTABLISHED)
   7.584 +    {
   7.585 +      return false;
   7.586 +    }
   7.587 +  int len, err;
   7.588 +  uint8_t buffer[8192];
   7.589 +  len = sizeof(buffer);
   7.590 +  m_errno = ERROR_NOTERROR;
   7.591 +  err = m_nscTcpSocket->read_data(buffer, &len);
   7.592 +  if (err == 0 && len == 0)
   7.593 +    {
   7.594 +      NS_LOG_LOGIC ("ReadPendingData got EOF from socket");
   7.595 +      m_state = CLOSED;
   7.596 +      return false;
   7.597 +    }
   7.598 +  m_errno = GetNativeNs3Errno(err);
   7.599 +  switch (m_errno)
   7.600 +    {
   7.601 +      case ERROR_NOTERROR: break; // some data was sent
   7.602 +      case ERROR_AGAIN: return false;
   7.603 +      default:
   7.604 +        NS_LOG_WARN ("Error (" << err << ") " <<
   7.605 +                     "during read_data, ns-3 errno set to" << m_errno);
   7.606 +        m_state = CLOSED;
   7.607 +        return false;
   7.608 +    }
   7.609 +
   7.610 +  Ptr<Packet> p =  Create<Packet> (buffer, len);
   7.611 +
   7.612 +  SocketAddressTag tag;
   7.613 +
   7.614 +  tag.SetAddress (m_peerAddress);
   7.615 +  p->AddTag (tag);
   7.616 +  m_deliveryQueue.push (p);
   7.617 +  m_rxAvailable += p->GetSize ();
   7.618 +
   7.619 +  NotifyDataRecv ();
   7.620 +  return true;
   7.621 +}
   7.622 +
   7.623 +bool NscTcpSocketImpl::SendPendingData (void)
   7.624 +{
   7.625 +  NS_LOG_FUNCTION (this);
   7.626 +  NS_LOG_LOGIC ("ENTERING SendPendingData");
   7.627 +
   7.628 +  if (m_txBuffer.empty ())
   7.629 +    {
   7.630 +      return false;
   7.631 +    }
   7.632 +
   7.633 +  int ret;
   7.634 +  size_t size, written = 0;
   7.635 +
   7.636 +  do {
   7.637 +    Ptr<Packet> &p = m_txBuffer.front ();
   7.638 +    size = p->GetSize ();
   7.639 +    NS_ASSERT (size > 0);
   7.640 +
   7.641 +    m_errno = ERROR_NOTERROR;
   7.642 +    ret = m_nscTcpSocket->send_data((const char *)p->PeekData (), size);
   7.643 +    if (ret <= 0)
   7.644 +      {
   7.645 +        m_errno = GetNativeNs3Errno(ret);
   7.646 +        if (m_errno != ERROR_AGAIN)
   7.647 +          {
   7.648 +            NS_LOG_WARN ("Error (" << ret << ") " <<
   7.649 +                         "during send_data, ns-3 errno set to" << m_errno);
   7.650 +          }
   7.651 +        break;
   7.652 +      }
   7.653 +    written += ret;
   7.654 +
   7.655 +    NS_ASSERT (m_txBufferSize >= (size_t)ret);
   7.656 +    m_txBufferSize -= ret;
   7.657 +
   7.658 +    if ((size_t)ret < size)
   7.659 +      {
   7.660 +        p->RemoveAtStart(ret);
   7.661 +        break;
   7.662 +      }
   7.663 +
   7.664 +    m_txBuffer.pop ();
   7.665 +
   7.666 +    if (m_txBuffer.empty ())
   7.667 +      {
   7.668 +        if (m_closeOnEmpty)
   7.669 +          {
   7.670 +            m_nscTcpSocket->disconnect();
   7.671 +            m_state = CLOSED;
   7.672 +          }
   7.673 +        break;
   7.674 +      }
   7.675 +  } while ((size_t) ret == size);
   7.676 +
   7.677 +  if (written > 0)
   7.678 +    {
   7.679 +      Simulator::ScheduleNow(&NscTcpSocketImpl::NotifyDataSent, this, ret);
   7.680 +      return true;
   7.681 +    }
   7.682 +  return false;
   7.683 +}
   7.684 +
   7.685 +Ptr<NscTcpSocketImpl> NscTcpSocketImpl::Copy ()
   7.686 +{
   7.687 +  return CopyObject<NscTcpSocketImpl> (this);
   7.688 +}
   7.689 +
   7.690 +void
   7.691 +NscTcpSocketImpl::SetSndBufSize (uint32_t size)
   7.692 +{
   7.693 +  m_sndBufSize = size;
   7.694 +}
   7.695 +
   7.696 +uint32_t
   7.697 +NscTcpSocketImpl::GetSndBufSize (void) const
   7.698 +{
   7.699 +  return m_sndBufSize;
   7.700 +}
   7.701 +
   7.702 +void
   7.703 +NscTcpSocketImpl::SetRcvBufSize (uint32_t size)
   7.704 +{
   7.705 +  m_rcvBufSize = size;
   7.706 +}
   7.707 +
   7.708 +uint32_t
   7.709 +NscTcpSocketImpl::GetRcvBufSize (void) const
   7.710 +{
   7.711 +  return m_rcvBufSize;
   7.712 +}
   7.713 +
   7.714 +void
   7.715 +NscTcpSocketImpl::SetSegSize (uint32_t size)
   7.716 +{
   7.717 +  m_segmentSize = size;
   7.718 +}
   7.719 +
   7.720 +uint32_t
   7.721 +NscTcpSocketImpl::GetSegSize (void) const
   7.722 +{
   7.723 +  return m_segmentSize;
   7.724 +}
   7.725 +
   7.726 +void
   7.727 +NscTcpSocketImpl::SetAdvWin (uint32_t window)
   7.728 +{
   7.729 +  m_advertisedWindowSize = window;
   7.730 +}
   7.731 +
   7.732 +uint32_t
   7.733 +NscTcpSocketImpl::GetAdvWin (void) const
   7.734 +{
   7.735 +  return m_advertisedWindowSize;
   7.736 +}
   7.737 +
   7.738 +void
   7.739 +NscTcpSocketImpl::SetSSThresh (uint32_t threshold)
   7.740 +{
   7.741 +  m_ssThresh = threshold;
   7.742 +}
   7.743 +
   7.744 +uint32_t
   7.745 +NscTcpSocketImpl::GetSSThresh (void) const
   7.746 +{
   7.747 +  return m_ssThresh;
   7.748 +}
   7.749 +
   7.750 +void
   7.751 +NscTcpSocketImpl::SetInitialCwnd (uint32_t cwnd)
   7.752 +{
   7.753 +  m_initialCWnd = cwnd;
   7.754 +}
   7.755 +
   7.756 +uint32_t
   7.757 +NscTcpSocketImpl::GetInitialCwnd (void) const
   7.758 +{
   7.759 +  return m_initialCWnd;
   7.760 +}
   7.761 +
   7.762 +void 
   7.763 +NscTcpSocketImpl::SetConnTimeout (Time timeout)
   7.764 +{
   7.765 +  m_cnTimeout = timeout;
   7.766 +}
   7.767 +
   7.768 +Time
   7.769 +NscTcpSocketImpl::GetConnTimeout (void) const
   7.770 +{
   7.771 +  return m_cnTimeout;
   7.772 +}
   7.773 +
   7.774 +void 
   7.775 +NscTcpSocketImpl::SetConnCount (uint32_t count)
   7.776 +{
   7.777 +  m_cnCount = count;
   7.778 +}
   7.779 +
   7.780 +uint32_t 
   7.781 +NscTcpSocketImpl::GetConnCount (void) const
   7.782 +{
   7.783 +  return m_cnCount;
   7.784 +}
   7.785 +
   7.786 +void 
   7.787 +NscTcpSocketImpl::SetDelAckTimeout (Time timeout)
   7.788 +{
   7.789 +  m_delAckTimeout = timeout;
   7.790 +}
   7.791 +
   7.792 +Time
   7.793 +NscTcpSocketImpl::GetDelAckTimeout (void) const
   7.794 +{
   7.795 +  return m_delAckTimeout;
   7.796 +}
   7.797 +
   7.798 +void
   7.799 +NscTcpSocketImpl::SetDelAckMaxCount (uint32_t count)
   7.800 +{
   7.801 +  m_delAckMaxCount = count;
   7.802 +}
   7.803 +
   7.804 +uint32_t
   7.805 +NscTcpSocketImpl::GetDelAckMaxCount (void) const
   7.806 +{
   7.807 +  return m_delAckMaxCount;
   7.808 +}
   7.809 +
   7.810 +enum Socket::SocketErrno
   7.811 +NscTcpSocketImpl::GetNativeNs3Errno(int error) const
   7.812 +{
   7.813 +  enum nsc_errno err;
   7.814 +
   7.815 +  if (error >= 0)
   7.816 +    {
   7.817 +       return ERROR_NOTERROR;
   7.818 +    }
   7.819 +  err = (enum nsc_errno) error;
   7.820 +  switch (err)
   7.821 +    {
   7.822 +      case NSC_EADDRINUSE: // fallthrough
   7.823 +      case NSC_EADDRNOTAVAIL: return ERROR_AFNOSUPPORT;
   7.824 +      case NSC_EINPROGRESS: // Altough nsc sockets are nonblocking, we pretend they're not.
   7.825 +      case NSC_EAGAIN: return ERROR_AGAIN;
   7.826 +      case NSC_EISCONN: // fallthrough
   7.827 +      case NSC_EALREADY: return ERROR_ISCONN;
   7.828 +      case NSC_ECONNREFUSED: return ERROR_NOROUTETOHOST; // XXX, better mapping?
   7.829 +      case NSC_ECONNRESET: // for no, all of these fall through
   7.830 +      case NSC_EHOSTDOWN:
   7.831 +      case NSC_ENETUNREACH:
   7.832 +      case NSC_EHOSTUNREACH: return ERROR_NOROUTETOHOST;
   7.833 +      case NSC_EMSGSIZE: return ERROR_MSGSIZE;
   7.834 +      case NSC_ENOTCONN: return ERROR_NOTCONN;
   7.835 +      case NSC_ESHUTDOWN: return ERROR_SHUTDOWN;
   7.836 +      case NSC_ETIMEDOUT: return ERROR_NOTCONN; // XXX - this mapping isn't correct
   7.837 +      case NSC_ENOTDIR: // used by eg. sysctl(2). Shouldn't happen normally,
   7.838 +                        // but is triggered by e.g. show_config().
   7.839 +      case NSC_EUNKNOWN: return ERROR_INVAL; // Catches stacks that 'return -1' without real mapping
   7.840 +    }
   7.841 +  NS_ASSERT_MSG(0, "Unknown NSC error");
   7.842 +  return ERROR_INVAL;
   7.843 +}
   7.844 +
   7.845 +}//namespace ns3
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/internet-stack/nsc-tcp-socket-impl.h	Fri Aug 29 23:08:18 2008 +0200
     8.3 @@ -0,0 +1,171 @@
     8.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     8.5 +/*
     8.6 + * This program is free software; you can redistribute it and/or modify
     8.7 + * it under the terms of the GNU General Public License version 2 as
     8.8 + * published by the Free Software Foundation;
     8.9 + *
    8.10 + * This program is distributed in the hope that it will be useful,
    8.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.13 + * GNU General Public License for more details.
    8.14 + *
    8.15 + * You should have received a copy of the GNU General Public License
    8.16 + * along with this program; if not, write to the Free Software
    8.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.18 + */
    8.19 +#ifndef NSC_TCP_SOCKET_IMPL_H
    8.20 +#define NSC_TCP_SOCKET_IMPL_H
    8.21 +
    8.22 +#include <stdint.h>
    8.23 +#include <queue>
    8.24 +#include <vector>
    8.25 +
    8.26 +#include "ns3/callback.h"
    8.27 +#include "ns3/traced-value.h"
    8.28 +#include "ns3/tcp-socket.h"
    8.29 +#include "ns3/ptr.h"
    8.30 +#include "ns3/ipv4-address.h"
    8.31 +#include "ns3/inet-socket-address.h"
    8.32 +#include "ns3/event-id.h"
    8.33 +#include "tcp-typedefs.h"
    8.34 +#include "pending-data.h"
    8.35 +#include "sequence-number.h"
    8.36 +#include "rtt-estimator.h"
    8.37 +
    8.38 +#include "nsc/sim/sim_interface.h"
    8.39 +
    8.40 +namespace ns3 {
    8.41 +
    8.42 +class Ipv4EndPoint;
    8.43 +class Node;
    8.44 +class Packet;
    8.45 +class NscTcpL4Protocol;
    8.46 +class TcpHeader;
    8.47 +
    8.48 +class NscTcpSocketImpl : public TcpSocket
    8.49 +{
    8.50 +public:
    8.51 +  static TypeId GetTypeId (void);
    8.52 +  /**
    8.53 +   * Create an unbound tcp socket.
    8.54 +   */
    8.55 +  NscTcpSocketImpl ();
    8.56 +  NscTcpSocketImpl (const NscTcpSocketImpl& sock);
    8.57 +  virtual ~NscTcpSocketImpl ();
    8.58 +
    8.59 +  void SetNode (Ptr<Node> node);
    8.60 +  void SetTcp (Ptr<NscTcpL4Protocol> tcp);
    8.61 +  void SetRtt (Ptr<RttEstimator> rtt);
    8.62 +
    8.63 +  virtual enum SocketErrno GetErrno (void) const;
    8.64 +  virtual Ptr<Node> GetNode (void) const;
    8.65 +  virtual int Bind (void);
    8.66 +  virtual int Bind (const Address &address);
    8.67 +  virtual int Close (void);
    8.68 +  virtual int ShutdownSend (void);
    8.69 +  virtual int ShutdownRecv (void);
    8.70 +  virtual int Connect(const Address &address);
    8.71 +  virtual int Listen(uint32_t queueLimit);
    8.72 +  virtual uint32_t GetTxAvailable (void) const;
    8.73 +  virtual int Send (Ptr<Packet> p, uint32_t flags);
    8.74 +  virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
    8.75 +  virtual uint32_t GetRxAvailable (void) const;
    8.76 +  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
    8.77 +  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
    8.78 +    Address &fromAddress);
    8.79 +
    8.80 +private:
    8.81 +  void NSCWakeup(void);
    8.82 +  friend class Tcp;
    8.83 +  // invoked by Tcp class
    8.84 +  int FinishBind (void);
    8.85 +  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
    8.86 +  void Destroy (void);
    8.87 +  //methods for state
    8.88 +  bool SendPendingData(void);
    8.89 +  bool ReadPendingData(void);
    8.90 +  bool Accept(void);
    8.91 +  void CompleteFork(void);
    8.92 +  void ConnectionSucceeded();
    8.93 +
    8.94 +  // Manage data tx/rx
    8.95 +  // XXX This should be virtual and overridden
    8.96 +  Ptr<NscTcpSocketImpl> Copy ();
    8.97 +
    8.98 +  // attribute related
    8.99 +  virtual void SetSndBufSize (uint32_t size);
   8.100 +  virtual uint32_t GetSndBufSize (void) const;
   8.101 +  virtual void SetRcvBufSize (uint32_t size);
   8.102 +  virtual uint32_t GetRcvBufSize (void) const;
   8.103 +  virtual void SetSegSize (uint32_t size);
   8.104 +  virtual uint32_t GetSegSize (void) const;
   8.105 +  virtual void SetAdvWin (uint32_t window);
   8.106 +  virtual uint32_t GetAdvWin (void) const;
   8.107 +  virtual void SetSSThresh (uint32_t threshold);
   8.108 +  virtual uint32_t GetSSThresh (void) const;
   8.109 +  virtual void SetInitialCwnd (uint32_t cwnd);
   8.110 +  virtual uint32_t GetInitialCwnd (void) const;
   8.111 +  virtual void SetConnTimeout (Time timeout);
   8.112 +  virtual Time GetConnTimeout (void) const;
   8.113 +  virtual void SetConnCount (uint32_t count);
   8.114 +  virtual uint32_t GetConnCount (void) const;
   8.115 +  virtual void SetDelAckTimeout (Time timeout);
   8.116 +  virtual Time GetDelAckTimeout (void) const;
   8.117 +  virtual void SetDelAckMaxCount (uint32_t count);
   8.118 +  virtual uint32_t GetDelAckMaxCount (void) const;
   8.119 +
   8.120 +  enum Socket::SocketErrno GetNativeNs3Errno(int err) const;
   8.121 +  uint32_t m_delAckMaxCount;
   8.122 +  Time m_delAckTimeout;
   8.123 +
   8.124 +  Ipv4EndPoint *m_endPoint;
   8.125 +  Ptr<Node> m_node;
   8.126 +  Ptr<NscTcpL4Protocol> m_tcp;
   8.127 +  Ipv4Address m_remoteAddress;
   8.128 +  uint16_t m_remotePort;
   8.129 +  //these two are so that the socket/endpoint cloning works
   8.130 +  Ipv4Address m_localAddress;
   8.131 +  uint16_t m_localPort;
   8.132 +  InetSocketAddress m_peerAddress;
   8.133 +  enum SocketErrno m_errno;
   8.134 +  bool m_shutdownSend;
   8.135 +  bool m_shutdownRecv;
   8.136 +  bool m_connected;
   8.137 +  
   8.138 +  //manage the state infomation
   8.139 +  States_t m_state;
   8.140 +  bool m_closeOnEmpty;
   8.141 +
   8.142 +  //needed to queue data when in SYN_SENT state
   8.143 +  std::queue<Ptr<Packet> > m_txBuffer;
   8.144 +  uint32_t m_txBufferSize;
   8.145 +
   8.146 +  // Window management
   8.147 +  uint32_t                       m_segmentSize;          //SegmentSize
   8.148 +  uint32_t                       m_rxWindowSize;
   8.149 +  uint32_t                       m_advertisedWindowSize; //Window to advertise
   8.150 +  TracedValue<uint32_t>          m_cWnd;                 //Congestion window
   8.151 +  uint32_t                       m_ssThresh;             //Slow Start Threshold
   8.152 +  uint32_t                       m_initialCWnd;          //Initial cWnd value
   8.153 +
   8.154 +  // Round trip time estimation
   8.155 +  Ptr<RttEstimator> m_rtt;
   8.156 +  Time m_lastMeasuredRtt;
   8.157 +
   8.158 +  // Timer-related members
   8.159 +  Time              m_cnTimeout; 
   8.160 +  uint32_t          m_cnCount;
   8.161 +
   8.162 +  // Temporary queue for delivering data to application
   8.163 +  std::queue<Ptr<Packet> > m_deliveryQueue;
   8.164 +  uint32_t m_rxAvailable;
   8.165 +  INetStreamSocket* m_nscTcpSocket;
   8.166 +
   8.167 +  // Attributes
   8.168 +  uint32_t m_sndBufSize;   // buffer limit for the outgoing queue
   8.169 +  uint32_t m_rcvBufSize;   // maximum receive socket buffer size
   8.170 +};
   8.171 +
   8.172 +}//namespace ns3
   8.173 +
   8.174 +#endif /* NSC_TCP_SOCKET_IMPL_H */