# HG changeset patch # User Gustavo J. A. M. Carneiro # Date 1215796552 -3600 # Node ID 5dd595cb7eba61f7422cf179f331e9c9592eb2db # Parent 48d69d8eac3891b15c1c3057640b24c0f30e6497# Parent 3efa652c47ef2769523825f83bdecc6ae0626aeb merge diff -r 48d69d8eac38 -r 5dd595cb7eba examples/tcp-2way.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/tcp-2way.cc Fri Jul 11 18:15:52 2008 +0100 @@ -0,0 +1,785 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright 2007 University of Washington + * Copyright 2007 Georgia Tech Research Corporation + * Copyright 2008 Sandia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * Sandia is a multiprogram laboratory operated by Sandia + * Corporation, a Lockheed Martin Company, for the United States + * Department of Energy's National Nuclear Security Administration + * under Contract DE-AC04-94AL85000. + * + * Author: David Evensky, Sandia National Labs + * + * includes GPL'ed ns-3-dev code from: + * udp-echo, // ??, (c) U. Wash. 2007 + * tcp-large-transfer // ?? + * packet-sink // Tom Henderson, (c) U. Wash. 2007 + * onoff // George F. Riley, (c) GT Res Corp. 2007 + */ + + +/* NOTE +This isn't really an example file, so don't look to closely at it as a starting +script. It is here for validation of the TCP model. +*/ + +#include +#include +#include +#include +#include +#include + +#include "ns3/core-module.h" +#include "ns3/helper-module.h" +#include "ns3/node-module.h" +#include "ns3/global-route-manager.h" +#include "ns3/simulator-module.h" +#include "ns3/log.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("tcp-2way"); + +//----------defines------------------------------------------------------------- +//define to print more debugging info. +#define VERBOSE_TESTING + +/* define to die because Socket::Recv() is told to + * only read an "undesired" number of bytes + * fails NS_ASSERT in HandleRead because rx_addr_tag + * tag isn't there. + */ +//#define TOO_SMALL_BUG + +//define to print this pointer in NS_LOG_FUNCTION +//#define PRINT_THIS + +/*define to print packet info in HandleRead + *expected output is of the form: + *536:P{536} *bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00] <0|536|884018> + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | | + * | | | | | | | +bytes left + * | | | | | | | to read in + * | | | | | | | sent buffer + * | | | | | | +bytes read in + * | | | | | | this packet if + * | | | | | | header read, + * | | | | | | prints size + * | | | | | | in () + * | | | | | +bytes cur. packet + * | | | | | left to process + * | | | | +mac addr of sender + * | | | +IP addr of sender + * | | +print '*' while processing first chunk in a received packet. + * | | if there are multiple small sent packets, these can appear in + * | | a single packet, and are processed by a do {} while() loop. + * | +rle output of packet::PeekData(), in this case filled with 536 bytes + * | filled with the letter 'P' (brought to you by the letter 'Q' and the + * | number '9' :-)) + * + packet::GetSize() + * + * If there is a header it will look more like: + * 536:N{317}@B.{6}HELLOP{206} *bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00]\ + * <219|317|0> + * 536:N{317}@B.{6}HELLOP{206} bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00]\ + * <0|206(13)|999794> (ArchHeader=HELLO:1000000) + * where you can see that this first packet includes 317 bytes from the + * previous send packet (filled with N) and 13 bytes of header before the 206 + * bytes of payload (filled with P). + */ + +#define RECV_PRINT + +// dcl non-method functions.... +std::string rle(const uint8_t *, int ); +std::ofstream fileOut("tcp-2way.out"); + +//----------class ArchHeader dcl and definition--------------------------------- +/* + * ArchHeader: A toy header that holds a string + * and a uint32_t. The string is an abitrary label + * and the int is used as the length of the payload. + */ + +class ArchHeader : public Header { +public: + virtual uint32_t GetSerializedSize (void) const; + virtual void Serialize (Buffer::Iterator) const; + virtual uint32_t Deserialize (Buffer::Iterator); + virtual void Print (std::ostream &) const; + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + + // accessor functions..... + void SetIntValue (uint32_t); + uint32_t GetIntValue (void) const; + void SetStrValue (const std::string &s); + std::string GetStrValue (void) const; +private: + uint32_t int_value; + std::string str_value; +}; + + +TypeId +ArchHeader::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::ArchHeader") + .AddConstructor () // NOTE: Required for ???? + .SetParent
() // ditto + ; + return tid; +} + +TypeId +ArchHeader::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +uint32_t +ArchHeader::GetSerializedSize (void) const +{ + return 2*sizeof (uint32_t) + str_value.size (); // int, str len & bytes +} + +void +ArchHeader::Serialize (Buffer::Iterator i) const +{ + i.WriteU32 (int_value); + uint32_t str_len = str_value.size (); + i.WriteU32 (str_len); + for (uint32_t j = 0; j < str_value.size (); j++) + i.WriteU8 (str_value[j]); +} + +uint32_t +ArchHeader::Deserialize (Buffer::Iterator i) +{ + int_value = i.ReadU32 (); + uint32_t str_len = i.ReadU32 (); + str_value.reserve (str_len); + for (uint32_t j = 0; j < str_len; j++) { + char v = i.ReadU8 (); + str_value.push_back (v); + } + return 2*sizeof (uint32_t) + str_value.size (); +} + + +void +ArchHeader::SetIntValue (uint32_t v_) +{ + int_value = v_; +} + +uint32_t +ArchHeader::GetIntValue (void) const +{ + return int_value; +} + +void +ArchHeader::SetStrValue (const std::string &s) +{ + str_value = s; +} + +std::string +ArchHeader::GetStrValue (void) const +{ + return str_value; +} + +void +ArchHeader::Print (std::ostream &os) const +{ + os << "(ArchHeader=" << str_value << ":" << int_value << ")"; +} + +//----------class TalkerApp dcl and definition---------------------------------- +/* + * TalkerApp: + * An an Application that can serve as both Rx and Tx side. + * and is configured by ConfRecv/ConfSend and driven by + * ScheduleSendPacket. Becareful not to try to send a packet + * from the Rx side to the Tx side (back channel) before the + * connection is setup, which has to be from the Tx to the Rx + * (the forward channel). + */ + +class TalkerApp : public Application { +public: + TalkerApp (); + virtual ~TalkerApp (); + void ConfRecv (Ptr,const Address &); + void ConfSend (Ptr,const Address &); + void ScheduleSendPacket(const Time ,const char , const uint32_t size ); + +protected: + virtual void DoDispose (void); +private: + virtual void StartApplication (void); + virtual void StopApplication (void); + + void StartApplicationRecv (void); + void StartApplicationSend (void); + + void HandleRead (Ptr); + void SendPacket (std::string,char,uint32_t); + + void CloseConnection (Ptr socket); + void ConnectionSucceeded (Ptr); + void ConnectionFailed (Ptr); + bool ConnectionRequested (Ptr, const Address &); + void ConnectionCreated (Ptr, const Address &); + + + bool verbose; + Ptr m_socket; + Ptr m_servsocket; + Address m_local; + Address m_remote; + int i_am_listener; + typedef std::map, uint32_t>::iterator left_to_read_iterator_type; + std::map, uint32_t> m_left_to_read; +}; + +class TalkerApp_sub : public TalkerApp { +public: + int foo(void); +}; + +int +TalkerApp_sub::foo(void) {return 0;} + +TalkerApp::TalkerApp () : + verbose (false), + m_socket (0), + m_servsocket (0), + i_am_listener (0) +{} + +TalkerApp::~TalkerApp () +{} + +void +TalkerApp::DoDispose (void) +{ + m_socket = 0; + m_servsocket = 0; + Application::DoDispose (); +} + + +void +TalkerApp::CloseConnection (Ptr sock) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + ); + sock->Close (); +} + +void +TalkerApp::ConnectionSucceeded (Ptr sock) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + + ); +} + +void +TalkerApp::ConnectionFailed (Ptr sock) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + ); +} + +bool +TalkerApp::ConnectionRequested (Ptr sock, const Address &addr) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + << addr + ); + return true; +} + +void +TalkerApp::ConnectionCreated (Ptr sock, const Address &addr) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << sock + << addr + ); + m_socket = sock; + m_socket->SetRecvCallback(MakeCallback (&TalkerApp::HandleRead, this)); +} + +void +TalkerApp::ScheduleSendPacket (const Time dt,const char fill, + const uint32_t size) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << dt + << fill + << size + ); + Simulator::Schedule(dt,&TalkerApp::SendPacket, this, + std::string("HELLO"),fill,size); +} + + +void +TalkerApp::StartApplication () +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + ); + if (i_am_listener) + StartApplicationRecv (); + else + StartApplicationSend (); +} + +void +TalkerApp::StartApplicationSend () +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + ); + + if (!m_socket) { + m_socket = Socket::CreateSocket (GetNode (), + TcpSocketFactory::GetTypeId ()); + m_socket->Bind (); + } + + m_socket->Connect (m_remote); + m_socket->SetConnectCallback + ( + MakeCallback (&TalkerApp::ConnectionSucceeded,this), + MakeCallback (&TalkerApp::ConnectionFailed,this) + ); + m_socket->SetRecvCallback (MakeCallback (&TalkerApp::HandleRead, this)); +} + +void +TalkerApp::StartApplicationRecv () +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + ); + if (!m_servsocket) { + m_servsocket = Socket::CreateSocket (GetNode (), + TcpSocketFactory::GetTypeId ()); + m_servsocket->Bind (m_local); + m_servsocket->Listen (0); + } + + m_servsocket->SetAcceptCallback + ( + MakeCallback (&TalkerApp::ConnectionRequested,this), + MakeCallback (&TalkerApp::ConnectionCreated,this) + ); +} + +void +TalkerApp::ConfRecv (Ptr node, const Address &addr) +{ + i_am_listener = 1; + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << node + << addr + ); + m_local = addr; + node->AddApplication (this); +} + +void +TalkerApp::ConfSend (Ptr node, const Address &addr) +{ + i_am_listener = 0; + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << node + << addr + ); + m_remote = addr; + node->AddApplication (this); +} + + +void +TalkerApp::SendPacket (std::string label,char fill,uint32_t payloadsize) +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + << label + << fill + << payloadsize + ); + +#if 0 + Ptr p = Create (payloadsize); // zero byte filled packet. +#else + uint8_t *buf = (uint8_t *) malloc(payloadsize*sizeof(uint8_t)); + memset(buf,fill,payloadsize); + Ptr p = Create (buf,payloadsize); // filled packet. + free(buf); +#endif + if (verbose) { + p->Print (fileOut << "Before Marking|"); + fileOut << std::endl; + } + + ArchHeader hdr; + hdr.SetStrValue (label); + hdr.SetIntValue (p->GetSize()); + p->AddHeader (hdr); + if (verbose) { + p->Print(fileOut << "After Header Marking|"); + fileOut << std::endl; + } + + m_socket->Send (p); +} + +void +TalkerApp::StopApplication () +{ + NS_LOG_FUNCTION ((i_am_listener ? "Server|" : "Client|") +#ifdef PRINT_THIS + << this +#endif + ); + if (m_socket) + m_socket->SetRecvCallback (MakeNullCallback > ()); +} + +void +TalkerApp::HandleRead (Ptr socket) +{ + left_to_read_iterator_type iter = m_left_to_read.find (socket); + if (iter == m_left_to_read.end ()) + m_left_to_read[socket] = 0; + + std::ostringstream pretty; + pretty << (i_am_listener ? "Server" : "Client") + << (iter == m_left_to_read.end () ? + "(new)" : "(old)") + << "|"; + + NS_LOG_FUNCTION ( pretty.str () +#ifdef PRINT_THIS + << this +#endif + << socket + ); + /* + * NOTE: I can crash with the # bytes == 500 rather than 536 + * which seems to be the default MTU + */ + +#ifdef TOO_SMALL_BUG + const uint32_t number_of_bytes_willing_to_read = 500; +#else + const uint32_t number_of_bytes_willing_to_read = 536; +#endif + const uint32_t unused_flags = 0; + + Ptr packet; + while (packet = socket->Recv (number_of_bytes_willing_to_read, + unused_flags) ){ + std::string raw_rle = rle(packet->PeekData(), + packet->GetSize()); + SocketAddressTag rx_addr_tag; + bool found; + found = packet->FindFirstMatchingTag (rx_addr_tag); + NS_ASSERT (found); + Address from = rx_addr_tag.GetAddress (); + // XXX packet->RemoveTag (tag); + if (InetSocketAddress::IsMatchingType (from)) { + InetSocketAddress address = InetSocketAddress::ConvertFrom (from); + +#ifdef VERBOSE_TESTING + packet->Print (fileOut << "Packet Dump: "); + fileOut << std::endl; +#endif + + + bool freshly_in_the_loop = true; + do { +#if defined(RECV_PRINT) + fileOut + << raw_rle // :PeekBuffer> + << (freshly_in_the_loop ? " *" : " ") /* used to see if the do while + * does anything */ + << "bytes from " + << address.GetIpv4 () << " [" << address << "] "; +#endif + freshly_in_the_loop = false; + int header_bytes = 0; + ArchHeader* hdr = 0; // sadly, can't be a Ptr<> + if ( + (m_left_to_read[socket] == 0) + ) { + hdr = new ArchHeader; + if (packet->RemoveHeader (*hdr)) { + m_left_to_read[socket] = hdr->GetIntValue (); + header_bytes = hdr->GetSerializedSize (); + } else { + ; // never get here, ns3 dumps if no header is there. + } + } + uint32_t num_bytes_processed = 0; + if (m_left_to_read[socket] <= packet->GetSize ()) { + packet->RemoveAtStart (m_left_to_read[socket]); + num_bytes_processed = m_left_to_read[socket]; + m_left_to_read[socket] = 0; + + } else { + m_left_to_read[socket] -= packet->GetSize (); + num_bytes_processed = packet->GetSize (); + packet->RemoveAtStart (packet->GetSize ()); + } + +#if defined(RECV_PRINT) + fileOut + << "<" + << packet->GetSize () + << "|" + << num_bytes_processed + ; + if (header_bytes) + fileOut + << "(" + << header_bytes + << ")" + ; + fileOut + << "|" + << m_left_to_read[socket] + << ">"; +#ifdef VERBOSE_TESTING + if (hdr) + hdr->Print(fileOut << " "); +#endif + fileOut << std::endl; +#endif + if (hdr) + delete hdr; // free what we new.... + } while ( + packet->GetSize () + ); + } else { + fileOut << "not a match in HandleRead" << std::endl; + } + + } +} + +//---------------Non-member functions------------------------------------------- +/* + * returns a string containing the length of the buffer, + * followed by an run length encoded version of the buffer + * un-printables are represented by '.' (i.e. special_marker + * const). + */ +std::string rle(const uint8_t *buf, int buflen) { + + int justify = 5; + std::ostringstream o; + const uint8_t min_rep = 3; + uint8_t cur_char = 0; + const uint8_t special_marker = '.'; + int cur_cnt = 0; + if (justify) { + o << std::setw(justify) << std::right << buflen << ":"; + } else { + o << buflen << ":"; + } + + for (int i = 0; i < buflen; i++) { + if ( + (!isprint(buf[i]) && cur_char == special_marker) || + (buf[i] == cur_char) + ) + cur_cnt++; + else { + if (cur_cnt >= min_rep) + o << (isprint(cur_char) ? static_cast(cur_char) : '.') << "{" + << cur_cnt << "}"; + else + for (int irep=0; irep < cur_cnt; irep++) + o << (isprint(cur_char) ? static_cast(cur_char) : '.'); + if (isprint(buf[i])) + cur_char = buf[i]; + else + cur_char = special_marker; + cur_cnt = 1; + } + } + if (cur_cnt >= min_rep) + o << (isprint(cur_char) ? static_cast(cur_char) : '.') << "{" + << cur_cnt << "}"; + else + for (int irep=0; irep < cur_cnt; irep++) + o << (isprint(cur_char) ? static_cast(cur_char) : '.'); + return o.str(); +} + +//---------------Main----------------------------------------------------------- +int +main (int argc, char *argv[]) { + + std::clog.rdbuf (fileOut.rdbuf ()); /* till we can do this in ns3::log + * without this ns3 logging messages + * are far away from normal output + */ + +#ifdef VERBOSE_TESTING + LogComponentEnable ("tcp-2way",LOG_LEVEL_ALL); +#endif + + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + Packet::EnableMetadata (); + + // boilerplate: "c0[0]" is Tx, "c0[1]" is Rx. + NodeContainer c0; + c0.Create (2); + + // We create the channels first without any IP addressing information + PointToPointHelper p2p; + p2p.SetDeviceAttribute ("DataRate",DataRateValue (DataRate (10000000))); + p2p.SetChannelAttribute ("Delay",TimeValue (MilliSeconds (10))); + NetDeviceContainer dev0 = p2p.Install (c0); + + // add ip/tcp stack to nodes. + InternetStackHelper internet; + internet.Install (c0); + + // Later, we add IP addresses. + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.0.0", "255.255.255.0"); + Ipv4InterfaceContainer ifaces = ipv4.Assign (dev0); + + // Configure the apps. + uint16_t servPort = 32; + + + // setup Rx side using ns3::Node "c0[1]" to listen for ANY:servPort + Ptr sink = CreateObject(); + sink->ConfRecv (c0.Get (1), + InetSocketAddress (Ipv4Address::GetAny (), servPort)); + sink->Start (Seconds (0.0)); // somehow we get by without a Stop. bad form? + + // setup Tx side using ns3::Node "c0[0]" to talk to "c0[1]":servPort + Ptr source = CreateObject(); + source->ConfSend (c0.Get (0), + InetSocketAddress (ifaces.GetAddress (1), + servPort)); + source->Start (Seconds (0.0)); + + // 10 sec is an eternity for this case, we should be done by then. + Simulator::Stop (Seconds (10)); + + + // For regression use only output ascii and pcap traces. +#ifdef REGRESSION_MODE + std::ofstream ascii; + ascii.open ("tcp-2way.tr"); + PointToPointHelper::EnableAsciiAll (ascii); + PointToPointHelper::EnablePcapAll ("tcp-2way"); +#endif + + /* + * Now lets schedule some packets and go. For scheduling packets + * we have to be careful not to do the backchannel too early or + * we try to use a socket that doesn't yet exist since on the Rx + * side the socket is created as part of the normal Tx->Rx connection + * setup. + * + * The delay of 40ms was by trial and error and seems good enough. It + * would be nice to know what the bounds are and why.... + */ + + char tagchar = 'A'; // the fill character in case we fill in SendPacket. + + Time d2t = MilliSeconds(40); /* rate to change time offset (dt) so packets + * are sent in order (Tx->Rx, Rx->Tx for a given + * size over a range of sizes).*/ + + Time dt = MilliSeconds(0); /* ns3 doesn't take absolute times, but times + * relative to Simulator::Now() */ + + uint32_t size = 0; + source->ScheduleSendPacket (dt, tagchar, size); + dt += d2t; + ++tagchar; + sink->ScheduleSendPacket (dt, tagchar, size); + for (size = 1; size <= 1000000; size *= 10) { + dt += d2t; + ++tagchar; + source->ScheduleSendPacket (dt, tagchar, size); + dt += d2t; + ++tagchar; + sink->ScheduleSendPacket (dt, tagchar, size); + } + + // Release the Hounds!! + Simulator::Run (); + Simulator::Destroy (); + fileOut.close(); +} diff -r 48d69d8eac38 -r 5dd595cb7eba examples/wscript --- a/examples/wscript Wed Jul 09 18:50:28 2008 +0100 +++ b/examples/wscript Fri Jul 11 18:15:52 2008 +0100 @@ -56,6 +56,10 @@ ['point-to-point', 'internet-stack']) obj.source = 'tcp-errors.cc' + obj = bld.create_ns3_program('tcp-2way', + ['point-to-point', 'internet-stack']) + obj.source = 'tcp-2way.cc' + obj = bld.create_ns3_program('tcp-star-server', ['point-to-point', 'internet-stack']) obj.source = 'tcp-star-server.cc' diff -r 48d69d8eac38 -r 5dd595cb7eba src/common/buffer.cc --- a/src/common/buffer.cc Wed Jul 09 18:50:28 2008 +0100 +++ b/src/common/buffer.cc Fri Jul 11 18:15:52 2008 +0100 @@ -1128,6 +1128,12 @@ return ~sum; } +uint32_t +Buffer::Iterator::GetSize (void) const +{ + return m_dataEnd - m_dataStart; +} + } // namespace ns3 diff -r 48d69d8eac38 -r 5dd595cb7eba src/common/buffer.h --- a/src/common/buffer.h Wed Jul 09 18:50:28 2008 +0100 +++ b/src/common/buffer.h Fri Jul 11 18:15:52 2008 +0100 @@ -358,6 +358,11 @@ */ uint16_t CalculateIpChecksum(uint16_t size, uint32_t initialChecksum); + /** + * \returns the size of the underlying buffer we are iterating + */ + uint32_t GetSize (void) const; + private: friend class Buffer; Iterator (Buffer const*buffer); diff -r 48d69d8eac38 -r 5dd595cb7eba src/core/deprecated.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/deprecated.h Fri Jul 11 18:15:52 2008 +0100 @@ -0,0 +1,10 @@ +#ifndef NS3_DEPRECATED_H +#define NS3_DEPRECATED_H + +#ifdef __GNUC__ +#define NS_DEPRECATED __attribute__ ((deprecated)) +#else +#define NS_DEPRECATED +#endif + +#endif /* NS3_DEPRECATED_H */ diff -r 48d69d8eac38 -r 5dd595cb7eba src/core/wscript --- a/src/core/wscript Wed Jul 09 18:50:28 2008 +0100 +++ b/src/core/wscript Fri Jul 11 18:15:52 2008 +0100 @@ -110,5 +110,6 @@ 'trace-source-accessor.h', 'config.h', 'object-vector.h', + 'deprecated.h' ] diff -r 48d69d8eac38 -r 5dd595cb7eba src/helper/csma-helper.cc --- a/src/helper/csma-helper.cc Wed Jul 09 18:50:28 2008 +0100 +++ b/src/helper/csma-helper.cc Fri Jul 11 18:15:52 2008 +0100 @@ -64,6 +64,17 @@ } void +CsmaHelper::SetDeviceParameter (std::string n1, const AttributeValue &v1) +{ + SetDeviceAttribute (n1, v1); +} +void +CsmaHelper::SetChannelParameter (std::string n1, const AttributeValue &v1) +{ + SetChannelAttribute (n1, v1); +} + +void CsmaHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid) { std::ostringstream oss; diff -r 48d69d8eac38 -r 5dd595cb7eba src/helper/csma-helper.h --- a/src/helper/csma-helper.h Wed Jul 09 18:50:28 2008 +0100 +++ b/src/helper/csma-helper.h Fri Jul 11 18:15:52 2008 +0100 @@ -27,6 +27,7 @@ #include "ns3/net-device-container.h" #include "ns3/node-container.h" #include "ns3/csma-channel.h" +#include "ns3/deprecated.h" namespace ns3 { @@ -79,6 +80,9 @@ */ void SetChannelAttribute (std::string n1, const AttributeValue &v1); + void SetDeviceParameter (std::string n1, const AttributeValue &v1) NS_DEPRECATED; + void SetChannelParameter (std::string n1, const AttributeValue &v1) NS_DEPRECATED; + /** * \param filename filename prefix to use for pcap files. * \param nodeid the id of the node to generate pcap output for. diff -r 48d69d8eac38 -r 5dd595cb7eba src/helper/point-to-point-helper.cc --- a/src/helper/point-to-point-helper.cc Wed Jul 09 18:50:28 2008 +0100 +++ b/src/helper/point-to-point-helper.cc Fri Jul 11 18:15:52 2008 +0100 @@ -64,6 +64,17 @@ } void +PointToPointHelper::SetDeviceParameter (std::string name, const AttributeValue &value) +{ + SetDeviceAttribute (name, value); +} +void +PointToPointHelper::SetChannelParameter (std::string name, const AttributeValue &value) +{ + SetChannelAttribute (name, value); +} + +void PointToPointHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid) { std::ostringstream oss; diff -r 48d69d8eac38 -r 5dd595cb7eba src/helper/point-to-point-helper.h --- a/src/helper/point-to-point-helper.h Wed Jul 09 18:50:28 2008 +0100 +++ b/src/helper/point-to-point-helper.h Fri Jul 11 18:15:52 2008 +0100 @@ -23,6 +23,7 @@ #include "ns3/object-factory.h" #include "ns3/net-device-container.h" #include "ns3/node-container.h" +#include "ns3/deprecated.h" #include namespace ns3 { @@ -78,6 +79,9 @@ */ void SetChannelAttribute (std::string name, const AttributeValue &value); + void SetDeviceParameter (std::string name, const AttributeValue &value) NS_DEPRECATED; + void SetChannelParameter (std::string name, const AttributeValue &value) NS_DEPRECATED; + /** * \param filename filename prefix to use for pcap files. * \param nodeid the id of the node to generate pcap output for. diff -r 48d69d8eac38 -r 5dd595cb7eba src/internet-stack/tcp-header.cc --- a/src/internet-stack/tcp-header.cc Wed Jul 09 18:50:28 2008 +0100 +++ b/src/internet-stack/tcp-header.cc Fri Jul 11 18:15:52 2008 +0100 @@ -23,6 +23,7 @@ #include "tcp-socket-impl.h" #include "tcp-header.h" #include "ns3/buffer.h" +#include "ns3/address-utils.h" namespace ns3 { @@ -37,8 +38,6 @@ m_flags (0), m_windowSize (0xffff), m_urgentPointer (0), - m_initialChecksum(0), - m_checksum (0), m_calcChecksum(false), m_goodChecksum(true) {} @@ -52,11 +51,6 @@ m_calcChecksum = true; } -void TcpHeader::SetPayloadSize(uint16_t payloadSize) -{ - m_payloadSize = payloadSize; -} - void TcpHeader::SetSourcePort (uint16_t port) { m_sourcePort = port; @@ -85,10 +79,6 @@ { m_windowSize = windowSize; } -void TcpHeader::SetChecksum (uint16_t checksum) -{ - m_checksum = checksum; -} void TcpHeader::SetUrgentPointer (uint16_t urgentPointer) { m_urgentPointer = urgentPointer; @@ -122,10 +112,6 @@ { return m_windowSize; } -uint16_t TcpHeader::GetChecksum () const -{ - return m_checksum; -} uint16_t TcpHeader::GetUrgentPointer () const { return m_urgentPointer; @@ -133,29 +119,31 @@ void TcpHeader::InitializeChecksum (Ipv4Address source, - Ipv4Address destination, - uint8_t protocol) + Ipv4Address destination, + uint8_t protocol) { - Buffer buf = Buffer(12); - uint8_t tmp[4]; - Buffer::Iterator it; - uint16_t tcpLength = m_payloadSize + GetSerializedSize(); - - buf.AddAtStart(12); - it = buf.Begin(); + m_source = source; + m_destination = destination; + m_protocol = protocol; +} - source.Serialize(tmp); - it.Write(tmp, 4); /* source IP address */ - destination.Serialize(tmp); - it.Write(tmp, 4); /* destination IP address */ - it.WriteU8(0); /* protocol */ - it.WriteU8(protocol); /* protocol */ - it.WriteU8(tcpLength >> 8); /* length */ - it.WriteU8(tcpLength & 0xff); /* length */ +uint16_t +TcpHeader::CalculateHeaderChecksum (uint16_t size) const +{ + Buffer buf = Buffer (12); + buf.AddAtStart (12); + Buffer::Iterator it = buf.Begin (); - it = buf.Begin(); + WriteTo (it, m_source); + WriteTo (it, m_destination); + it.WriteU8 (0); /* protocol */ + it.WriteU8 (m_protocol); /* protocol */ + it.WriteU8 (size >> 8); /* length */ + it.WriteU8 (size & 0xff); /* length */ + + it = buf.Begin (); /* we don't CompleteChecksum ( ~ ) now */ - m_initialChecksum = ~(it.CalculateIpChecksum(12)); + return ~(it.CalculateIpChecksum (12)); } bool @@ -219,7 +207,6 @@ void TcpHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; - uint16_t tcpLength = m_payloadSize + GetSerializedSize(); i.WriteHtonU16 (m_sourcePort); i.WriteHtonU16 (m_destinationPort); i.WriteHtonU32 (m_sequenceNumber); @@ -231,8 +218,9 @@ if(m_calcChecksum) { + uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); i = start; - uint16_t checksum = i.CalculateIpChecksum(tcpLength, m_initialChecksum); + uint16_t checksum = i.CalculateIpChecksum(start.GetSize (), headerChecksum); i = start; i.Next(16); @@ -250,16 +238,16 @@ m_flags = field & 0x3F; m_length = field>>12; m_windowSize = i.ReadNtohU16 (); - m_checksum = i.ReadU16 (); + i.Next (2); m_urgentPointer = i.ReadNtohU16 (); if(m_calcChecksum) - { + { + uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); i = start; - uint16_t checksum = i.CalculateIpChecksum(m_payloadSize + GetSerializedSize(), m_initialChecksum); - + uint16_t checksum = i.CalculateIpChecksum(start.GetSize (), headerChecksum); m_goodChecksum = (checksum == 0); - } + } return GetSerializedSize (); } diff -r 48d69d8eac38 -r 5dd595cb7eba src/internet-stack/tcp-header.h --- a/src/internet-stack/tcp-header.h Wed Jul 09 18:50:28 2008 +0100 +++ b/src/internet-stack/tcp-header.h Fri Jul 11 18:15:52 2008 +0100 @@ -78,10 +78,6 @@ */ void SetWindowSize (uint16_t windowSize); /** - * \param checksum the checksum for this TcpHeader - */ - void SetChecksum (uint16_t checksum); - /** * \param urgentPointer the urgent pointer for this TcpHeader */ void SetUrgentPointer (uint16_t urgentPointer); @@ -117,10 +113,6 @@ */ uint16_t GetWindowSize () const; /** - * \return the checksum for this TcpHeader - */ - uint16_t GetChecksum () const; - /** * \return the urgent pointer for this TcpHeader */ uint16_t GetUrgentPointer () const; @@ -151,17 +143,13 @@ virtual uint32_t Deserialize (Buffer::Iterator start); /** - * \param size The payload size in bytes - */ - void SetPayloadSize (uint16_t size); - - /** * \brief Is the TCP checksum correct ? * \returns true if the checksum is correct, false otherwise. */ bool IsChecksumOk (void) const; private: + uint16_t CalculateHeaderChecksum (uint16_t size) const; uint16_t m_sourcePort; uint16_t m_destinationPort; uint32_t m_sequenceNumber; @@ -170,13 +158,14 @@ uint8_t m_flags; // really a uint6_t uint16_t m_windowSize; uint16_t m_urgentPointer; - uint16_t m_payloadSize; + + Ipv4Address m_source; + Ipv4Address m_destination; + uint8_t m_protocol; + uint16_t m_initialChecksum; - uint16_t m_checksum; - bool m_calcChecksum; bool m_goodChecksum; - }; }; // namespace ns3 diff -r 48d69d8eac38 -r 5dd595cb7eba src/internet-stack/tcp-l4-protocol.cc --- a/src/internet-stack/tcp-l4-protocol.cc Wed Jul 09 18:50:28 2008 +0100 +++ b/src/internet-stack/tcp-l4-protocol.cc Fri Jul 11 18:15:52 2008 +0100 @@ -448,6 +448,7 @@ if(m_calcChecksum) { tcpHeader.EnableChecksums(); + tcpHeader.InitializeChecksum (source, destination, PROT_NUMBER); } packet->PeekHeader (tcpHeader); @@ -495,7 +496,6 @@ TcpHeader tcpHeader; tcpHeader.SetDestinationPort (dport); tcpHeader.SetSourcePort (sport); - tcpHeader.SetPayloadSize(packet->GetSize()); if(m_calcChecksum) { tcpHeader.EnableChecksums(); @@ -529,7 +529,6 @@ // XXX outgoingHeader cannot be logged outgoingHeader.SetLength (5); //header length in units of 32bit words - outgoingHeader.SetPayloadSize(packet->GetSize()); /* outgoingHeader.SetUrgentPointer (0); //XXX */ if(m_calcChecksum) { diff -r 48d69d8eac38 -r 5dd595cb7eba src/internet-stack/tcp-socket-impl.h --- a/src/internet-stack/tcp-socket-impl.h Wed Jul 09 18:50:28 2008 +0100 +++ b/src/internet-stack/tcp-socket-impl.h Fri Jul 11 18:15:52 2008 +0100 @@ -50,7 +50,13 @@ * This class contains an implementation of TCP Tahoe, as well as a sockets * interface for talking to TCP. Features include connection orientation, * reliability through cumulative acknowledgements, congestion and flow - * control. Finite send/receive buffer semantics are modeled. + * control. Finite send buffer semantics are modeled, but as of yet, finite + * receive buffer modelling is unimplemented. + * + * The closedown of these sockets is as of yet not compliant with the relevent + * RFCs, i.e. the FIN handshaking isn't correct. While this is visible at the + * PCAP tracing level, it has no effect on the statistics users are interested + * in, i.e. throughput, delay, etc. of actual payload data. * * Asynchronous callbacks to provide notifications to higher layers that a * protocol event has occured, such as space freeing up in the send buffer diff -r 48d69d8eac38 -r 5dd595cb7eba src/internet-stack/udp-header.cc --- a/src/internet-stack/udp-header.cc Wed Jul 09 18:50:28 2008 +0100 +++ b/src/internet-stack/udp-header.cc Fri Jul 11 18:15:52 2008 +0100 @@ -19,6 +19,7 @@ */ #include "udp-header.h" +#include "ns3/address-utils.h" namespace ns3 { @@ -32,8 +33,6 @@ : m_sourcePort (0xfffd), m_destinationPort (0xfffd), m_payloadSize (0xfffd), - m_initialChecksum (0), - m_checksum(0), m_calcChecksum(false), m_goodChecksum(true) {} @@ -71,35 +70,31 @@ return m_destinationPort; } void -UdpHeader::SetPayloadSize (uint16_t size) -{ - m_payloadSize = size; -} -void UdpHeader::InitializeChecksum (Ipv4Address source, Ipv4Address destination, uint8_t protocol) { - Buffer buf = Buffer(12); - uint8_t tmp[4]; - Buffer::Iterator it; - uint16_t udpLength = m_payloadSize + GetSerializedSize(); - - buf.AddAtStart(12); - it = buf.Begin(); + m_source = source; + m_destination = destination; + m_protocol = protocol; +} +uint16_t +UdpHeader::CalculateHeaderChecksum (uint16_t size) const +{ + Buffer buf = Buffer (12); + buf.AddAtStart (12); + Buffer::Iterator it = buf.Begin (); - source.Serialize(tmp); - it.Write(tmp, 4); /* source IP address */ - destination.Serialize(tmp); - it.Write(tmp, 4); /* destination IP address */ - it.WriteU8(0); /* protocol */ - it.WriteU8(protocol); /* protocol */ - it.WriteU8(udpLength >> 8); /* length */ - it.WriteU8(udpLength & 0xff); /* length */ + WriteTo (it, m_source); + WriteTo (it, m_destination); + it.WriteU8 (0); /* protocol */ + it.WriteU8 (m_protocol); /* protocol */ + it.WriteU8 (size >> 8); /* length */ + it.WriteU8 (size & 0xff); /* length */ - it = buf.Begin(); + it = buf.Begin (); /* we don't CompleteChecksum ( ~ ) now */ - m_initialChecksum = ~(it.CalculateIpChecksum(12)); + return ~(it.CalculateIpChecksum (12)); } bool @@ -142,17 +137,17 @@ UdpHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; - uint16_t udpLength = m_payloadSize + GetSerializedSize(); i.WriteHtonU16 (m_sourcePort); i.WriteHtonU16 (m_destinationPort); - i.WriteHtonU16 (udpLength); + i.WriteHtonU16 (start.GetSize ()); i.WriteU16 (0); if (m_calcChecksum) { + uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); i = start; - uint16_t checksum = i.CalculateIpChecksum(udpLength, m_initialChecksum); + uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksum); i = start; i.Next(6); @@ -166,12 +161,13 @@ m_sourcePort = i.ReadNtohU16 (); m_destinationPort = i.ReadNtohU16 (); m_payloadSize = i.ReadNtohU16 () - GetSerializedSize (); - m_checksum = i.ReadU16(); + i.Next (2); if(m_calcChecksum) { + uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); i = start; - uint16_t checksum = i.CalculateIpChecksum(m_payloadSize + GetSerializedSize(), m_initialChecksum); + uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksum); m_goodChecksum = (checksum == 0); } diff -r 48d69d8eac38 -r 5dd595cb7eba src/internet-stack/udp-header.h --- a/src/internet-stack/udp-header.h Wed Jul 09 18:50:28 2008 +0100 +++ b/src/internet-stack/udp-header.h Fri Jul 11 18:15:52 2008 +0100 @@ -66,10 +66,6 @@ * \return the destination port for this UdpHeader */ uint16_t GetDestinationPort (void) const; - /** - * \param size The payload size in bytes - */ - void SetPayloadSize (uint16_t size); /** * \param source the ip source to use in the underlying @@ -100,12 +96,14 @@ bool IsChecksumOk (void) const; private: + uint16_t CalculateHeaderChecksum (uint16_t size) const; uint16_t m_sourcePort; uint16_t m_destinationPort; uint16_t m_payloadSize; - uint16_t m_initialChecksum; - uint16_t m_checksum; + Ipv4Address m_source; + Ipv4Address m_destination; + uint8_t m_protocol; bool m_calcChecksum; bool m_goodChecksum; }; diff -r 48d69d8eac38 -r 5dd595cb7eba src/internet-stack/udp-l4-protocol.cc --- a/src/internet-stack/udp-l4-protocol.cc Wed Jul 09 18:50:28 2008 +0100 +++ b/src/internet-stack/udp-l4-protocol.cc Fri Jul 11 18:15:52 2008 +0100 @@ -163,7 +163,6 @@ udpHeader.EnableChecksums(); } - udpHeader.SetPayloadSize (packet->GetSize () - udpHeader.GetSerializedSize ()); udpHeader.InitializeChecksum (source, destination, PROT_NUMBER); packet->RemoveHeader (udpHeader); @@ -195,13 +194,12 @@ if(m_calcChecksum) { udpHeader.EnableChecksums(); + udpHeader.InitializeChecksum (saddr, + daddr, + PROT_NUMBER); } udpHeader.SetDestinationPort (dport); udpHeader.SetSourcePort (sport); - udpHeader.SetPayloadSize (packet->GetSize ()); - udpHeader.InitializeChecksum (saddr, - daddr, - PROT_NUMBER); packet->AddHeader (udpHeader); diff -r 48d69d8eac38 -r 5dd595cb7eba src/node/tcp-socket-factory.h --- a/src/node/tcp-socket-factory.h Wed Jul 09 18:50:28 2008 +0100 +++ b/src/node/tcp-socket-factory.h Fri Jul 11 18:15:52 2008 +0100 @@ -48,8 +48,6 @@ public: static TypeId GetTypeId (void); - virtual Ptr CreateSocket (void) = 0; - }; } // namespace ns3 diff -r 48d69d8eac38 -r 5dd595cb7eba src/node/udp-socket-factory.h --- a/src/node/udp-socket-factory.h Wed Jul 09 18:50:28 2008 +0100 +++ b/src/node/udp-socket-factory.h Fri Jul 11 18:15:52 2008 +0100 @@ -42,14 +42,6 @@ public: static TypeId GetTypeId (void); - /** - * \return smart pointer to Socket - * - * API for creating socket instances; must be implemented by UDP - * implementations.. - */ - virtual Ptr CreateSocket (void) = 0; - }; } // namespace ns3 diff -r 48d69d8eac38 -r 5dd595cb7eba wscript --- a/wscript Wed Jul 09 18:50:28 2008 +0100 +++ b/wscript Fri Jul 11 18:15:52 2008 +0100 @@ -197,7 +197,7 @@ if (os.path.basename(conf.env['CXX']).startswith("g++") and 'CXXFLAGS' not in os.environ): - variant_env.append_value('CXXFLAGS', ['-Werror']) + variant_env.append_value('CXXFLAGS', ['-Werror', '-Wno-error=deprecated-declarations']) if 'debug' in Params.g_options.debug_level.lower(): variant_env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE')