nsc: core files.
This adds the core network simulation cradle support
code.
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 */