From 4db6e9a69ae93791de7ef2c9c60ee9a167d10311 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 29 May 2007 16:09:20 +0200 Subject: [PATCH 001/116] merge unfinished packet history code --- SConstruct | 2 + src/common/packet-history.cc | 985 +++++++++++++++++++++++++++++++++++ src/common/packet-history.h | 188 +++++++ src/common/packet.cc | 17 +- src/common/packet.h | 23 +- 5 files changed, 1203 insertions(+), 12 deletions(-) create mode 100644 src/common/packet-history.cc create mode 100644 src/common/packet-history.h diff --git a/SConstruct b/SConstruct index 26cedc0bf..a96adb851 100644 --- a/SConstruct +++ b/SConstruct @@ -188,6 +188,7 @@ common.add_sources([ 'chunk.cc', 'header.cc', 'trailer.cc', + 'packet-history.cc', 'packet.cc', 'tags.cc', 'pcap-writer.cc', @@ -209,6 +210,7 @@ common.add_inst_headers([ 'trailer.h', 'tags.h', 'packet.h', + 'packet-history.h', 'uv-trace-source.h', 'sv-trace-source.h', 'fv-trace-source.h', diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc new file mode 100644 index 000000000..564c899fd --- /dev/null +++ b/src/common/packet-history.cc @@ -0,0 +1,985 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2006,2007 INRIA + * All rights reserved. + * + * 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 + * + * Author: Mathieu Lacage + */ +#include +#include "ns3/assert.h" +#include "ns3/fatal-error.h" +#include "packet-history.h" +#include "chunk.h" +#include "buffer.h" + +namespace ns3 { + +bool PacketHistory::m_enable = false; +PacketHistory::ChunkFactories PacketHistory::m_factories; +uint32_t PacketHistory::m_maxSize = 0; +PacketHistory::DataFreeList PacketHistory::m_freeList; + +void +PacketHistory::Enable (void) +{ + m_enable = true; +} + + +PacketHistory::PacketHistory () + : m_data (0), + m_end (0), + m_n (0) +{ + Construct (0, 0); +} +PacketHistory::PacketHistory (uint32_t uid, uint32_t size) + : m_data (0), + m_end (0), + m_n (0) +{ + Construct (uid, size); +} +void +PacketHistory::Construct (uint32_t uid, uint32_t size) +{ + if (m_enable) + { + m_data = PacketHistory::Create (size); + AppendOneCommand (PacketHistory::INIT_UID, + uid); + } +} +PacketHistory::PacketHistory (PacketHistory const &o) + : m_data (o.m_data), + m_end (o.m_end), + m_n (o.m_n) +{ + if (m_data != 0) + { + m_data->m_count++; + } +} +PacketHistory & +PacketHistory::operator = (PacketHistory const& o) +{ + if (m_data == o.m_data) + { + // self assignment + return *this; + } + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } + m_data = o.m_data; + m_end = o.m_end; + m_n = o.m_n; + if (m_data != 0) + { + m_data->m_count++; + } + return *this; +} +PacketHistory::~PacketHistory () +{ + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } +} + + +struct PacketHistory::CommandData * +PacketHistory::Create (uint32_t size) +{ + if (size > m_maxSize) + { + m_maxSize = size; + } + while (!m_freeList.empty ()) + { + struct PacketHistory::CommandData *data = m_freeList.back (); + m_freeList.pop_back (); + if (data->m_size >= size) + { + data->m_count = 1; + return data; + } + PacketHistory::Deallocate (data); + } + return PacketHistory::Allocate (size); +} + +void +PacketHistory::Recycle (struct CommandData *data) +{ + NS_ASSERT (data->m_count == 0); + if (m_freeList.size () > 1000 || + data->m_size < m_maxSize) + { + PacketHistory::Deallocate (data); + } + else + { + m_freeList.push_back (data); + } +} + +struct PacketHistory::CommandData * +PacketHistory::Allocate (uint32_t n) +{ + uint32_t size = sizeof (struct CommandData); + if (n <= 4) + { + n = 4; + } + size += (n-4) * (4 + 1); + uint8_t *buf = new uint8_t [size]; + struct CommandData *data = (struct CommandData *)buf; + data->m_size = n; + data->m_count = 1; + return data; +} +void +PacketHistory::Deallocate (struct CommandData *data) +{ + uint8_t *buf = (uint8_t *)data; + delete [] buf; +} + +void +PacketHistory::AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1) +{ + NS_ASSERT (m_data != 0); + uint32_t n = GetUleb128Size (type); + n += GetUleb128Size (data0); + n += GetUleb128Size (data1); + + if (m_data->m_size > m_end + n) + { + if (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + AppendValue (data1); + AppendValue (data0); + AppendValue (type); + m_n++; + return; + } + else + { + uint8_t *buffer = &(m_data->m_data[m_end]); + uint32_t lastType = ReadValue (&buffer); + if (lastType == type) + { + uint32_t lastData = ReadValue (&buffer); + if (lastData == data0) + { + lastData = ReadValue (&buffer); + if (lastData == data1) + { + return; + } + } + } + } + } + Reserve (n); + AppendValue (data1); + AppendValue (data0); + AppendValue (type); + m_n++; +} + +void +PacketHistory::AppendOneCommand (uint32_t type, uint32_t data) +{ + NS_ASSERT (m_data != 0); + uint32_t n = GetUleb128Size (data); + n += GetUleb128Size (type); + + if (m_data->m_size > m_end + n) + { + if (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + AppendValue (data); + AppendValue (type); + m_n++; + return; + } + else + { + uint8_t *buffer = &(m_data->m_data[m_end]); + uint32_t lastType = ReadValue (&buffer); + if (lastType == type) + { + uint32_t lastData = ReadValue (&buffer); + if (lastData == data) + { + return; + } + } + } + } + Reserve (n); + AppendValue (data); + AppendValue (type); + m_n++; +} +void +PacketHistory::ReserveCopy (uint32_t size) +{ + struct CommandData *newData = PacketHistory::Create (m_end + size); + memcpy (newData->m_data, m_data->m_data, m_end); + newData->m_dirtyEnd = m_end; + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + m_data = newData; +} +void +PacketHistory::Reserve (uint32_t size) +{ + NS_ASSERT (m_data != 0); + if (m_data->m_size > m_end + size && + (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end)) + { + /* enough room, not dirty. */ + } + else + { + /* (enough room and dirty) or (not enough room) */ + ReserveCopy (size); + } +} + +uint32_t +PacketHistory::GetUleb128Size (uint32_t value) const +{ + uint32_t n = 0; + uint32_t tmp = value; + do { + tmp >>= 7; + n++; + } while (tmp != 0); + return n; +} + +uint32_t +PacketHistory::GetReverseUleb128Size (uint8_t *buffer) const +{ + uint8_t *cur = buffer; + uint8_t byte = *cur; + if (byte & 0x80) + { + NS_FATAL_ERROR ("The last byte should have a zero high bit"); + } + cur--; + while ((byte & 0x80) && (buffer - cur) < 5) + { + cur--; + byte = *cur; + } + uint32_t n = buffer - cur; + return n; +} + +void +PacketHistory::AppendValue (uint32_t value) +{ + uint32_t n = 0; + uint8_t *buffer = &m_data->m_data[m_end]; + do { + uint8_t byte = value & (~0x80); + value >>= 7; + if (value != 0) + { + /* more bytes to come */ + byte |= 0x80; + } + n++; + *buffer = byte; + buffer++; + } while (value != 0); + m_end += n; + if (m_end > m_data->m_dirtyEnd) + { + m_data->m_dirtyEnd = m_end; + } +} + +uint32_t +PacketHistory::ReadValue (uint8_t **pBuffer) const +{ + uint32_t n = GetReverseUleb128Size (*pBuffer); + NS_ASSERT (n > 0); + uint8_t *buffer = *pBuffer - n + 1; + uint32_t result = 0; + uint8_t shift, byte; + result = 0; + shift = 0; + do { + byte = *buffer; + buffer++; + result |= (byte & (~0x80))<m_data[m_end], o.m_data->m_data, o.m_end); + m_end += o.m_end; + if (m_end > m_data->m_dirtyEnd) + { + m_data->m_dirtyEnd = m_end; + } + AppendOneCommand (PacketHistory::ADD_AT_END, 0); + } +} +void +PacketHistory::AddPaddingAtEnd (uint32_t end) +{ + if (m_enable) + { + AppendOneCommand (PacketHistory::PADDING_AT_END, end); + } +} +void +PacketHistory::RemoveAtStart (uint32_t start) +{ + if (m_enable) + { + AppendOneCommand (PacketHistory::REM_AT_START, start); + } +} +void +PacketHistory::RemoveAtEnd (uint32_t end) +{ + if (m_enable) + { + AppendOneCommand (PacketHistory::REM_AT_END, end); + } +} + +void +PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const +{ + if (!m_enable) + { + return; + } + + Buffer original = buffer; + HeadersToPrint headersToPrint; + TrailersToPrint trailersToPrint; + uint8_t *dataBuffer = &m_data->m_data[m_end] - 1; + int32_t start = 0; + int32_t end = buffer.GetSize (); + int32_t curStart = start; + int32_t curEnd = end; + for (uint32_t i = 0; i < m_n; i++) + { + uint32_t type = ReadValue (&dataBuffer); + uint32_t data = ReadValue (&dataBuffer); + switch (type) + { + case PacketHistory::INIT_UID: + break; + case PacketHistory::INIT_SIZE: + std::cout << "init size=" << data << std::endl; + break; + case PacketHistory::ADD_HEADER: { + int32_t size = ReadValue (&dataBuffer); + if (curStart == start) + { + if (start + size < end) + { + headersToPrint.push_back (std::make_pair (data, curStart)); + } + curStart += size; + start += size; + } + else if (curStart + size <= start) + { + // header lies entirely outside of data area. + curStart += size; + } + else if (curStart < start) + { + // header lies partly inside and outside of data area + // potentially, because we fragmented the packet in the middle + // of this header. + curStart += size; + } + else + { + // header lies entirely inside data area but there is some + // data at the start of the data area which does not belong + // to this header. Potentially, because we fragmented + // the packet in the middle of a previous header. + NS_ASSERT (curStart > start); + // we print the content of the header anyway because we can. + if (start + size < end) + { + headersToPrint.push_back (std::make_pair (data, curStart)); + } + curStart += size; + start = curStart; + } + } break; + case PacketHistory::REM_HEADER: { + int32_t size = ReadValue (&dataBuffer); + if (curStart <= start) + { + // header lies entirely outside of data area. + curStart -= size; + } + else + { + NS_ASSERT (false); + } + } break; + case PacketHistory::ADD_TRAILER: { + int32_t size = ReadValue (&dataBuffer); + if (curEnd == end) + { + if (end - size >= start) + { + // trailer lies exactly at the end of the data area + trailersToPrint.push_back (std::make_pair (data, buffer.GetSize () - curEnd)); + } + curEnd -= size; + end -= size; + } + else if (curEnd - size >= end) + { + // trailer lies entirely outside of data area. + curEnd -= size; + } + else if (curEnd > end) + { + // header lies partly inside and partly outside of + // data area, potentially because of fragmentation. + curEnd -= size; + } + else + { + // header lies entirely inside data area + NS_ASSERT (curEnd < end); + if (end - size >= start) + { + trailersToPrint.push_back (std::make_pair (data, buffer.GetSize () - curEnd)); + } + curEnd -= size; + end = curEnd; + + } + } break; + case PacketHistory::REM_TRAILER: { + int32_t size = ReadValue (&dataBuffer); + if (curEnd >= end) + { + curEnd += size; + } + else + { + NS_ASSERT (false); + } + } break; + case PacketHistory::REM_AT_START: + curStart -= data; + break; + case PacketHistory::REM_AT_END: + curEnd += data; + break; + } + } + for (HeadersToPrint::iterator j = headersToPrint.begin (); + j != headersToPrint.end (); j++) + { + uint32_t uid = j->first; + uint32_t offset = j->second; + Buffer tmp = original; + tmp.RemoveAtStart (offset); + Chunk *chunk = CreateStatic (uid); + chunk->Deserialize (tmp.Begin ()); + chunk->Print (os); + } + for (TrailersToPrint::reverse_iterator j = trailersToPrint.rbegin (); + j != trailersToPrint.rend (); j++) + { + uint32_t uid = j->first; + uint32_t offset = j->second; + Buffer tmp = original; + tmp.RemoveAtEnd (offset); + Chunk *chunk = CreateStatic (uid); + chunk->Deserialize (tmp.End ()); + chunk->Print (os); + } +} + + +Chunk * +PacketHistory::CreateStatic (uint32_t uid) +{ + for (ChunkFactoriesI i = m_factories.begin (); i != m_factories.end (); i++) + { + if (i->first == uid) + { + return (*i->second) (); + } + } + NS_ASSERT_MSG (false, "cannot be reached"); + /* quiet compiler */ + return 0; +} +uint32_t +PacketHistory::RegisterChunkFactory (Chunk *(*createStatic) (void)) +{ + static uint32_t uid = 0; + uid++; + for (ChunkFactoriesI i = m_factories.begin (); i != m_factories.end (); i++) + { + NS_ASSERT (i->first != uid); + } + m_factories.push_back (std::make_pair (uid, createStatic)); + return uid; +} + +}; // namespace ns3 + +#include +#include +#include "ns3/test.h" +#include "header.h" +#include "trailer.h" +#include "packet.h" + +namespace ns3 { + +static std::list g_prints; +static bool g_headerError; +static bool g_trailerError; + +static void +RecordPrint (int n) +{ + g_prints.push_back (n); +} + +static void +RecordTrailerError (int n) +{ + g_trailerError = true; +} + +static void +RecordHeaderError (int n) +{ + g_headerError = true; +} + +static void +CleanupPrints (void) +{ + g_prints.erase (g_prints.begin (), g_prints.end ()); +} + +template +class HistoryHeader : public Header +{ +private: + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); +}; + +template +void +HistoryHeader::PrintTo (std::ostream &os) const +{ + RecordPrint (N); +} +template +uint32_t +HistoryHeader::GetSerializedSize (void) const +{ + return N; +} +template +void +HistoryHeader::SerializeTo (Buffer::Iterator start) const +{ + start.WriteU8 (N, N); +} +template +uint32_t +HistoryHeader::DeserializeFrom (Buffer::Iterator start) +{ + for (int i = 0; i < N; i++) + { + if (start.ReadU8 () != N) + { + RecordHeaderError (N); + } + } + return N; +} + +template +class HistoryTrailer : public Trailer +{ +private: + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); +}; + +template +void +HistoryTrailer::PrintTo (std::ostream &os) const +{ + RecordPrint (N); +} +template +uint32_t +HistoryTrailer::GetSerializedSize (void) const +{ + return N; +} +template +void +HistoryTrailer::SerializeTo (Buffer::Iterator start) const +{ + start.WriteU8 (N, N); +} +template +uint32_t +HistoryTrailer::DeserializeFrom (Buffer::Iterator start) +{ + start.Prev (N); + for (int i = 0; i < N; i++) + { + if (start.ReadU8 () != N) + { + RecordTrailerError (N); + } + } + return N; +} + + + +class PacketHistoryTest : public Test { +public: + PacketHistoryTest (); + virtual ~PacketHistoryTest (); + bool CheckHistory (Packet p, char *file, int line, uint32_t n, ...); + virtual bool RunTests (void); +}; + +PacketHistoryTest::PacketHistoryTest () + : Test ("PacketHistory") +{} + +PacketHistoryTest::~PacketHistoryTest () +{} + +bool +PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ...) +{ + g_headerError = false; + g_trailerError = false; + va_list ap; + p.Print (std::cerr); + va_start (ap, n); + if (g_headerError) + { + std::cout << "PacketHistory header error. file=" << file + << ", line=" << line << std::endl; + return false; + } + if (g_trailerError) + { + std::cout << "PacketHistory trailer error. file=" << file + << ", line=" << line << std::endl; + return false; + } + if (n != g_prints.size ()) + { + goto error; + } + for (std::list::iterator i = g_prints.begin (); + i != g_prints.end (); i++) + { + int v = va_arg (ap, int); + if (v != *i) + { + va_end (ap); + goto error; + } + } + va_end (ap); + return true; + error: + std::cout << "PacketHistory error. file="<< file + << ", line=" << line << ", got:\""; + for (std::list::iterator i = g_prints.begin (); + i != g_prints.end (); i++) + { + std::cout << *i << ", "; + } + std::cout << "\", expected: \""; + va_start (ap, n); + for (uint32_t j = 0; j < n; j++) + { + int v = va_arg (ap, int); + std::cout << v << ", "; + } + va_end (ap); + std::cout << "\"" << std::endl; + return false; +} + +#define ADD_HEADER(p, n) \ + { \ + HistoryHeader header; \ + p.AddHeader (header); \ + } +#define ADD_TRAILER(p, n) \ + { \ + HistoryTrailer trailer; \ + p.AddTrailer (trailer); \ + } +#define REM_HEADER(p, n) \ + { \ + HistoryHeader header; \ + p.RemoveHeader (header); \ + } +#define REM_TRAILER(p, n) \ + { \ + HistoryTrailer trailer; \ + p.RemoveTrailer (trailer); \ + } +#define CHECK_HISTORY(p, ...) \ + { \ + if (!CheckHistory (p, __FILE__, \ + __LINE__, __VA_ARGS__)) \ + { \ + ok = false; \ + } \ + CleanupPrints (); \ + } + +bool +PacketHistoryTest::RunTests (void) +{ + bool ok = true; + + PacketHistory::Enable (); + + Packet p = Packet (0); + Packet p1 = Packet (0); + + p = Packet (10); + ADD_TRAILER (p, 100); + CHECK_HISTORY (p, 1, 100); + + p = Packet (10); + ADD_HEADER (p, 1); + ADD_HEADER (p, 2); + ADD_HEADER (p, 3); + CHECK_HISTORY (p, 3, + 3, 2, 1); + ADD_HEADER (p, 5); + CHECK_HISTORY (p, 4, + 5, 3, 2, 1); + ADD_HEADER (p, 6); + CHECK_HISTORY (p, 5, + 6, 5, 3, 2, 1); + + p = Packet (10); + ADD_HEADER (p, 1); + ADD_HEADER (p, 2); + ADD_HEADER (p, 3); + REM_HEADER (p, 3); + CHECK_HISTORY (p, 2, + 2, 1); + + p = Packet (10); + ADD_HEADER (p, 1); + ADD_HEADER (p, 2); + ADD_HEADER (p, 3); + REM_HEADER (p, 3); + REM_HEADER (p, 2); + CHECK_HISTORY (p, 1, + 1); + + p = Packet (10); + ADD_HEADER (p, 1); + ADD_HEADER (p, 2); + ADD_HEADER (p, 3); + REM_HEADER (p, 3); + REM_HEADER (p, 2); + REM_HEADER (p, 1); + CHECK_HISTORY (p, 0); + + p = Packet (10); + ADD_HEADER (p, 1); + ADD_HEADER (p, 2); + ADD_HEADER (p, 3); + p1 = p; + REM_HEADER (p1, 3); + REM_HEADER (p1, 2); + REM_HEADER (p1, 1); + CHECK_HISTORY (p1, 0); + CHECK_HISTORY (p, 3, + 3, 2, 1); + ADD_HEADER (p1, 1); + ADD_HEADER (p1, 2); + CHECK_HISTORY (p1, 2, + 2, 1); + CHECK_HISTORY (p, 3, + 3, 2, 1); + ADD_HEADER (p, 3); + CHECK_HISTORY (p, 4, + 3, 3, 2, 1); + ADD_TRAILER (p, 4); + CHECK_HISTORY (p, 5, + 3, 3, 2, 1, 4); + ADD_TRAILER (p, 5); + CHECK_HISTORY (p, 6, + 3, 3, 2, 1, 4, 5); + REM_HEADER (p, 3); + CHECK_HISTORY (p, 5, + 3, 2, 1, 4, 5); + REM_TRAILER (p, 5); + CHECK_HISTORY (p, 4, + 3, 2, 1, 4); + p1 = p; + REM_TRAILER (p, 4); + CHECK_HISTORY (p, 3, + 3, 2, 1); + CHECK_HISTORY (p1, 4, + 3, 2, 1, 4); + p1.RemoveAtStart (3); + CHECK_HISTORY (p1, 3, + 2, 1, 4); + p1.RemoveAtStart (2); + CHECK_HISTORY (p1, 2, + 1, 4); + p1.RemoveAtEnd (4); + CHECK_HISTORY (p1, 1, + 1); + p1.RemoveAtStart (1); + CHECK_HISTORY (p1, 0); + + p = Packet (10); + ADD_HEADER (p, 8); + ADD_TRAILER (p, 8); + ADD_TRAILER (p, 8); + p.RemoveAtStart (8+10+8); + CHECK_HISTORY (p, 1, 8); + + + p = Packet (10); + ADD_HEADER (p, 10); + ADD_HEADER (p, 8); + ADD_TRAILER (p, 6); + ADD_TRAILER (p, 7); + ADD_TRAILER (p, 9); + p.RemoveAtStart (5); + p.RemoveAtEnd (12); + CHECK_HISTORY (p, 2, 10, 6); + + + return ok; +} + +static PacketHistoryTest g_packetHistoryTest; + +}//namespace ns3 diff --git a/src/common/packet-history.h b/src/common/packet-history.h new file mode 100644 index 000000000..efbc82418 --- /dev/null +++ b/src/common/packet-history.h @@ -0,0 +1,188 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2006,2007 INRIA + * All rights reserved. + * + * 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 + * + * Author: Mathieu Lacage + */ +#ifndef PACKET_HISTORY_H +#define PACKET_HISTORY_H + +#include +#include +#include "ns3/callback.h" + +namespace ns3 { + +class Chunk; +class Buffer; + +class PacketPrinter +{ +public: + void PrintForward (void); + void PrintBackward (void); + template + void Add (Callback cb); + +private: + std::vector > m_printers; + bool m_forward; +}; + +class PacketHistory { +public: + static void Enable (void); + + PacketHistory (uint32_t uid, uint32_t size); + PacketHistory (PacketHistory const &o); + PacketHistory &operator = (PacketHistory const& o); + ~PacketHistory (); + + template + void AddHeader (T const &header, uint32_t size); + template + void RemoveHeader (T const &header, uint32_t size); + + template + void AddTrailer (T const &trailer, uint32_t size); + template + void RemoveTrailer (T const &trailer, uint32_t size); + + PacketHistory CreateFragment (uint32_t start, uint32_t length) const; + void AddAtEnd (PacketHistory const&o); + void AddPaddingAtEnd (uint32_t end); + void RemoveAtStart (uint32_t start); + void RemoveAtEnd (uint32_t end); + + void PrintDefault (std::ostream &os, Buffer buffer) const; + void Print (std::ostream &os, Buffer buffer, PacketPrinter printer) const; + +private: + enum CommandType { + INIT_UID = 0, + ADD_HEADER = 1, + REM_HEADER = 2, + ADD_TRAILER = 3, + REM_TRAILER = 4, + ADD_AT_END = 5, + REM_AT_START = 6, + REM_AT_END = 7, + FRAGMENT = 8, + PADDING_AT_END = 9, + INIT_SIZE = 10, + LAST + }; + struct CommandData { + uint32_t m_count; + uint32_t m_size; + uint32_t m_dirtyEnd; + uint8_t m_data[8]; + }; + typedef std::vector > HeadersToPrint; + typedef std::vector > TrailersToPrint; + template + class ChunkUid { + public: + static const uint32_t GetUid (void); + static Chunk *CreateStatic (void); + }; + typedef std::vector > ChunkFactories; + typedef std::vector >::iterator ChunkFactoriesI; + typedef std::vector DataFreeList; + + PacketHistory (); + void Reserve (uint32_t n); + void Construct (uint32_t uid, uint32_t size); + uint32_t GetUleb128Size (uint32_t value) const; + uint32_t GetReverseUleb128Size (uint8_t *buffer) const; + void AppendValue (uint32_t value); + uint32_t ReadValue (uint8_t **pBuffer) const; + void AppendOneCommand (uint32_t type, uint32_t data); + void AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1); + void ReserveCopy (uint32_t size); + void AddHeader (uint32_t uid, Chunk const & header, uint32_t size); + void RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size); + void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); + void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); + static struct PacketHistory::CommandData *Create (uint32_t size); + static void Recycle (struct CommandData *data); + static struct PacketHistory::CommandData *Allocate (uint32_t n); + static void Deallocate (struct CommandData *data); + static Chunk *CreateStatic (uint32_t uid); + static uint32_t RegisterChunkFactory (Chunk *(*createStatic) (void)); + + static DataFreeList m_freeList; + static ChunkFactories m_factories; + static bool m_enable; + static uint32_t m_maxSize; + + struct CommandData *m_data; + uint32_t m_end; + uint32_t m_n; +}; + +}; // namespace ns3 + +namespace ns3 { + +template +const uint32_t +PacketHistory::ChunkUid::GetUid (void) +{ + static uint32_t uid = + PacketHistory::RegisterChunkFactory (&PacketHistory::ChunkUid::CreateStatic); + return uid; +} +template +Chunk * +PacketHistory::ChunkUid::CreateStatic (void) +{ + static T chunk = T (); + return &chunk; +} + + +template +void +PacketHistory::AddHeader (T const &header, uint32_t size) +{ + AddHeader (ChunkUid::GetUid (), header, size); +} + +template +void +PacketHistory::RemoveHeader (T const &header, uint32_t size) +{ + RemoveHeader (ChunkUid::GetUid (), header, size); +} +template +void +PacketHistory::AddTrailer (T const &trailer, uint32_t size) +{ + AddTrailer (ChunkUid::GetUid (), trailer, size); +} +template +void +PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) +{ + RemoveTrailer (ChunkUid::GetUid (), trailer, size); +} + +}; // namespace ns3 + + +#endif /* PACKET_HISTORY_H */ diff --git a/src/common/packet.cc b/src/common/packet.cc index 459cdae39..5372ff83a 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -27,6 +27,7 @@ uint32_t Packet::m_globalUid = 0; Packet::Packet () : m_buffer (), + m_history (m_globalUid, 0), m_uid (m_globalUid) { m_globalUid++; @@ -34,12 +35,14 @@ Packet::Packet () Packet::Packet (uint32_t size) : m_buffer (size), + m_history (m_globalUid, size), m_uid (m_globalUid) { m_globalUid++; } Packet::Packet (uint8_t const*buffer, uint32_t size) : m_buffer (), + m_history (m_globalUid, size), m_uid (m_globalUid) { m_globalUid++; @@ -48,9 +51,10 @@ Packet::Packet (uint8_t const*buffer, uint32_t size) i.Write (buffer, size); } -Packet::Packet (Buffer buffer, Tags tags, uint32_t uid) +Packet::Packet (Buffer buffer, Tags tags, PacketHistory history, uint32_t uid) : m_buffer (buffer), m_tags (tags), + m_history (history), m_uid (uid) {} @@ -58,7 +62,8 @@ Packet Packet::CreateFragment (uint32_t start, uint32_t length) const { Buffer buffer = m_buffer.CreateFragment (start, length); - return Packet (buffer, m_tags, m_uid); + PacketHistory history = m_history.CreateFragment (start, length); + return Packet (buffer, m_tags, history, m_uid); } uint32_t @@ -79,21 +84,25 @@ Packet::AddAtEnd (Packet packet) * XXX: we might need to merge the tag list of the * other packet into the current packet. */ + m_history.AddAtEnd (packet.m_history); } void Packet::AddPaddingAtEnd (uint32_t size) { m_buffer.AddAtEnd (size); + m_history.AddPaddingAtEnd (size); } void Packet::RemoveAtEnd (uint32_t size) { m_buffer.RemoveAtEnd (size); + m_history.RemoveAtEnd (size); } void Packet::RemoveAtStart (uint32_t size) { m_buffer.RemoveAtStart (size); + m_history.RemoveAtStart (size); } void @@ -116,6 +125,8 @@ Packet::GetUid (void) const void Packet::Print (std::ostream &os) const -{} +{ + m_history.PrintDefault (os, m_buffer); +} }; // namespace ns3 diff --git a/src/common/packet.h b/src/common/packet.h index 4a0154d73..2d7cda917 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -26,6 +26,7 @@ #include "header.h" #include "trailer.h" #include "tags.h" +#include "packet-history.h" #include "ns3/callback.h" #include "ns3/assert.h" @@ -129,7 +130,7 @@ public: uint32_t GetSize (void) const; /** * Add header to this packet. This method invokes the - * ns3::Header::GetSerializedSize and ns3::Header::SerializeTo + * ns3::Chunk::GetSerializedSize and ns3::Chunk::SerializeTo * methods to reserve space in the buffer and request the * header to serialize itself in the packet buffer. * @@ -139,8 +140,7 @@ public: void AddHeader (T const &header); /** * Deserialize and remove the header from the internal buffer. - * This method invokes ns3::Header::DeserializeFrom - * and then removes the deserialized bytes from the buffer. + * This method invokes ns3::Chunk::DeserializeFrom. * * \param header a reference to the header to remove from the internal buffer. * \returns the number of bytes removed from the packet. @@ -149,7 +149,7 @@ public: uint32_t RemoveHeader (T &header); /** * Add trailer to this packet. This method invokes the - * ns3::Trailer::GetSerializedSize and ns3::Trailer::serializeTo + * ns3::Chunk::GetSerializedSize and ns3::Trailer::serializeTo * methods to reserve space in the buffer and request the trailer * to serialize itself in the packet buffer. * @@ -159,8 +159,7 @@ public: void AddTrailer (T const &trailer); /** * Remove a deserialized trailer from the internal buffer. - * This method invokes the ns3::Trailer::DeserializeFrom method - * and then removes the deserialized bytes from the buffer. + * This method invokes the ns3::Chunk::DeserializeFrom method. * * \param trailer a reference to the trailer to remove from the internal buffer. * \returns the number of bytes removed from the end of the packet. @@ -256,9 +255,10 @@ public: void Print (std::ostream &os) const; private: - Packet (Buffer buffer, Tags tags, uint32_t uid); + Packet (Buffer buffer, Tags tags, PacketHistory history, uint32_t uid); Buffer m_buffer; Tags m_tags; + PacketHistory m_history; uint32_t m_uid; static uint32_t m_globalUid; }; @@ -282,6 +282,7 @@ Packet::AddHeader (T const &header) uint32_t size = header.GetSize (); m_buffer.AddAtStart (size); header.Serialize (m_buffer.Begin ()); + m_history.AddHeader (header, size); } template uint32_t @@ -291,6 +292,7 @@ Packet::RemoveHeader (T &header) "Must pass Header subclass to Packet::RemoveHeader"); uint32_t deserialized = header.Deserialize (m_buffer.Begin ()); m_buffer.RemoveAtStart (deserialized); + m_history.RemoveHeader (header, deserialized); return deserialized; } template @@ -301,8 +303,10 @@ Packet::AddTrailer (T const &trailer) "Must pass Trailer subclass to Packet::AddTrailer"); uint32_t size = trailer.GetSize (); m_buffer.AddAtEnd (size); - Buffer::Iterator end = m_buffer.End (); - trailer.Serialize (end); + Buffer::Iterator start = m_buffer.End (); + start.Prev (size); + trailer.Serialize (start); + m_history.AddTrailer (trailer, size); } template uint32_t @@ -312,6 +316,7 @@ Packet::RemoveTrailer (T &trailer) "Must pass Trailer subclass to Packet::RemoveTrailer"); uint32_t deserialized = trailer.Deserialize (m_buffer.End ()); m_buffer.RemoveAtEnd (deserialized); + m_history.RemoveTrailer (trailer, deserialized); return deserialized; } From b71248e0f392195eb44f969d725b526e62e84b5b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 29 May 2007 16:24:40 +0200 Subject: [PATCH 002/116] keep track of the aggregation state --- src/common/packet-history.cc | 48 +++++++++++++++++++++++++++--------- src/common/packet-history.h | 5 +++- src/common/packet.cc | 3 ++- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 564c899fd..2a6a2d1ff 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -42,14 +42,16 @@ PacketHistory::Enable (void) PacketHistory::PacketHistory () : m_data (0), m_end (0), - m_n (0) + m_n (0), + m_aggregated (false) { Construct (0, 0); } PacketHistory::PacketHistory (uint32_t uid, uint32_t size) : m_data (0), m_end (0), - m_n (0) + m_n (0), + m_aggregated (false) { Construct (uid, size); } @@ -66,7 +68,8 @@ PacketHistory::Construct (uint32_t uid, uint32_t size) PacketHistory::PacketHistory (PacketHistory const &o) : m_data (o.m_data), m_end (o.m_end), - m_n (o.m_n) + m_n (o.m_n), + m_aggregated (o.m_aggregated) { if (m_data != 0) { @@ -92,6 +95,7 @@ PacketHistory::operator = (PacketHistory const& o) m_data = o.m_data; m_end = o.m_end; m_n = o.m_n; + m_aggregated = o.m_aggregated; if (m_data != 0) { m_data->m_count++; @@ -364,9 +368,12 @@ PacketHistory::ReadValue (uint8_t **pBuffer) const } PacketHistory -PacketHistory::CreateFragment (uint32_t start, uint32_t length) const +PacketHistory::CreateFragment (uint32_t start, uint32_t end) const { - return *this; + PacketHistory fragment = *this; + fragment.RemoveAtStart (start); + fragment.RemoveAtEnd (end); + return fragment; } void @@ -406,6 +413,7 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { if (m_enable) { + m_aggregated = true; uint32_t n = GetUleb128Size (PacketHistory::ADD_AT_END); n += o.m_end; Reserve (n); @@ -444,13 +452,8 @@ PacketHistory::RemoveAtEnd (uint32_t end) } void -PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const +PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const { - if (!m_enable) - { - return; - } - Buffer original = buffer; HeadersToPrint headersToPrint; TrailersToPrint trailersToPrint; @@ -600,6 +603,29 @@ PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const } } +void +PacketHistory::PrintComplex (std::ostream &os, Buffer buffer) const +{ +} + +void +PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const +{ + if (!m_enable) + { + return; + } + + if (m_aggregated) + { + PrintComplex (os, buffer); + } + else + { + PrintSimple (os, buffer); + } +} + Chunk * PacketHistory::CreateStatic (uint32_t uid) diff --git a/src/common/packet-history.h b/src/common/packet-history.h index efbc82418..429447d64 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -62,13 +62,15 @@ public: template void RemoveTrailer (T const &trailer, uint32_t size); - PacketHistory CreateFragment (uint32_t start, uint32_t length) const; + PacketHistory CreateFragment (uint32_t start, uint32_t end) const; void AddAtEnd (PacketHistory const&o); void AddPaddingAtEnd (uint32_t end); void RemoveAtStart (uint32_t start); void RemoveAtEnd (uint32_t end); void PrintDefault (std::ostream &os, Buffer buffer) const; + void PrintSimple (std::ostream &os, Buffer buffer) const; + void PrintComplex (std::ostream &os, Buffer buffer) const; void Print (std::ostream &os, Buffer buffer, PacketPrinter printer) const; private: @@ -133,6 +135,7 @@ private: struct CommandData *m_data; uint32_t m_end; uint32_t m_n; + bool m_aggregated; }; }; // namespace ns3 diff --git a/src/common/packet.cc b/src/common/packet.cc index 5372ff83a..9b36f3f66 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -62,7 +62,8 @@ Packet Packet::CreateFragment (uint32_t start, uint32_t length) const { Buffer buffer = m_buffer.CreateFragment (start, length); - PacketHistory history = m_history.CreateFragment (start, length); + uint32_t end = buffer.GetSize () - (start + length); + PacketHistory history = m_history.CreateFragment (start, end); return Packet (buffer, m_tags, history, m_uid); } From fe44d27cdecf31feecbe37074a53b959d07d5041 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 29 May 2007 16:53:53 +0200 Subject: [PATCH 003/116] prepare for forward iteration of history. --- src/common/packet-history.cc | 52 +++++++++++++++++++++++++----------- src/common/packet-history.h | 4 ++- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 2a6a2d1ff..25f8c65ba 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -195,13 +195,13 @@ PacketHistory::AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1) else { uint8_t *buffer = &(m_data->m_data[m_end]); - uint32_t lastType = ReadValue (&buffer); + uint32_t lastType = ReadReverseValue (&buffer); if (lastType == type) { - uint32_t lastData = ReadValue (&buffer); + uint32_t lastData = ReadReverseValue (&buffer); if (lastData == data0) { - lastData = ReadValue (&buffer); + lastData = ReadReverseValue (&buffer); if (lastData == data1) { return; @@ -237,10 +237,10 @@ PacketHistory::AppendOneCommand (uint32_t type, uint32_t data) else { uint8_t *buffer = &(m_data->m_data[m_end]); - uint32_t lastType = ReadValue (&buffer); + uint32_t lastType = ReadReverseValue (&buffer); if (lastType == type) { - uint32_t lastData = ReadValue (&buffer); + uint32_t lastData = ReadReverseValue (&buffer); if (lastData == data) { return; @@ -339,11 +339,8 @@ PacketHistory::AppendValue (uint32_t value) } uint32_t -PacketHistory::ReadValue (uint8_t **pBuffer) const +PacketHistory::ReadValue (uint8_t *buffer, uint32_t *n) const { - uint32_t n = GetReverseUleb128Size (*pBuffer); - NS_ASSERT (n > 0); - uint8_t *buffer = *pBuffer - n + 1; uint32_t result = 0; uint8_t shift, byte; result = 0; @@ -353,6 +350,7 @@ PacketHistory::ReadValue (uint8_t **pBuffer) const buffer++; result |= (byte & (~0x80))< 0); + uint8_t *buffer = *pBuffer - n + 1; + uint32_t read = 0; + uint32_t result = ReadValue (buffer, &read); + NS_ASSERT (read == n); *pBuffer = *pBuffer - n; return result; } +uint32_t +PacketHistory::ReadForwardValue (uint8_t **pBuffer) const +{ + uint32_t read = 0; + uint32_t result = ReadValue (*pBuffer, &read); + *pBuffer = *pBuffer + read; + return result; +} + PacketHistory PacketHistory::CreateFragment (uint32_t start, uint32_t end) const { @@ -464,8 +483,8 @@ PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const int32_t curEnd = end; for (uint32_t i = 0; i < m_n; i++) { - uint32_t type = ReadValue (&dataBuffer); - uint32_t data = ReadValue (&dataBuffer); + uint32_t type = ReadReverseValue (&dataBuffer); + uint32_t data = ReadReverseValue (&dataBuffer); switch (type) { case PacketHistory::INIT_UID: @@ -474,7 +493,7 @@ PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const std::cout << "init size=" << data << std::endl; break; case PacketHistory::ADD_HEADER: { - int32_t size = ReadValue (&dataBuffer); + int32_t size = ReadReverseValue (&dataBuffer); if (curStart == start) { if (start + size < end) @@ -513,7 +532,7 @@ PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const } } break; case PacketHistory::REM_HEADER: { - int32_t size = ReadValue (&dataBuffer); + int32_t size = ReadReverseValue (&dataBuffer); if (curStart <= start) { // header lies entirely outside of data area. @@ -525,7 +544,7 @@ PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const } } break; case PacketHistory::ADD_TRAILER: { - int32_t size = ReadValue (&dataBuffer); + int32_t size = ReadReverseValue (&dataBuffer); if (curEnd == end) { if (end - size >= start) @@ -561,7 +580,7 @@ PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const } } break; case PacketHistory::REM_TRAILER: { - int32_t size = ReadValue (&dataBuffer); + int32_t size = ReadReverseValue (&dataBuffer); if (curEnd >= end) { curEnd += size; @@ -606,6 +625,9 @@ PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const void PacketHistory::PrintComplex (std::ostream &os, Buffer buffer) const { + // we need to build a linked list of the different fragments + // which are stored in this packet. + } void diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 429447d64..1029d0f71 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -112,7 +112,9 @@ private: uint32_t GetUleb128Size (uint32_t value) const; uint32_t GetReverseUleb128Size (uint8_t *buffer) const; void AppendValue (uint32_t value); - uint32_t ReadValue (uint8_t **pBuffer) const; + uint32_t ReadForwardValue (uint8_t **pBuffer) const; + uint32_t ReadReverseValue (uint8_t **pBuffer) const; + uint32_t ReadValue (uint8_t *buffer, uint32_t *n) const; void AppendOneCommand (uint32_t type, uint32_t data); void AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1); void ReserveCopy (uint32_t size); From 639231388c76edf50f1be7c6c3133fa62cb934fd Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 30 May 2007 07:42:56 +0200 Subject: [PATCH 004/116] implement ItemList construction --- src/common/packet-history.cc | 208 ++++++++++++++++++++++++++++++++++- src/common/packet-history.h | 1 - 2 files changed, 207 insertions(+), 2 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 25f8c65ba..14d10981f 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -19,12 +19,178 @@ * Author: Mathieu Lacage */ #include +#include #include "ns3/assert.h" #include "ns3/fatal-error.h" #include "packet-history.h" #include "chunk.h" #include "buffer.h" +namespace { + +class ItemList +{ +public: + void InitPayload (uint32_t uid, uint32_t size); + void AddHeader (uint32_t type, uint32_t size); + void AddTrailer (uint32_t type, uint32_t size); + + void RemHeader (uint32_t type, uint32_t size); + void RemTrailer (uint32_t type, uint32_t size); + + void RemAtStart (uint32_t toRemove); + void RemAtEnd (uint32_t toRemove); + + void AddAtEnd (ItemList const *other); + +private: + enum Type { + PAYLOAD, + CHUNK, + }; + struct Item + { + enum ItemList::Type m_type; + uint32_t m_size; + uint32_t m_chunkType; + uint32_t m_fragmentStart; + uint32_t m_fragmentEnd; + uint32_t m_uid; + }; + std::list m_itemList; +}; + +void +ItemList::InitPayload (uint32_t uid, uint32_t size) +{ + NS_ASSERT (m_itemList.empty ()); + struct Item item; + item.m_type = ItemList::PAYLOAD; + item.m_size = size; + item.m_fragmentStart = 0; + item.m_fragmentEnd = item.m_size; + item.m_uid = uid; + m_itemList.push_back (item); +} + +void +ItemList::AddHeader (uint32_t type, uint32_t size) +{ + struct Item item; + item.m_type = ItemList::CHUNK; + item.m_chunkType = type; + item.m_size = size; + item.m_fragmentStart = 0; + item.m_fragmentEnd = size; + item.m_uid = m_itemList.front ().m_uid; + m_itemList.push_front (item); +} + +void +ItemList::AddTrailer (uint32_t type, uint32_t size) +{ + struct Item item; + item.m_type = ItemList::CHUNK; + item.m_chunkType = type; + item.m_size = size; + item.m_fragmentStart = 0; + item.m_fragmentEnd = size; + item.m_uid = m_itemList.back ().m_uid; + m_itemList.push_back (item); +} + +void +ItemList::RemHeader (uint32_t type, uint32_t size) +{ + struct Item item = m_itemList.front (); + if (item.m_type != CHUNK || + item.m_size != size || + item.m_chunkType != type) + { + NS_FATAL_ERROR ("Removing Unexpected header"); + } + else if (item.m_fragmentStart != 0 || + item.m_fragmentEnd != item.m_size) + { + NS_FATAL_ERROR ("Removing non-complete header"); + } + m_itemList.pop_front (); +} +void +ItemList::RemTrailer (uint32_t type, uint32_t size) +{ + struct Item item = m_itemList.back (); + if (item.m_type != CHUNK || + item.m_size != size || + item.m_chunkType != type) + { + NS_FATAL_ERROR ("Removing Unexpected trailer"); + } + else if (item.m_fragmentStart != 0 || + item.m_fragmentEnd != item.m_size) + { + NS_FATAL_ERROR ("Removing non-complete trailer"); + } + m_itemList.pop_back (); +} + +void +ItemList::RemAtStart (uint32_t toRemove) +{ + uint32_t leftToRemove = toRemove; + while (!m_itemList.empty () && leftToRemove > 0) + { + struct Item &item = m_itemList.front (); + if (item.m_size >= leftToRemove) + { + m_itemList.pop_front (); + leftToRemove -= item.m_size; + } + else + { + item.m_size -= leftToRemove; + item.m_fragmentStart += leftToRemove; + leftToRemove = 0; + NS_ASSERT (item.m_size == item.m_fragmentEnd - item.m_fragmentStart && + item.m_fragmentStart <= item.m_fragmentEnd); + } + } + NS_ASSERT (leftToRemove == 0); +} +void +ItemList::RemAtEnd (uint32_t toRemove) +{ + uint32_t leftToRemove = toRemove; + while (!m_itemList.empty () && leftToRemove > 0) + { + struct Item &item = m_itemList.back (); + if (item.m_size >= leftToRemove) + { + m_itemList.pop_back (); + leftToRemove -= item.m_size; + } + else + { + item.m_size -= leftToRemove; + item.m_fragmentEnd -= leftToRemove; + leftToRemove = 0; + } + NS_ASSERT (item.m_size == item.m_fragmentEnd - item.m_fragmentStart && + item.m_fragmentStart <= item.m_fragmentEnd); + } + NS_ASSERT (leftToRemove == 0); +} + +void +ItemList::AddAtEnd (ItemList const *other) +{ + +} + + + +} // anonymous namespace + namespace ns3 { bool PacketHistory::m_enable = false; @@ -627,7 +793,47 @@ PacketHistory::PrintComplex (std::ostream &os, Buffer buffer) const { // we need to build a linked list of the different fragments // which are stored in this packet. - + uint8_t *dataBuffer = &m_data->m_data[0]; + ItemList itemList; + for (uint32_t i = 0; i < m_n; i++) + { + uint32_t type = ReadForwardValue (&dataBuffer); + uint32_t data = ReadForwardValue (&dataBuffer); + switch (type) + { + case INIT_UID: + break; + case INIT_SIZE: { + itemList.InitPayload (0, data); + } break; + case ADD_HEADER: { + uint32_t size = ReadForwardValue (&dataBuffer); + itemList.AddHeader (data, size); + } break; + case REM_HEADER: { + uint32_t size = ReadForwardValue (&dataBuffer); + itemList.RemHeader (data, size); + } break; + case ADD_TRAILER: { + uint32_t size = ReadForwardValue (&dataBuffer); + itemList.AddTrailer (data, size); + } break; + case REM_TRAILER: { + uint32_t size = ReadForwardValue (&dataBuffer); + itemList.RemTrailer (data, size); + } break; + case ADD_AT_END: + break; + case REM_AT_START: { + itemList.RemAtStart (data); + } break; + case REM_AT_END: { + itemList.RemAtEnd (data); + } break; + case PADDING_AT_END: + break; + } + } } void diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 1029d0f71..d6866b26b 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -83,7 +83,6 @@ private: ADD_AT_END = 5, REM_AT_START = 6, REM_AT_END = 7, - FRAGMENT = 8, PADDING_AT_END = 9, INIT_SIZE = 10, LAST From d9f03cafbe4edeab13e330347c08696e42ad324e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 30 May 2007 09:48:53 +0200 Subject: [PATCH 005/116] implement ItemList::AddAtEnd --- src/common/packet-history.cc | 55 ++++++++++++++++++++++++++++++------ src/common/packet-history.h | 10 +++++-- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 14d10981f..256e397e7 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -43,6 +43,8 @@ public: void AddAtEnd (ItemList const *other); + void Print (std::ostream &os, ns3::Buffer buffer) const; + private: enum Type { PAYLOAD, @@ -66,6 +68,7 @@ ItemList::InitPayload (uint32_t uid, uint32_t size) NS_ASSERT (m_itemList.empty ()); struct Item item; item.m_type = ItemList::PAYLOAD; + item.m_chunkType = 0; item.m_size = size; item.m_fragmentStart = 0; item.m_fragmentEnd = item.m_size; @@ -168,7 +171,7 @@ ItemList::RemAtEnd (uint32_t toRemove) { m_itemList.pop_back (); leftToRemove -= item.m_size; - } + } else { item.m_size -= leftToRemove; @@ -176,7 +179,8 @@ ItemList::RemAtEnd (uint32_t toRemove) leftToRemove = 0; } NS_ASSERT (item.m_size == item.m_fragmentEnd - item.m_fragmentStart && - item.m_fragmentStart <= item.m_fragmentEnd); + item.m_fragmentStart <= item.m_fragmentEnd && + item.m_fragmentEnd <= item.m_size); } NS_ASSERT (leftToRemove == 0); } @@ -184,10 +188,30 @@ ItemList::RemAtEnd (uint32_t toRemove) void ItemList::AddAtEnd (ItemList const *other) { - + for (std::list::const_iterator i = other->m_itemList.begin (); + i != other->m_itemList.end (); i++) + { + const ItemList::Item &item = *i; + ItemList::Item &last = m_itemList.back (); + if (item.m_uid == last.m_uid && + item.m_type == last.m_type && + item.m_chunkType == last.m_chunkType && + item.m_size == last.m_size && + last.m_fragmentEnd != last.m_size && + item.m_fragmentStart == last.m_fragmentEnd) + { + last.m_fragmentEnd = item.m_fragmentEnd; + } + else + { + m_itemList.push_back (item); + } + } } - +void +ItemList::Print (std::ostream &os, ns3::Buffer buffer) const +{} } // anonymous namespace @@ -525,7 +549,7 @@ PacketHistory::ReadValue (uint8_t *buffer, uint32_t *n) const /* This means that the LEB128 number was not valid. * ie: the last (5th) byte did not have the high-order bit zeroed. */ - result = -1; + result = 0xffffffff; } return result; } @@ -600,6 +624,7 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { m_aggregated = true; uint32_t n = GetUleb128Size (PacketHistory::ADD_AT_END); + n += GetUleb128Size (o.m_end); n += o.m_end; Reserve (n); memcpy (&m_data->m_data[m_end], o.m_data->m_data, o.m_end); @@ -608,7 +633,7 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { m_data->m_dirtyEnd = m_end; } - AppendOneCommand (PacketHistory::ADD_AT_END, 0); + AppendOneCommand (PacketHistory::ADD_AT_END, o.m_end); } } void @@ -795,6 +820,17 @@ PacketHistory::PrintComplex (std::ostream &os, Buffer buffer) const // which are stored in this packet. uint8_t *dataBuffer = &m_data->m_data[0]; ItemList itemList; + BuildItemList (&itemList, dataBuffer, m_end); + itemList.Print (os, buffer); +} + +void +PacketHistory::BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) const +{ + // we need to build a linked list of the different fragments + // which are stored in this packet. + uint8_t *dataBuffer = buffer; + ItemList itemList; for (uint32_t i = 0; i < m_n; i++) { uint32_t type = ReadForwardValue (&dataBuffer); @@ -822,8 +858,11 @@ PacketHistory::PrintComplex (std::ostream &os, Buffer buffer) const uint32_t size = ReadForwardValue (&dataBuffer); itemList.RemTrailer (data, size); } break; - case ADD_AT_END: - break; + case ADD_AT_END: { + ItemList other; + BuildItemList (&other, dataBuffer, data); + itemList.AddAtEnd (&other); + } break; case REM_AT_START: { itemList.RemAtStart (data); } break; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index d6866b26b..e072a6a6d 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -25,6 +25,10 @@ #include #include "ns3/callback.h" +namespace { +class ItemList; +} + namespace ns3 { class Chunk; @@ -69,8 +73,6 @@ public: void RemoveAtEnd (uint32_t end); void PrintDefault (std::ostream &os, Buffer buffer) const; - void PrintSimple (std::ostream &os, Buffer buffer) const; - void PrintComplex (std::ostream &os, Buffer buffer) const; void Print (std::ostream &os, Buffer buffer, PacketPrinter printer) const; private: @@ -121,6 +123,10 @@ private: void RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size); void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); + void PrintSimple (std::ostream &os, Buffer buffer) const; + void PrintComplex (std::ostream &os, Buffer buffer) const; + void BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) const; + static struct PacketHistory::CommandData *Create (uint32_t size); static void Recycle (struct CommandData *data); static struct PacketHistory::CommandData *Allocate (uint32_t n); From 66c3a25fe1df34810316138c8a92c048031ded53 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 30 May 2007 10:03:15 +0200 Subject: [PATCH 006/116] add Chunk::GetName and implement it --- samples/main-packet.cc | 6 ++++++ src/common/chunk.cc | 5 +++++ src/common/chunk.h | 2 ++ src/common/header.h | 4 ++++ src/common/packet-history.cc | 20 ++++++++++++++++++++ src/common/trailer.h | 4 ++++ src/internet-node/arp-header.cc | 5 +++++ src/internet-node/arp-header.h | 1 + src/internet-node/ipv4-header.cc | 6 ++++++ src/internet-node/ipv4-header.h | 1 + src/internet-node/udp-header.cc | 6 +++++- src/internet-node/udp-header.h | 1 + src/node/llc-snap-header.cc | 6 ++++++ src/node/llc-snap-header.h | 1 + 14 files changed, 67 insertions(+), 1 deletion(-) diff --git a/samples/main-packet.cc b/samples/main-packet.cc index 01b46097c..777f95815 100644 --- a/samples/main-packet.cc +++ b/samples/main-packet.cc @@ -15,6 +15,7 @@ public: void SetData (uint16_t data); uint16_t GetData (void) const; private: + virtual std::string DoGetName (void) const; virtual void PrintTo (std::ostream &os) const; virtual void SerializeTo (Buffer::Iterator start) const; virtual uint32_t DeserializeFrom (Buffer::Iterator start); @@ -27,6 +28,11 @@ MyHeader::MyHeader () {} MyHeader::~MyHeader () {} +std::string +MyHeader::DoGetName (void) const +{ + return "MyHeader"; +} void MyHeader::PrintTo (std::ostream &os) const { diff --git a/src/common/chunk.cc b/src/common/chunk.cc index 34c6cbce6..52c1112c3 100644 --- a/src/common/chunk.cc +++ b/src/common/chunk.cc @@ -30,6 +30,11 @@ Chunk::Chunk () Chunk::~Chunk () {} +std::string +Chunk::GetName (void) const +{ + return DoGetName (); +} void Chunk::Print (std::ostream &os) const { diff --git a/src/common/chunk.h b/src/common/chunk.h index 9aa025f96..ab568cd9f 100644 --- a/src/common/chunk.h +++ b/src/common/chunk.h @@ -33,11 +33,13 @@ public: Chunk (); virtual ~Chunk (); + std::string GetName (void) const; void Print (std::ostream &os) const; uint32_t GetSize (void) const; void Serialize (Buffer::Iterator start) const; uint32_t Deserialize (Buffer::Iterator start); private: + virtual std::string DoGetName (void) const = 0; virtual void PrintTo (std::ostream &os) const = 0; virtual uint32_t GetSerializedSize (void) const = 0; virtual void SerializeTo (Buffer::Iterator i) const = 0; diff --git a/src/common/header.h b/src/common/header.h index b51b520ba..18ff84bb2 100644 --- a/src/common/header.h +++ b/src/common/header.h @@ -41,6 +41,10 @@ class Header : public Chunk { public: virtual ~Header (); private: + /** + * \returns a user-readable name to identify this type of header. + */ + virtual std::string DoGetName (void) const = 0; /** * \param os the std output stream in which this * protocol header must print itself. diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 256e397e7..4a0e65e88 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -925,6 +925,7 @@ PacketHistory::RegisterChunkFactory (Chunk *(*createStatic) (void)) #include #include +#include #include "ns3/test.h" #include "header.h" #include "trailer.h" @@ -964,12 +965,22 @@ template class HistoryHeader : public Header { private: + virtual std::string DoGetName (void) const; virtual void PrintTo (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; virtual void SerializeTo (Buffer::Iterator start) const; virtual uint32_t DeserializeFrom (Buffer::Iterator start); }; +template +std::string +HistoryHeader::DoGetName (void) const +{ + std::ostringstream oss; + oss << N; + return oss.str (); +} + template void HistoryHeader::PrintTo (std::ostream &os) const @@ -1006,12 +1017,21 @@ template class HistoryTrailer : public Trailer { private: + virtual std::string DoGetName (void) const; virtual void PrintTo (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; virtual void SerializeTo (Buffer::Iterator start) const; virtual uint32_t DeserializeFrom (Buffer::Iterator start); }; +template +std::string +HistoryTrailer::DoGetName (void) const +{ + std::ostringstream oss; + oss << N; + return oss.str (); +} template void HistoryTrailer::PrintTo (std::ostream &os) const diff --git a/src/common/trailer.h b/src/common/trailer.h index 7ad1e7c31..90d75f2c5 100644 --- a/src/common/trailer.h +++ b/src/common/trailer.h @@ -41,6 +41,10 @@ class Trailer : public Chunk { public: virtual ~Trailer (); private: + /** + * \returns a user-readable name to identify this type of header. + */ + virtual std::string DoGetName (void) const = 0; /** * \param os the std output stream in which this * protocol trailer must print itself. diff --git a/src/internet-node/arp-header.cc b/src/internet-node/arp-header.cc index 3554681ee..0263a29ee 100644 --- a/src/internet-node/arp-header.cc +++ b/src/internet-node/arp-header.cc @@ -83,6 +83,11 @@ ArpHeader::GetDestinationIpv4Address (void) return m_ipv4Dest; } +std::string +ArpHeader::DoGetName (void) const +{ + return "Arp"; +} void ArpHeader::PrintTo (std::ostream &os) const diff --git a/src/internet-node/arp-header.h b/src/internet-node/arp-header.h index d215186ac..9f85579f5 100644 --- a/src/internet-node/arp-header.h +++ b/src/internet-node/arp-header.h @@ -50,6 +50,7 @@ class ArpHeader : public Header { Ipv4Address GetDestinationIpv4Address (void); private: + virtual std::string DoGetName (void) const; /** * \param os */ diff --git a/src/internet-node/ipv4-header.cc b/src/internet-node/ipv4-header.cc index 15be05cab..6242bec23 100644 --- a/src/internet-node/ipv4-header.cc +++ b/src/internet-node/ipv4-header.cc @@ -190,6 +190,12 @@ Ipv4Header::IsChecksumOk (void) const return m_goodChecksum; } +std::string +Ipv4Header::DoGetName (void) const +{ + return "Ipv4"; +} + void Ipv4Header::PrintTo (std::ostream &os) const { diff --git a/src/internet-node/ipv4-header.h b/src/internet-node/ipv4-header.h index 910313073..b45ed9f02 100644 --- a/src/internet-node/ipv4-header.h +++ b/src/internet-node/ipv4-header.h @@ -140,6 +140,7 @@ public: bool IsChecksumOk (void) const; private: + virtual std::string DoGetName (void) const; virtual void PrintTo (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; virtual void SerializeTo (Buffer::Iterator start) const; diff --git a/src/internet-node/udp-header.cc b/src/internet-node/udp-header.cc index 38a7fa7d8..c4ef2642d 100644 --- a/src/internet-node/udp-header.cc +++ b/src/internet-node/udp-header.cc @@ -91,7 +91,11 @@ UdpHeader::InitializeChecksum (Ipv4Address source, m_initialChecksum = Ipv4ChecksumCalculate (0, buf, 12); } - +std::string +UdpHeader::DoGetName (void) const +{ + return "Udp"; +} void UdpHeader::PrintTo (std::ostream &os) const diff --git a/src/internet-node/udp-header.h b/src/internet-node/udp-header.h index 1948440cf..332614ba0 100644 --- a/src/internet-node/udp-header.h +++ b/src/internet-node/udp-header.h @@ -81,6 +81,7 @@ public: uint8_t protocol); private: + virtual std::string DoGetName (void) const; virtual void PrintTo (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; virtual void SerializeTo (Buffer::Iterator start) const; diff --git a/src/node/llc-snap-header.cc b/src/node/llc-snap-header.cc index 6f4b2295f..b7bd73121 100644 --- a/src/node/llc-snap-header.cc +++ b/src/node/llc-snap-header.cc @@ -47,6 +47,12 @@ LlcSnapHeader::GetSerializedSize (void) const return 1 + 1 + 1 + 3 + 2; } +std::string +LlcSnapHeader::DoGetName (void) const +{ + return "LlcSnap"; +} + void LlcSnapHeader::PrintTo (std::ostream &os) const { diff --git a/src/node/llc-snap-header.h b/src/node/llc-snap-header.h index 5b7457ad6..ad98cda7c 100644 --- a/src/node/llc-snap-header.h +++ b/src/node/llc-snap-header.h @@ -37,6 +37,7 @@ class LlcSnapHeader : public Header { uint16_t GetType (void); private: + virtual std::string DoGetName (void) const; virtual void PrintTo (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; virtual void SerializeTo (Buffer::Iterator start) const; From e7abed2defc53542ef321067f5eee07dd1d07e87 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 30 May 2007 12:45:32 +0200 Subject: [PATCH 007/116] try to design a packer printer class --- src/common/packet-printer.cc | 55 +++++++++++++ src/common/packet-printer.h | 150 +++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 src/common/packet-printer.cc create mode 100644 src/common/packet-printer.h diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc new file mode 100644 index 000000000..e8fcd44a7 --- /dev/null +++ b/src/common/packet-printer.cc @@ -0,0 +1,55 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * All rights reserved. + * + * 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 + * + * Author: Mathieu Lacage + */ + +#include "packet-printer.h" + +namespace ns3 { + +PacketPrinter::PacketPrinter () + : m_forward (true) +{} + +void +PacketPrinter::PrintForward (void) +{} +void +PacketPrinter::PrintBackward (void) +{} +void +PacketPrinter::AddPayloadPrinter (Callback printer) +{ + m_payloadPrinter = printer; +} + /** + * \param printer Arguments: output stream, packet uid, size, header/trailer name, fragment information + */ + void AddDefaultPrinter (Callback printer); + +} // namespace ns3 diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h new file mode 100644 index 000000000..d298d60db --- /dev/null +++ b/src/common/packet-printer.h @@ -0,0 +1,150 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * All rights reserved. + * + * 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 + * + * Author: Mathieu Lacage + */ +#ifndef PACKET_PRINTER_H +#define PACKET_PRINTER_H + +#include "ns3/callback.h" +#include "ns3/ptr.h" + +namespace ns3 { + +class PacketPrinter +{ +public: + /** + * \brief callback to print payload. + * + * Arguments: output stream, packet uid, size, fragment information + */ + typedef Callback + PayloadPrinter; + + /** + * \brief callback to print whole chunks. + * + * Arguments: output stream, packet uid, size, header/trailer type instance + */ + typedef Callback ChunkPrinter; + + /** + * \brief callback to print fragmented chunks. + * + * Arguments: output stream, packet uid, size, header/trailer name, fragment information + */ + typedef Callback + ChunkFragmentPrinter; + + /** + * \brief callback to print chunks for which no specific callback was specified. + * + * Arguments: output stream, packet uid, size, header/trailer name, fragment information + */ + typedef Callback + DefaultPrinter; + + struct FragmentInformation + { + uint32_t start; + uint32_t end; + }; + + /** + * Print the content of the packet forward. + */ + void PrintForward (void); + /** + * Print the content of the packet backward. + */ + void PrintBackward (void); + /** + * \param printer printer for payload + */ + void AddPayloadPrinter (PayloadPrinter printer); + /** + * \param printer printer for the specified chunk + * \param fragmentPrinter printer for a fragment of the specified chunk + */ + template + void AddPrinter (Callback printer, + ChunkFragmentPrinter fragmentPrinter); + /** + * \param printer printer for a chunk for which no callback was specified explicitely + */ + void AddDefaultPrinter (DefaultPrinter printer); + +private: + friend class PacketHistory; + + static PacketPrinter GetDefault (void); + template + static uint32_t GetUid (void) const; + static std::string GetName (uint32_t uid) const; + static T &CreateStatic (uint32_t uid) const; + + void PrintChunk (uint32_t uid, + Buffer::iterator i, + std::ostream &os, + uint32_t packetUid, + uint32_t size); + void PrintChunkFragment (uint32_t uid, + std::ostream &os, + uint32_t packetUid, + uint32_t size, + uint32_t fragmentStart, + uint32_t fragmentEnd); + void PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size, + uint32_t fragmentStart, uint32_t fragmentEnd); + struct Printer + { + uint32_t m_uid; + Ptr m_printer; + Callback + m_fragmentPrinter; + }; + std::vector m_printers; + bool m_forward; +}; + +} // namespace ns3 + +namespace ns3 { + +template +void +PacketHistory::AddPrinter (Callback printer, + Callback fragmentPrinter) +{ + uint32_t uid = PacketHistory::GetUid (); + struct Printer printer; + printer.m_uid = uid; + printer.m_printer = printer.PeekImpl (); + printer.m_fragmentPrinter = fragmentPrinter; + m_printers.push_back (printer); +} + +} // namespace ns3 + +#endif /* PACKET_PRINTER_H */ From 65f215eee257d159dc1d2747e02cc1bcb051c60f Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 11:03:26 +0200 Subject: [PATCH 008/116] add a new overloaded Assign method --- src/core/callback.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/callback.h b/src/core/callback.h index efeb44be2..526c022a3 100644 --- a/src/core/callback.h +++ b/src/core/callback.h @@ -331,6 +331,16 @@ public: const Callback *goodType = static_cast *> (&other); *this = *goodType; } + void Assign (Ptr other) { + CallbackImpl *impl = dynamic_cast *> (PeekPointer (other)); + if (other == 0) + { + NS_FATAL_ERROR ("Incompatible types. (feed to \"c++filt -t\")" + " got=" << typeid (other).name () << + ", expected=" << typeid (*impl).name ()); + } + *this = Callback (impl); + } private: virtual CallbackImpl *PeekImpl (void) const { return PeekPointer (m_impl); From ab5c0a43bd9d6ae7f7d92b1cc0cdacfe42f5def6 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 11:03:42 +0200 Subject: [PATCH 009/116] rework the PacketPrinter code --- src/common/packet-printer.cc | 83 +++++++++++++++++++---- src/common/packet-printer.h | 123 ++++++++++++++++++++++++++--------- 2 files changed, 164 insertions(+), 42 deletions(-) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index e8fcd44a7..16c83da2c 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -29,10 +29,14 @@ PacketPrinter::PacketPrinter () void PacketPrinter::PrintForward (void) -{} +{ + m_forward = true; +} void PacketPrinter::PrintBackward (void) -{} +{ + m_forward = false; +} void PacketPrinter::AddPayloadPrinter (Callback printer); + +PacketPrinter::RegisteredChunks * +PacketPrinter::GetRegisteredChunks (void) +{ + static RegisteredChunks registeredChunks; + return ®isteredChunks; +} + +void +PacketPrinter::PrintChunk (uint32_t chunkUid, + Buffer::Iterator start, + std::ostream &os, + uint32_t packetUid, + uint32_t size) +{ + RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); + for (PrinterList::iterator i = m_printerList.begin (); i != m_printerList.end (); i++) + { + if (i->m_chunkUid == chunkUid) + { + DoPrintCallback cb = (*registeredChunks)[chunkUid].first; + cb (i->m_printer, start, os, packetUid, size); + return; + } + } + DoGetNameCallback cb = (*registeredChunks)[chunkUid].second; + std::string name = cb (); + struct PacketPrinter::FragmentInformation info; + info.start = 0; + info.end = size; + m_defaultPrinter (os, packetUid, size, name, info); +} +void +PacketPrinter::PrintChunkFragment (uint32_t chunkUid, + std::ostream &os, + uint32_t packetUid, + uint32_t size, + uint32_t fragmentStart, + uint32_t fragmentEnd) +{ + RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); + DoGetNameCallback cb = (*registeredChunks)[chunkUid].second; + std::string name = cb (); + struct PacketPrinter::FragmentInformation info; + info.start = fragmentStart; + info.end = fragmentEnd; + for (PrinterList::iterator i = m_printerList.begin (); i != m_printerList.end (); i++) + { + if (i->m_chunkUid == chunkUid) + { + i->m_fragmentPrinter (os, packetUid, size, name, info); + return; + } + } + m_defaultPrinter (os, packetUid, size, name, info); +} +void +PacketPrinter::PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size, + uint32_t fragmentStart, uint32_t fragmentEnd) +{ + struct PacketPrinter::FragmentInformation info; + info.start = fragmentStart; + info.end = fragmentEnd; + m_payloadPrinter (os, packetUid, size, info); +} + } // namespace ns3 diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index d298d60db..5a07b9529 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -23,12 +23,21 @@ #include "ns3/callback.h" #include "ns3/ptr.h" +#include "buffer.h" +#include namespace ns3 { +class Chunk; + class PacketPrinter { public: + struct FragmentInformation + { + uint32_t start; + uint32_t end; + }; /** * \brief callback to print payload. * @@ -37,13 +46,6 @@ public: typedef Callback PayloadPrinter; - /** - * \brief callback to print whole chunks. - * - * Arguments: output stream, packet uid, size, header/trailer type instance - */ - typedef Callback ChunkPrinter; - /** * \brief callback to print fragmented chunks. * @@ -60,11 +62,7 @@ public: typedef Callback DefaultPrinter; - struct FragmentInformation - { - uint32_t start; - uint32_t end; - }; + PacketPrinter (); /** * Print the content of the packet forward. @@ -92,15 +90,39 @@ public: private: friend class PacketHistory; + struct Printer + { + uint32_t m_chunkUid; + Ptr m_printer; + Callback + m_fragmentPrinter; + }; + typedef void (*DoPrintCallback) (Ptr, Buffer::Iterator, std::ostream &, + uint32_t, uint32_t); + typedef std::string (*DoGetNameCallback) (void); + typedef std::vector PrinterList; + typedef std::vector > RegisteredChunks; + static PacketPrinter GetDefault (void); + template - static uint32_t GetUid (void) const; - static std::string GetName (uint32_t uid) const; - static T &CreateStatic (uint32_t uid) const; + static void DoPrint (Ptr callbackPrinter, + Buffer::Iterator i, + std::ostream &os, + uint32_t packetUid, + uint32_t size); + template + static std::string DoGetName (void); + template + static uint32_t GetUid (void); + template + static uint32_t AllocateUid (void); + static RegisteredChunks *GetRegisteredChunks (void); + void PrintChunk (uint32_t uid, - Buffer::iterator i, + Buffer::Iterator i, std::ostream &os, uint32_t packetUid, uint32_t size); @@ -112,14 +134,11 @@ private: uint32_t fragmentEnd); void PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size, uint32_t fragmentStart, uint32_t fragmentEnd); - struct Printer - { - uint32_t m_uid; - Ptr m_printer; - Callback - m_fragmentPrinter; - }; - std::vector m_printers; + + static PacketPrinter m_defaultPacketPrinter; + PrinterList m_printerList; + PayloadPrinter m_payloadPrinter; + DefaultPrinter m_defaultPrinter; bool m_forward; }; @@ -129,7 +148,7 @@ namespace ns3 { template void -PacketHistory::AddPrinter (Callback printer, +PacketPrinter::AddPrinter (Callback printer, Callback fragmentPrinter) { - uint32_t uid = PacketHistory::GetUid (); - struct Printer printer; - printer.m_uid = uid; - printer.m_printer = printer.PeekImpl (); - printer.m_fragmentPrinter = fragmentPrinter; - m_printers.push_back (printer); + static uint32_t uid = PacketPrinter::GetUid (); + struct PacketPrinter::Printer p; + p.m_chunkUid = uid; + p.m_printer = printer.PeekImpl (); + p.m_fragmentPrinter = fragmentPrinter; + m_printerList.push_back (p); } +template +void +PacketPrinter::DoPrint (Ptr printerCallback, + Buffer::Iterator i, + std::ostream &os, + uint32_t packetUid, + uint32_t size) +{ + T chunk = T (); + chunk.Deserialize (i); + Callback callback; + callback.Assign (printerCallback); + callback (os, packetUid, size, &chunk); +} + +template +std::string +PacketPrinter::DoGetName (void) +{ + T chunk = T (); + return chunk.GetName (); +} + +template +uint32_t +PacketPrinter::GetUid (void) +{ + static uint32_t uid = PacketPrinter::AllocateUid (); + return uid; +} + +template +uint32_t +PacketPrinter::AllocateUid (void) +{ + RegisteredChunks *chunks = PacketPrinter::GetRegisteredChunks (); + chunks->push_back (std::make_pair(&PacketPrinter::DoPrint, + &PacketPrinter::DoGetName)); + return chunks->size (); +} + + } // namespace ns3 #endif /* PACKET_PRINTER_H */ From 4b8dabddaed8a6dcdb90f7f47b68a721c4333b8b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 12:34:33 +0200 Subject: [PATCH 010/116] add support for a default PacketPrinter --- src/common/packet-printer.cc | 54 ++++++++++++++++++++++++++++++++++++ src/common/packet-printer.h | 29 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 16c83da2c..f038a129f 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -54,6 +54,25 @@ PacketPrinter::GetRegisteredChunks (void) return ®isteredChunks; } +PacketPrinter +PacketPrinter::GetDefault (void) +{ + return *(PacketPrinter::PeekDefault ()); +} +PacketPrinter * +PacketPrinter::PeekDefault (void) +{ + static PacketPrinter *tmp = PacketPrinter::CreateStaticDefault (); + return tmp; +} +PacketPrinter * +PacketPrinter::CreateStaticDefault (void) +{ + static PacketPrinter tmp; + return &tmp; +} + + void PacketPrinter::PrintChunk (uint32_t chunkUid, Buffer::Iterator start, @@ -112,5 +131,40 @@ PacketPrinter::PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size m_payloadPrinter (os, packetUid, size, info); } +void +PacketPrinter::DoDefaultPrintPayload (std::ostream & os, + uint32_t packetUid, + uint32_t size, + struct PacketPrinter::FragmentInformation info) +{ + os << "data "; + os << "[" << info.start << ":" << info.end << "] -> " + << "[0:" << size << "]"; + os << std::endl; +} + +void +PacketPrinter::DoDefaultPrintDefault (std::ostream & os, + uint32_t packetUid, + uint32_t size, + std::string &name, + struct PacketPrinter::FragmentInformation info) +{ + NS_ASSERT_MSG (false, "This should never happen because we provide a printer for _all_ chunk types."); +} + +void +PacketPrinter::DoDefaultPrintFragment (std::ostream & os, + uint32_t packetUid, + uint32_t size, + std::string &name, + struct PacketPrinter::FragmentInformation info) +{ + os << name << " "; + os << "[" << info.start << ":" << info.end << "] -> " + << "[0:" << size << "]"; + os << std::endl; +} + } // namespace ns3 diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 5a07b9529..116607007 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -105,6 +105,24 @@ private: static PacketPrinter GetDefault (void); + static PacketPrinter *PeekDefault (void); + static PacketPrinter *CreateStaticDefault (void); + static void DoDefaultPrintPayload (std::ostream & os, + uint32_t packetUid, + uint32_t size, + struct PacketPrinter::FragmentInformation info); + static void DoDefaultPrintDefault (std::ostream & os, + uint32_t packetUid, + uint32_t size, + std::string &name, + struct PacketPrinter::FragmentInformation info); + template + static void DoDefaultPrint (std::ostream &os, uint32_t packetUid, uint32_t size, const T *chunk); + static void DoDefaultPrintFragment (std::ostream & os, + uint32_t packetUid, + uint32_t size, + std::string &name, + struct PacketPrinter::FragmentInformation info); template static void DoPrint (Ptr callbackPrinter, @@ -202,9 +220,20 @@ PacketPrinter::AllocateUid (void) RegisteredChunks *chunks = PacketPrinter::GetRegisteredChunks (); chunks->push_back (std::make_pair(&PacketPrinter::DoPrint, &PacketPrinter::DoGetName)); + PacketPrinter::PeekDefault ()->AddPrinter (MakeCallback (&PacketPrinter::DoDefaultPrint), + MakeCallback (&PacketPrinter::DoDefaultPrintFragment)); return chunks->size (); } +template +void +PacketPrinter::DoDefaultPrint (std::ostream &os, uint32_t packetUid, uint32_t size, const T *chunk) +{ + chunk->Print (os); + os << std::endl; +} + + } // namespace ns3 From afb85320bfff266431747ba9a0e36ed1463d5645 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 13:37:05 +0200 Subject: [PATCH 011/116] constify, allow ItemList access to private methods --- src/common/packet-printer.cc | 10 +++++----- src/common/packet-printer.h | 11 ++++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index f038a129f..0c0eaeadc 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -78,10 +78,10 @@ PacketPrinter::PrintChunk (uint32_t chunkUid, Buffer::Iterator start, std::ostream &os, uint32_t packetUid, - uint32_t size) + uint32_t size) const { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); - for (PrinterList::iterator i = m_printerList.begin (); i != m_printerList.end (); i++) + for (PrinterList::const_iterator i = m_printerList.begin (); i != m_printerList.end (); i++) { if (i->m_chunkUid == chunkUid) { @@ -103,7 +103,7 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid, uint32_t packetUid, uint32_t size, uint32_t fragmentStart, - uint32_t fragmentEnd) + uint32_t fragmentEnd) const { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); DoGetNameCallback cb = (*registeredChunks)[chunkUid].second; @@ -111,7 +111,7 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid, struct PacketPrinter::FragmentInformation info; info.start = fragmentStart; info.end = fragmentEnd; - for (PrinterList::iterator i = m_printerList.begin (); i != m_printerList.end (); i++) + for (PrinterList::const_iterator i = m_printerList.begin (); i != m_printerList.end (); i++) { if (i->m_chunkUid == chunkUid) { @@ -123,7 +123,7 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid, } void PacketPrinter::PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size, - uint32_t fragmentStart, uint32_t fragmentEnd) + uint32_t fragmentStart, uint32_t fragmentEnd) const { struct PacketPrinter::FragmentInformation info; info.start = fragmentStart; diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 116607007..52fd8b38a 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -26,6 +26,10 @@ #include "buffer.h" #include +namespace { + class ItemList; +} + namespace ns3 { class Chunk; @@ -90,6 +94,7 @@ public: private: friend class PacketHistory; + friend class ItemList; struct Printer { uint32_t m_chunkUid; @@ -143,15 +148,15 @@ private: Buffer::Iterator i, std::ostream &os, uint32_t packetUid, - uint32_t size); + uint32_t size) const; void PrintChunkFragment (uint32_t uid, std::ostream &os, uint32_t packetUid, uint32_t size, uint32_t fragmentStart, - uint32_t fragmentEnd); + uint32_t fragmentEnd) const; void PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size, - uint32_t fragmentStart, uint32_t fragmentEnd); + uint32_t fragmentStart, uint32_t fragmentEnd) const; static PacketPrinter m_defaultPacketPrinter; PrinterList m_printerList; From 8eef599aa671c197f4fc6a13b674cf5363151635 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 13:44:40 +0200 Subject: [PATCH 012/116] add public Callback::GetImpl --- src/core/callback.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/callback.h b/src/core/callback.h index 526c022a3..64e92ccd8 100644 --- a/src/core/callback.h +++ b/src/core/callback.h @@ -226,6 +226,7 @@ class CallbackBase { public: virtual ~CallbackBase () {} virtual CallbackImplBase *PeekImpl (void) const = 0; + virtual Ptr GetImpl (void) const = 0; }; /** @@ -341,6 +342,9 @@ public: } *this = Callback (impl); } + virtual PtrGetImpl (void) const { + return m_impl; + } private: virtual CallbackImpl *PeekImpl (void) const { return PeekPointer (m_impl); From 2e686bcca75a45200830a5ca85a3c4876a94c076 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 13:45:03 +0200 Subject: [PATCH 013/116] use Callback::GetImpl rather than Callback::PeekImpl --- src/common/packet-printer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 52fd8b38a..f40efa056 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -182,7 +182,7 @@ PacketPrinter::AddPrinter (Callback (); struct PacketPrinter::Printer p; p.m_chunkUid = uid; - p.m_printer = printer.PeekImpl (); + p.m_printer = printer.GetImpl (); p.m_fragmentPrinter = fragmentPrinter; m_printerList.push_back (p); } From 4736067ed22e19da2373f18574e62add3ce8f382 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 13:52:29 +0200 Subject: [PATCH 014/116] avoid recursive initialization of uid static variable --- src/common/packet-printer.cc | 17 +++++++++++++++++ src/common/packet-printer.h | 22 ++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 0c0eaeadc..bf8224db2 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -166,5 +166,22 @@ PacketPrinter::DoDefaultPrintFragment (std::ostream & os, os << std::endl; } +void +PacketPrinter::DoAddPrinter (uint32_t uid, + Ptr printer, + Callback fragmentPrinter) +{ + struct PacketPrinter::Printer p; + p.m_chunkUid = uid; + p.m_printer = printer; + p.m_fragmentPrinter = fragmentPrinter; + m_printerList.push_back (p); +} + } // namespace ns3 diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index f40efa056..2a0c36d3f 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -157,6 +157,14 @@ private: uint32_t fragmentEnd) const; void PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size, uint32_t fragmentStart, uint32_t fragmentEnd) const; + void DoAddPrinter (uint32_t uid, + Ptr printer, + Callback fragmentPrinter); static PacketPrinter m_defaultPacketPrinter; PrinterList m_printerList; @@ -180,11 +188,7 @@ PacketPrinter::AddPrinter (Callback fragmentPrinter) { static uint32_t uid = PacketPrinter::GetUid (); - struct PacketPrinter::Printer p; - p.m_chunkUid = uid; - p.m_printer = printer.GetImpl (); - p.m_fragmentPrinter = fragmentPrinter; - m_printerList.push_back (p); + DoAddPrinter (uid, printer.GetImpl (), fragmentPrinter); } template @@ -225,9 +229,11 @@ PacketPrinter::AllocateUid (void) RegisteredChunks *chunks = PacketPrinter::GetRegisteredChunks (); chunks->push_back (std::make_pair(&PacketPrinter::DoPrint, &PacketPrinter::DoGetName)); - PacketPrinter::PeekDefault ()->AddPrinter (MakeCallback (&PacketPrinter::DoDefaultPrint), - MakeCallback (&PacketPrinter::DoDefaultPrintFragment)); - return chunks->size (); + uint32_t uid = chunks->size (); + PacketPrinter::PeekDefault ()->DoAddPrinter (uid, + MakeCallback (&PacketPrinter::DoDefaultPrint).GetImpl (), + MakeCallback (&PacketPrinter::DoDefaultPrintFragment)); + return uid; } template From af44bde349e388a76e23efc0cc55422f0d57f825 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 14:00:03 +0200 Subject: [PATCH 015/116] fix off-by-one in uid allocation --- src/common/packet-printer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 2a0c36d3f..c4ee8b336 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -229,7 +229,7 @@ PacketPrinter::AllocateUid (void) RegisteredChunks *chunks = PacketPrinter::GetRegisteredChunks (); chunks->push_back (std::make_pair(&PacketPrinter::DoPrint, &PacketPrinter::DoGetName)); - uint32_t uid = chunks->size (); + uint32_t uid = chunks->size () - 1; PacketPrinter::PeekDefault ()->DoAddPrinter (uid, MakeCallback (&PacketPrinter::DoDefaultPrint).GetImpl (), MakeCallback (&PacketPrinter::DoDefaultPrintFragment)); From 3861a96d5ab74132fefc0ada9597ee00a498a668 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 14:30:07 +0200 Subject: [PATCH 016/116] implement forgotten PacketPrinter::AddDefaultPrinter --- src/common/packet-printer.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index bf8224db2..64ced28cd 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -38,14 +38,15 @@ PacketPrinter::PrintBackward (void) m_forward = false; } void -PacketPrinter::AddPayloadPrinter (Callback printer) +PacketPrinter::AddPayloadPrinter (PayloadPrinter printer) { m_payloadPrinter = printer; } +void +PacketPrinter::AddDefaultPrinter (DefaultPrinter printer) +{ + m_defaultPrinter = printer; +} PacketPrinter::RegisteredChunks * PacketPrinter::GetRegisteredChunks (void) From 20581afe80a0fddb1a9397871ba0b4d60059c57a Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 14:30:34 +0200 Subject: [PATCH 017/116] re-implement PacketHistory to use the PacketPrinter and work on ItemList::Print --- SConstruct | 2 + src/common/packet-history.cc | 322 ++++++++++++++++++++++++----------- src/common/packet-history.h | 56 +----- src/common/packet.cc | 7 + src/common/packet.h | 3 + 5 files changed, 242 insertions(+), 148 deletions(-) diff --git a/SConstruct b/SConstruct index a96adb851..e882b64b1 100644 --- a/SConstruct +++ b/SConstruct @@ -188,6 +188,7 @@ common.add_sources([ 'chunk.cc', 'header.cc', 'trailer.cc', + 'packet-printer.cc', 'packet-history.cc', 'packet.cc', 'tags.cc', @@ -210,6 +211,7 @@ common.add_inst_headers([ 'trailer.h', 'tags.h', 'packet.h', + 'packet-printer.h', 'packet-history.h', 'uv-trace-source.h', 'sv-trace-source.h', diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 4a0e65e88..f691009af 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -31,7 +31,7 @@ namespace { class ItemList { public: - void InitPayload (uint32_t uid, uint32_t size); + void InitPayload (uint32_t packetUid, uint32_t size); void AddHeader (uint32_t type, uint32_t size); void AddTrailer (uint32_t type, uint32_t size); @@ -43,12 +43,13 @@ public: void AddAtEnd (ItemList const *other); - void Print (std::ostream &os, ns3::Buffer buffer) const; + void Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter &printer) const; private: enum Type { PAYLOAD, - CHUNK, + HEADER, + TRAILER, }; struct Item { @@ -57,13 +58,13 @@ private: uint32_t m_chunkType; uint32_t m_fragmentStart; uint32_t m_fragmentEnd; - uint32_t m_uid; + uint32_t m_packetUid; }; std::list m_itemList; }; void -ItemList::InitPayload (uint32_t uid, uint32_t size) +ItemList::InitPayload (uint32_t packetUid, uint32_t size) { NS_ASSERT (m_itemList.empty ()); struct Item item; @@ -72,7 +73,7 @@ ItemList::InitPayload (uint32_t uid, uint32_t size) item.m_size = size; item.m_fragmentStart = 0; item.m_fragmentEnd = item.m_size; - item.m_uid = uid; + item.m_packetUid = packetUid; m_itemList.push_back (item); } @@ -80,12 +81,12 @@ void ItemList::AddHeader (uint32_t type, uint32_t size) { struct Item item; - item.m_type = ItemList::CHUNK; + item.m_type = ItemList::HEADER; item.m_chunkType = type; item.m_size = size; item.m_fragmentStart = 0; item.m_fragmentEnd = size; - item.m_uid = m_itemList.front ().m_uid; + item.m_packetUid = m_itemList.front ().m_packetUid; m_itemList.push_front (item); } @@ -93,12 +94,12 @@ void ItemList::AddTrailer (uint32_t type, uint32_t size) { struct Item item; - item.m_type = ItemList::CHUNK; + item.m_type = ItemList::TRAILER; item.m_chunkType = type; item.m_size = size; item.m_fragmentStart = 0; item.m_fragmentEnd = size; - item.m_uid = m_itemList.back ().m_uid; + item.m_packetUid = m_itemList.back ().m_packetUid; m_itemList.push_back (item); } @@ -106,7 +107,7 @@ void ItemList::RemHeader (uint32_t type, uint32_t size) { struct Item item = m_itemList.front (); - if (item.m_type != CHUNK || + if (item.m_type != ItemList::HEADER || item.m_size != size || item.m_chunkType != type) { @@ -123,7 +124,7 @@ void ItemList::RemTrailer (uint32_t type, uint32_t size) { struct Item item = m_itemList.back (); - if (item.m_type != CHUNK || + if (item.m_type != ItemList::TRAILER || item.m_size != size || item.m_chunkType != type) { @@ -193,7 +194,7 @@ ItemList::AddAtEnd (ItemList const *other) { const ItemList::Item &item = *i; ItemList::Item &last = m_itemList.back (); - if (item.m_uid == last.m_uid && + if (item.m_packetUid == last.m_packetUid && item.m_type == last.m_type && item.m_chunkType == last.m_chunkType && item.m_size == last.m_size && @@ -210,15 +211,43 @@ ItemList::AddAtEnd (ItemList const *other) } void -ItemList::Print (std::ostream &os, ns3::Buffer buffer) const -{} +ItemList::Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter &printer) const +{ + NS_ASSERT (!m_itemList.empty ()); + for (std::list::const_iterator i = m_itemList.begin (); + i != m_itemList.end (); i++) + { + ItemList::Item item = *i; + if (item.m_type == ItemList::PAYLOAD) + { + printer.PrintPayload (os, item.m_packetUid, item.m_size, item.m_fragmentStart, item.m_fragmentEnd); + } + else if (item.m_fragmentStart != 0 || + item.m_fragmentEnd != item.m_size) + { + printer.PrintChunkFragment (item.m_chunkType, os, item.m_packetUid, item.m_size, + item.m_fragmentStart, item.m_fragmentEnd); + } + else if (item.m_type == ItemList::HEADER) + { + ns3::Buffer::Iterator j = buffer.Begin (); + j.Next (0); //XXX + printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size); + } + else if (item.m_type == ItemList::TRAILER) + { + ns3::Buffer::Iterator j = buffer.End (); + j.Prev (0); //XXX + printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size); + } + } +} } // anonymous namespace namespace ns3 { bool PacketHistory::m_enable = false; -PacketHistory::ChunkFactories PacketHistory::m_factories; uint32_t PacketHistory::m_maxSize = 0; PacketHistory::DataFreeList PacketHistory::m_freeList; @@ -662,7 +691,7 @@ PacketHistory::RemoveAtEnd (uint32_t end) } void -PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const +PacketHistory::PrintSimple (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const { Buffer original = buffer; HeadersToPrint headersToPrint; @@ -794,34 +823,30 @@ PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const { uint32_t uid = j->first; uint32_t offset = j->second; - Buffer tmp = original; - tmp.RemoveAtStart (offset); - Chunk *chunk = CreateStatic (uid); - chunk->Deserialize (tmp.Begin ()); - chunk->Print (os); + Buffer::Iterator tmp = original.Begin (); + tmp.Next (offset); + printer.PrintChunk (uid, tmp, os, 0, 0); } for (TrailersToPrint::reverse_iterator j = trailersToPrint.rbegin (); j != trailersToPrint.rend (); j++) { uint32_t uid = j->first; uint32_t offset = j->second; - Buffer tmp = original; - tmp.RemoveAtEnd (offset); - Chunk *chunk = CreateStatic (uid); - chunk->Deserialize (tmp.End ()); - chunk->Print (os); + Buffer::Iterator tmp = original.End (); + tmp.Prev (offset); + printer.PrintChunk (uid, tmp, os, 0, 0); } } void -PacketHistory::PrintComplex (std::ostream &os, Buffer buffer) const +PacketHistory::PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const { // we need to build a linked list of the different fragments // which are stored in this packet. uint8_t *dataBuffer = &m_data->m_data[0]; ItemList itemList; BuildItemList (&itemList, dataBuffer, m_end); - itemList.Print (os, buffer); + itemList.Print (os, buffer, printer); } void @@ -877,6 +902,12 @@ PacketHistory::BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) co void PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const +{ + Print (os, buffer, PacketPrinter::GetDefault ()); +} + +void +PacketHistory::Print (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const { if (!m_enable) { @@ -885,41 +916,15 @@ PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const if (m_aggregated) { - PrintComplex (os, buffer); + PrintComplex (os, buffer, printer); } else { - PrintSimple (os, buffer); + PrintSimple (os, buffer, printer); } } -Chunk * -PacketHistory::CreateStatic (uint32_t uid) -{ - for (ChunkFactoriesI i = m_factories.begin (); i != m_factories.end (); i++) - { - if (i->first == uid) - { - return (*i->second) (); - } - } - NS_ASSERT_MSG (false, "cannot be reached"); - /* quiet compiler */ - return 0; -} -uint32_t -PacketHistory::RegisterChunkFactory (Chunk *(*createStatic) (void)) -{ - static uint32_t uid = 0; - uid++; - for (ChunkFactoriesI i = m_factories.begin (); i != m_factories.end (); i++) - { - NS_ASSERT (i->first != uid); - } - m_factories.push_back (std::make_pair (uid, createStatic)); - return uid; -} }; // namespace ns3 @@ -933,45 +938,33 @@ PacketHistory::RegisterChunkFactory (Chunk *(*createStatic) (void)) namespace ns3 { -static std::list g_prints; -static bool g_headerError; -static bool g_trailerError; - -static void -RecordPrint (int n) -{ - g_prints.push_back (n); -} - -static void -RecordTrailerError (int n) -{ - g_trailerError = true; -} - -static void -RecordHeaderError (int n) -{ - g_headerError = true; -} - -static void -CleanupPrints (void) -{ - g_prints.erase (g_prints.begin (), g_prints.end ()); -} - template class HistoryHeader : public Header { +public: + HistoryHeader (); + bool IsOk (void) const; private: virtual std::string DoGetName (void) const; virtual void PrintTo (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; virtual void SerializeTo (Buffer::Iterator start) const; virtual uint32_t DeserializeFrom (Buffer::Iterator start); + bool m_ok; }; +template +HistoryHeader::HistoryHeader () + : m_ok (false) +{} + +template +bool +HistoryHeader::IsOk (void) const +{ + return m_ok; +} + template std::string HistoryHeader::DoGetName (void) const @@ -985,7 +978,7 @@ template void HistoryHeader::PrintTo (std::ostream &os) const { - RecordPrint (N); + NS_ASSERT (false); } template uint32_t @@ -1003,11 +996,12 @@ template uint32_t HistoryHeader::DeserializeFrom (Buffer::Iterator start) { + m_ok = true; for (int i = 0; i < N; i++) { if (start.ReadU8 () != N) { - RecordHeaderError (N); + m_ok = false; } } return N; @@ -1016,14 +1010,30 @@ HistoryHeader::DeserializeFrom (Buffer::Iterator start) template class HistoryTrailer : public Trailer { +public: + HistoryTrailer (); + bool IsOk (void) const; private: virtual std::string DoGetName (void) const; virtual void PrintTo (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; virtual void SerializeTo (Buffer::Iterator start) const; virtual uint32_t DeserializeFrom (Buffer::Iterator start); + bool m_ok; }; +template +HistoryTrailer::HistoryTrailer () + : m_ok (false) +{} + +template +bool +HistoryTrailer::IsOk (void) const +{ + return m_ok; +} + template std::string HistoryTrailer::DoGetName (void) const @@ -1036,7 +1046,7 @@ template void HistoryTrailer::PrintTo (std::ostream &os) const { - RecordPrint (N); + NS_ASSERT (false); } template uint32_t @@ -1054,12 +1064,13 @@ template uint32_t HistoryTrailer::DeserializeFrom (Buffer::Iterator start) { + m_ok = true; start.Prev (N); for (int i = 0; i < N; i++) { if (start.ReadU8 () != N) { - RecordTrailerError (N); + m_ok = false; } } return N; @@ -1073,41 +1084,148 @@ public: virtual ~PacketHistoryTest (); bool CheckHistory (Packet p, char *file, int line, uint32_t n, ...); virtual bool RunTests (void); +private: + template + void PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryHeader *header); + template + void PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryTrailer *trailer); + void PrintFragment (std::ostream &os,uint32_t packetUid, + uint32_t size,std::string & name, + struct PacketPrinter::FragmentInformation info); + void PrintDefault (std::ostream& os,uint32_t packetUid, + uint32_t size,std::string& name, + struct PacketPrinter::FragmentInformation info); + void PrintPayload (std::ostream &os,uint32_t packetUid, + uint32_t size, + struct PacketPrinter::FragmentInformation info); + template + void RegisterHeader (void); + template + void RegisterTrailer (void); + void CleanupPrints (void); + + + bool m_headerError; + bool m_trailerError; + std::list m_prints; + PacketPrinter m_printer; }; PacketHistoryTest::PacketHistoryTest () : Test ("PacketHistory") -{} +{ + m_printer.AddPayloadPrinter (MakeCallback (&PacketHistoryTest::PrintPayload, this)); + m_printer.AddDefaultPrinter (MakeCallback (&PacketHistoryTest::PrintDefault, this)); +} PacketHistoryTest::~PacketHistoryTest () {} +template +void +PacketHistoryTest::RegisterHeader (void) +{ + static bool registered = false; + if (!registered) + { + m_printer.AddPrinter (MakeCallback (&PacketHistoryTest::PrintHeader, this), + MakeCallback (&PacketHistoryTest::PrintFragment, this)); + registered = true; + } +} + +template +void +PacketHistoryTest::RegisterTrailer (void) +{ + static bool registered = false; + if (!registered) + { + m_printer.AddPrinter (MakeCallback (&PacketHistoryTest::PrintTrailer, this), + MakeCallback (&PacketHistoryTest::PrintFragment, this)); + registered = true; + } +} + + +template +void +PacketHistoryTest::PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, + const HistoryHeader *header) +{ + if (!header->IsOk ()) + { + m_headerError = true; + } + m_prints.push_back (N); +} + +template +void +PacketHistoryTest::PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, + const HistoryTrailer *trailer) +{ + if (!trailer->IsOk ()) + { + m_trailerError = true; + } + m_prints.push_back (N); +} +void +PacketHistoryTest::PrintFragment (std::ostream &os,uint32_t packetUid, + uint32_t size,std::string & name, + struct PacketPrinter::FragmentInformation info) +{ + NS_ASSERT (false); +} +void +PacketHistoryTest::PrintDefault (std::ostream& os,uint32_t packetUid, + uint32_t size,std::string& name, + struct PacketPrinter::FragmentInformation info) +{ + NS_ASSERT (false); +} +void +PacketHistoryTest::PrintPayload (std::ostream &os,uint32_t packetUid, + uint32_t size, + struct PacketPrinter::FragmentInformation info) +{ + NS_ASSERT (false); +} + + +void +PacketHistoryTest::CleanupPrints (void) +{ + m_prints.clear (); +} + bool PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ...) { - g_headerError = false; - g_trailerError = false; + m_headerError = false; + m_trailerError = false; va_list ap; - p.Print (std::cerr); + p.Print (std::cerr, m_printer); va_start (ap, n); - if (g_headerError) + if (m_headerError) { std::cout << "PacketHistory header error. file=" << file << ", line=" << line << std::endl; return false; } - if (g_trailerError) + if (m_trailerError) { std::cout << "PacketHistory trailer error. file=" << file << ", line=" << line << std::endl; return false; } - if (n != g_prints.size ()) + if (n != m_prints.size ()) { goto error; } - for (std::list::iterator i = g_prints.begin (); - i != g_prints.end (); i++) + for (std::list::iterator i = m_prints.begin (); + i != m_prints.end (); i++) { int v = va_arg (ap, int); if (v != *i) @@ -1121,8 +1239,8 @@ PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ... error: std::cout << "PacketHistory error. file="<< file << ", line=" << line << ", got:\""; - for (std::list::iterator i = g_prints.begin (); - i != g_prints.end (); i++) + for (std::list::iterator i = m_prints.begin (); + i != m_prints.end (); i++) { std::cout << *i << ", "; } @@ -1141,21 +1259,25 @@ PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ... #define ADD_HEADER(p, n) \ { \ HistoryHeader header; \ + RegisterHeader (); \ p.AddHeader (header); \ } #define ADD_TRAILER(p, n) \ { \ HistoryTrailer trailer; \ + RegisterTrailer (); \ p.AddTrailer (trailer); \ } #define REM_HEADER(p, n) \ { \ HistoryHeader header; \ + RegisterHeader (); \ p.RemoveHeader (header); \ } #define REM_TRAILER(p, n) \ { \ HistoryTrailer trailer; \ + RegisterTrailer (); \ p.RemoveTrailer (trailer); \ } #define CHECK_HISTORY(p, ...) \ diff --git a/src/common/packet-history.h b/src/common/packet-history.h index e072a6a6d..cc76ef677 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -24,6 +24,7 @@ #include #include #include "ns3/callback.h" +#include "packet-printer.h" namespace { class ItemList; @@ -34,19 +35,6 @@ namespace ns3 { class Chunk; class Buffer; -class PacketPrinter -{ -public: - void PrintForward (void); - void PrintBackward (void); - template - void Add (Callback cb); - -private: - std::vector > m_printers; - bool m_forward; -}; - class PacketHistory { public: static void Enable (void); @@ -73,7 +61,7 @@ public: void RemoveAtEnd (uint32_t end); void PrintDefault (std::ostream &os, Buffer buffer) const; - void Print (std::ostream &os, Buffer buffer, PacketPrinter printer) const; + void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const; private: enum CommandType { @@ -97,14 +85,6 @@ private: }; typedef std::vector > HeadersToPrint; typedef std::vector > TrailersToPrint; - template - class ChunkUid { - public: - static const uint32_t GetUid (void); - static Chunk *CreateStatic (void); - }; - typedef std::vector > ChunkFactories; - typedef std::vector >::iterator ChunkFactoriesI; typedef std::vector DataFreeList; PacketHistory (); @@ -123,19 +103,16 @@ private: void RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size); void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); - void PrintSimple (std::ostream &os, Buffer buffer) const; - void PrintComplex (std::ostream &os, Buffer buffer) const; + void PrintSimple (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const; + void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const; void BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) const; static struct PacketHistory::CommandData *Create (uint32_t size); static void Recycle (struct CommandData *data); static struct PacketHistory::CommandData *Allocate (uint32_t n); static void Deallocate (struct CommandData *data); - static Chunk *CreateStatic (uint32_t uid); - static uint32_t RegisterChunkFactory (Chunk *(*createStatic) (void)); static DataFreeList m_freeList; - static ChunkFactories m_factories; static bool m_enable; static uint32_t m_maxSize; @@ -149,47 +126,30 @@ private: namespace ns3 { -template -const uint32_t -PacketHistory::ChunkUid::GetUid (void) -{ - static uint32_t uid = - PacketHistory::RegisterChunkFactory (&PacketHistory::ChunkUid::CreateStatic); - return uid; -} -template -Chunk * -PacketHistory::ChunkUid::CreateStatic (void) -{ - static T chunk = T (); - return &chunk; -} - - template void PacketHistory::AddHeader (T const &header, uint32_t size) { - AddHeader (ChunkUid::GetUid (), header, size); + AddHeader (PacketPrinter::GetUid (), header, size); } template void PacketHistory::RemoveHeader (T const &header, uint32_t size) { - RemoveHeader (ChunkUid::GetUid (), header, size); + RemoveHeader (PacketPrinter::GetUid (), header, size); } template void PacketHistory::AddTrailer (T const &trailer, uint32_t size) { - AddTrailer (ChunkUid::GetUid (), trailer, size); + AddTrailer (PacketPrinter::GetUid (), trailer, size); } template void PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) { - RemoveTrailer (ChunkUid::GetUid (), trailer, size); + RemoveTrailer (PacketPrinter::GetUid (), trailer, size); } }; // namespace ns3 diff --git a/src/common/packet.cc b/src/common/packet.cc index 9b36f3f66..a2d4fc80c 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -19,6 +19,7 @@ * Author: Mathieu Lacage */ #include "packet.h" +#include "packet-printer.h" #include "ns3/assert.h" namespace ns3 { @@ -130,4 +131,10 @@ Packet::Print (std::ostream &os) const m_history.PrintDefault (os, m_buffer); } +void +Packet::Print (std::ostream &os, const PacketPrinter &printer) const +{ + m_history.Print (os, m_buffer, printer); +} + }; // namespace ns3 diff --git a/src/common/packet.h b/src/common/packet.h index 2d7cda917..98caf46a5 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -32,6 +32,8 @@ namespace ns3 { +class PacketPrinter; + /** * \brief network packets * @@ -254,6 +256,7 @@ public: uint32_t GetUid (void) const; void Print (std::ostream &os) const; + void Print (std::ostream &os, const PacketPrinter &printer) const; private: Packet (Buffer buffer, Tags tags, PacketHistory history, uint32_t uid); Buffer m_buffer; From 581b34b58604bd9a95d8b92b964fc4fc7bb6d178 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 31 May 2007 14:52:15 +0200 Subject: [PATCH 018/116] force use of the ItemList to test it --- src/common/packet-history.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index f691009af..185fbb1dc 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -214,6 +214,15 @@ void ItemList::Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter &printer) const { NS_ASSERT (!m_itemList.empty ()); + uint32_t totalSize = 0; + for (std::list::const_iterator i = m_itemList.begin (); + i != m_itemList.end (); i++) + { + ItemList::Item item = *i; + totalSize += item.m_fragmentEnd - item.m_fragmentStart; + } + NS_ASSERT (totalSize == buffer.GetSize ()); + uint32_t offset = 0; for (std::list::const_iterator i = m_itemList.begin (); i != m_itemList.end (); i++) { @@ -231,15 +240,20 @@ ItemList::Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter else if (item.m_type == ItemList::HEADER) { ns3::Buffer::Iterator j = buffer.Begin (); - j.Next (0); //XXX + j.Next (offset); printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size); } else if (item.m_type == ItemList::TRAILER) { ns3::Buffer::Iterator j = buffer.End (); - j.Prev (0); //XXX + j.Prev (totalSize - offset + item.m_size); printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size); } + else + { + NS_ASSERT (false); + } + offset += item.m_fragmentEnd - item.m_fragmentStart; } } @@ -914,7 +928,7 @@ PacketHistory::Print (std::ostream &os, Buffer buffer, const PacketPrinter &prin return; } - if (m_aggregated) + if (true) { PrintComplex (os, buffer, printer); } From 9980528f1e30ef5cde1c70c3251c23451e2d1984 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 09:55:47 +0200 Subject: [PATCH 019/116] make chunkUid zero and invalid uid to improve debugging --- src/common/packet-printer.cc | 8 +++++--- src/common/packet-printer.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 64ced28cd..5fc7140ed 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -82,16 +82,17 @@ PacketPrinter::PrintChunk (uint32_t chunkUid, uint32_t size) const { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); + NS_ASSERT (chunkUid > 1); for (PrinterList::const_iterator i = m_printerList.begin (); i != m_printerList.end (); i++) { if (i->m_chunkUid == chunkUid) { - DoPrintCallback cb = (*registeredChunks)[chunkUid].first; + DoPrintCallback cb = (*registeredChunks)[chunkUid-1].first; cb (i->m_printer, start, os, packetUid, size); return; } } - DoGetNameCallback cb = (*registeredChunks)[chunkUid].second; + DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].second; std::string name = cb (); struct PacketPrinter::FragmentInformation info; info.start = 0; @@ -107,7 +108,8 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid, uint32_t fragmentEnd) const { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); - DoGetNameCallback cb = (*registeredChunks)[chunkUid].second; + NS_ASSERT (chunkUid > 1); + DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].second; std::string name = cb (); struct PacketPrinter::FragmentInformation info; info.start = fragmentStart; diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index c4ee8b336..2a0c36d3f 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -229,7 +229,7 @@ PacketPrinter::AllocateUid (void) RegisteredChunks *chunks = PacketPrinter::GetRegisteredChunks (); chunks->push_back (std::make_pair(&PacketPrinter::DoPrint, &PacketPrinter::DoGetName)); - uint32_t uid = chunks->size () - 1; + uint32_t uid = chunks->size (); PacketPrinter::PeekDefault ()->DoAddPrinter (uid, MakeCallback (&PacketPrinter::DoDefaultPrint).GetImpl (), MakeCallback (&PacketPrinter::DoDefaultPrintFragment)); From 8cf216212145b7e30a32a4c950501809798a187a Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 10:06:35 +0200 Subject: [PATCH 020/116] remove PrintSimple and revert order of history data written in data buffer --- src/common/packet-history.cc | 203 +++-------------------------------- src/common/packet-history.h | 5 +- 2 files changed, 18 insertions(+), 190 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 185fbb1dc..56421ddb7 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -294,8 +294,8 @@ PacketHistory::Construct (uint32_t uid, uint32_t size) if (m_enable) { m_data = PacketHistory::Create (size); - AppendOneCommand (PacketHistory::INIT_UID, - uid); + AppendOneCommand (PacketHistory::INIT, + size, uid); } } PacketHistory::PacketHistory (PacketHistory const &o) @@ -419,22 +419,22 @@ PacketHistory::AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1) if (m_data->m_count == 1 || m_data->m_dirtyEnd == m_end) { - AppendValue (data1); - AppendValue (data0); AppendValue (type); + AppendValue (data0); + AppendValue (data1); m_n++; return; } else { uint8_t *buffer = &(m_data->m_data[m_end]); - uint32_t lastType = ReadReverseValue (&buffer); + uint32_t lastType = ReadForwardValue (&buffer); if (lastType == type) { - uint32_t lastData = ReadReverseValue (&buffer); + uint32_t lastData = ReadForwardValue (&buffer); if (lastData == data0) { - lastData = ReadReverseValue (&buffer); + lastData = ReadForwardValue (&buffer); if (lastData == data1) { return; @@ -444,9 +444,9 @@ PacketHistory::AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1) } } Reserve (n); - AppendValue (data1); - AppendValue (data0); AppendValue (type); + AppendValue (data0); + AppendValue (data1); m_n++; } @@ -462,18 +462,18 @@ PacketHistory::AppendOneCommand (uint32_t type, uint32_t data) if (m_data->m_count == 1 || m_data->m_dirtyEnd == m_end) { - AppendValue (data); AppendValue (type); + AppendValue (data); m_n++; return; } else { uint8_t *buffer = &(m_data->m_data[m_end]); - uint32_t lastType = ReadReverseValue (&buffer); + uint32_t lastType = ReadForwardValue (&buffer); if (lastType == type) { - uint32_t lastData = ReadReverseValue (&buffer); + uint32_t lastData = ReadForwardValue (&buffer); if (lastData == data) { return; @@ -482,8 +482,8 @@ PacketHistory::AppendOneCommand (uint32_t type, uint32_t data) } } Reserve (n); - AppendValue (data); AppendValue (type); + AppendValue (data); m_n++; } void @@ -597,19 +597,6 @@ PacketHistory::ReadValue (uint8_t *buffer, uint32_t *n) const return result; } -uint32_t -PacketHistory::ReadReverseValue (uint8_t **pBuffer) const -{ - uint32_t n = GetReverseUleb128Size (*pBuffer); - NS_ASSERT (n > 0); - uint8_t *buffer = *pBuffer - n + 1; - uint32_t read = 0; - uint32_t result = ReadValue (buffer, &read); - NS_ASSERT (read == n); - *pBuffer = *pBuffer - n; - return result; -} - uint32_t PacketHistory::ReadForwardValue (uint8_t **pBuffer) const { @@ -704,154 +691,6 @@ PacketHistory::RemoveAtEnd (uint32_t end) } } -void -PacketHistory::PrintSimple (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const -{ - Buffer original = buffer; - HeadersToPrint headersToPrint; - TrailersToPrint trailersToPrint; - uint8_t *dataBuffer = &m_data->m_data[m_end] - 1; - int32_t start = 0; - int32_t end = buffer.GetSize (); - int32_t curStart = start; - int32_t curEnd = end; - for (uint32_t i = 0; i < m_n; i++) - { - uint32_t type = ReadReverseValue (&dataBuffer); - uint32_t data = ReadReverseValue (&dataBuffer); - switch (type) - { - case PacketHistory::INIT_UID: - break; - case PacketHistory::INIT_SIZE: - std::cout << "init size=" << data << std::endl; - break; - case PacketHistory::ADD_HEADER: { - int32_t size = ReadReverseValue (&dataBuffer); - if (curStart == start) - { - if (start + size < end) - { - headersToPrint.push_back (std::make_pair (data, curStart)); - } - curStart += size; - start += size; - } - else if (curStart + size <= start) - { - // header lies entirely outside of data area. - curStart += size; - } - else if (curStart < start) - { - // header lies partly inside and outside of data area - // potentially, because we fragmented the packet in the middle - // of this header. - curStart += size; - } - else - { - // header lies entirely inside data area but there is some - // data at the start of the data area which does not belong - // to this header. Potentially, because we fragmented - // the packet in the middle of a previous header. - NS_ASSERT (curStart > start); - // we print the content of the header anyway because we can. - if (start + size < end) - { - headersToPrint.push_back (std::make_pair (data, curStart)); - } - curStart += size; - start = curStart; - } - } break; - case PacketHistory::REM_HEADER: { - int32_t size = ReadReverseValue (&dataBuffer); - if (curStart <= start) - { - // header lies entirely outside of data area. - curStart -= size; - } - else - { - NS_ASSERT (false); - } - } break; - case PacketHistory::ADD_TRAILER: { - int32_t size = ReadReverseValue (&dataBuffer); - if (curEnd == end) - { - if (end - size >= start) - { - // trailer lies exactly at the end of the data area - trailersToPrint.push_back (std::make_pair (data, buffer.GetSize () - curEnd)); - } - curEnd -= size; - end -= size; - } - else if (curEnd - size >= end) - { - // trailer lies entirely outside of data area. - curEnd -= size; - } - else if (curEnd > end) - { - // header lies partly inside and partly outside of - // data area, potentially because of fragmentation. - curEnd -= size; - } - else - { - // header lies entirely inside data area - NS_ASSERT (curEnd < end); - if (end - size >= start) - { - trailersToPrint.push_back (std::make_pair (data, buffer.GetSize () - curEnd)); - } - curEnd -= size; - end = curEnd; - - } - } break; - case PacketHistory::REM_TRAILER: { - int32_t size = ReadReverseValue (&dataBuffer); - if (curEnd >= end) - { - curEnd += size; - } - else - { - NS_ASSERT (false); - } - } break; - case PacketHistory::REM_AT_START: - curStart -= data; - break; - case PacketHistory::REM_AT_END: - curEnd += data; - break; - } - } - for (HeadersToPrint::iterator j = headersToPrint.begin (); - j != headersToPrint.end (); j++) - { - uint32_t uid = j->first; - uint32_t offset = j->second; - Buffer::Iterator tmp = original.Begin (); - tmp.Next (offset); - printer.PrintChunk (uid, tmp, os, 0, 0); - } - for (TrailersToPrint::reverse_iterator j = trailersToPrint.rbegin (); - j != trailersToPrint.rend (); j++) - { - uint32_t uid = j->first; - uint32_t offset = j->second; - Buffer::Iterator tmp = original.End (); - tmp.Prev (offset); - printer.PrintChunk (uid, tmp, os, 0, 0); - } -} - void PacketHistory::PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const { @@ -876,10 +715,9 @@ PacketHistory::BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) co uint32_t data = ReadForwardValue (&dataBuffer); switch (type) { - case INIT_UID: - break; - case INIT_SIZE: { - itemList.InitPayload (0, data); + case INIT: { + uint32_t uid = ReadForwardValue (&dataBuffer); + itemList.InitPayload (uid, data); } break; case ADD_HEADER: { uint32_t size = ReadForwardValue (&dataBuffer); @@ -928,14 +766,7 @@ PacketHistory::Print (std::ostream &os, Buffer buffer, const PacketPrinter &prin return; } - if (true) - { - PrintComplex (os, buffer, printer); - } - else - { - PrintSimple (os, buffer, printer); - } + PrintComplex (os, buffer, printer); } diff --git a/src/common/packet-history.h b/src/common/packet-history.h index cc76ef677..bcd29d6ce 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -65,7 +65,7 @@ public: private: enum CommandType { - INIT_UID = 0, + INIT = 0, ADD_HEADER = 1, REM_HEADER = 2, ADD_TRAILER = 3, @@ -74,7 +74,6 @@ private: REM_AT_START = 6, REM_AT_END = 7, PADDING_AT_END = 9, - INIT_SIZE = 10, LAST }; struct CommandData { @@ -94,7 +93,6 @@ private: uint32_t GetReverseUleb128Size (uint8_t *buffer) const; void AppendValue (uint32_t value); uint32_t ReadForwardValue (uint8_t **pBuffer) const; - uint32_t ReadReverseValue (uint8_t **pBuffer) const; uint32_t ReadValue (uint8_t *buffer, uint32_t *n) const; void AppendOneCommand (uint32_t type, uint32_t data); void AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1); @@ -103,7 +101,6 @@ private: void RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size); void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); - void PrintSimple (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const; void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const; void BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) const; From 975c1dc46f6ec7e2399c5c9fe5bc0545876ee909 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 10:35:05 +0200 Subject: [PATCH 021/116] build the ItemList into the input list, not a temporary stack variable. --- src/common/packet-history.cc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 56421ddb7..c49aba0c8 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -708,7 +708,6 @@ PacketHistory::BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) co // we need to build a linked list of the different fragments // which are stored in this packet. uint8_t *dataBuffer = buffer; - ItemList itemList; for (uint32_t i = 0; i < m_n; i++) { uint32_t type = ReadForwardValue (&dataBuffer); @@ -717,34 +716,34 @@ PacketHistory::BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) co { case INIT: { uint32_t uid = ReadForwardValue (&dataBuffer); - itemList.InitPayload (uid, data); + list->InitPayload (uid, data); } break; case ADD_HEADER: { uint32_t size = ReadForwardValue (&dataBuffer); - itemList.AddHeader (data, size); + list->AddHeader (data, size); } break; case REM_HEADER: { uint32_t size = ReadForwardValue (&dataBuffer); - itemList.RemHeader (data, size); + list->RemHeader (data, size); } break; case ADD_TRAILER: { uint32_t size = ReadForwardValue (&dataBuffer); - itemList.AddTrailer (data, size); + list->AddTrailer (data, size); } break; case REM_TRAILER: { uint32_t size = ReadForwardValue (&dataBuffer); - itemList.RemTrailer (data, size); + list->RemTrailer (data, size); } break; case ADD_AT_END: { ItemList other; BuildItemList (&other, dataBuffer, data); - itemList.AddAtEnd (&other); + list->AddAtEnd (&other); } break; case REM_AT_START: { - itemList.RemAtStart (data); + list->RemAtStart (data); } break; case REM_AT_END: { - itemList.RemAtEnd (data); + list->RemAtEnd (data); } break; case PADDING_AT_END: break; From bf7acebc307b1a4a4644e6750584a8aa3b9eddb0 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 10:49:17 +0200 Subject: [PATCH 022/116] fix buggy assert --- src/common/packet-printer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 5fc7140ed..ed04c4761 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -82,7 +82,7 @@ PacketPrinter::PrintChunk (uint32_t chunkUid, uint32_t size) const { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); - NS_ASSERT (chunkUid > 1); + NS_ASSERT (chunkUid >= 1); for (PrinterList::const_iterator i = m_printerList.begin (); i != m_printerList.end (); i++) { if (i->m_chunkUid == chunkUid) @@ -108,7 +108,7 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid, uint32_t fragmentEnd) const { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); - NS_ASSERT (chunkUid > 1); + NS_ASSERT (chunkUid >= 1); DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].second; std::string name = cb (); struct PacketPrinter::FragmentInformation info; From 66bf48b6e6f607ce63a98168bed04b2ede0f853b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 11:03:56 +0200 Subject: [PATCH 023/116] make the tests pass again --- src/common/packet-history.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index c49aba0c8..28870c12d 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -145,17 +145,16 @@ ItemList::RemAtStart (uint32_t toRemove) while (!m_itemList.empty () && leftToRemove > 0) { struct Item &item = m_itemList.front (); - if (item.m_size >= leftToRemove) + if (item.m_fragmentEnd - item.m_fragmentStart <= leftToRemove) { m_itemList.pop_front (); leftToRemove -= item.m_size; } else { - item.m_size -= leftToRemove; item.m_fragmentStart += leftToRemove; leftToRemove = 0; - NS_ASSERT (item.m_size == item.m_fragmentEnd - item.m_fragmentStart && + NS_ASSERT (item.m_size >= item.m_fragmentEnd - item.m_fragmentStart && item.m_fragmentStart <= item.m_fragmentEnd); } } @@ -168,18 +167,17 @@ ItemList::RemAtEnd (uint32_t toRemove) while (!m_itemList.empty () && leftToRemove > 0) { struct Item &item = m_itemList.back (); - if (item.m_size >= leftToRemove) + if (item.m_fragmentEnd - item.m_fragmentStart <= leftToRemove) { m_itemList.pop_back (); leftToRemove -= item.m_size; } else { - item.m_size -= leftToRemove; item.m_fragmentEnd -= leftToRemove; leftToRemove = 0; } - NS_ASSERT (item.m_size == item.m_fragmentEnd - item.m_fragmentStart && + NS_ASSERT (item.m_size >= item.m_fragmentEnd - item.m_fragmentStart && item.m_fragmentStart <= item.m_fragmentEnd && item.m_fragmentEnd <= item.m_size); } @@ -246,7 +244,7 @@ ItemList::Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter else if (item.m_type == ItemList::TRAILER) { ns3::Buffer::Iterator j = buffer.End (); - j.Prev (totalSize - offset + item.m_size); + j.Prev (totalSize - (offset + item.m_size)); printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size); } else @@ -1020,7 +1018,7 @@ PacketHistoryTest::PrintFragment (std::ostream &os,uint32_t packetUid, uint32_t size,std::string & name, struct PacketPrinter::FragmentInformation info) { - NS_ASSERT (false); + //NS_ASSERT (false); } void PacketHistoryTest::PrintDefault (std::ostream& os,uint32_t packetUid, @@ -1034,7 +1032,7 @@ PacketHistoryTest::PrintPayload (std::ostream &os,uint32_t packetUid, uint32_t size, struct PacketPrinter::FragmentInformation info) { - NS_ASSERT (false); + //NS_ASSERT (false); } From 5a1ffabd0345bd4f897c70e1d6c0b4891ada62c7 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 11:12:55 +0200 Subject: [PATCH 024/116] test fragments --- src/common/packet-history.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 28870c12d..3b92ef0bc 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1018,7 +1018,7 @@ PacketHistoryTest::PrintFragment (std::ostream &os,uint32_t packetUid, uint32_t size,std::string & name, struct PacketPrinter::FragmentInformation info) { - //NS_ASSERT (false); + m_prints.push_back (info.end - info.start); } void PacketHistoryTest::PrintDefault (std::ostream& os,uint32_t packetUid, @@ -1032,7 +1032,7 @@ PacketHistoryTest::PrintPayload (std::ostream &os,uint32_t packetUid, uint32_t size, struct PacketPrinter::FragmentInformation info) { - //NS_ASSERT (false); + //m_prints.push_back (info.end - info.start); } @@ -1251,7 +1251,7 @@ PacketHistoryTest::RunTests (void) ADD_TRAILER (p, 9); p.RemoveAtStart (5); p.RemoveAtEnd (12); - CHECK_HISTORY (p, 2, 10, 6); + CHECK_HISTORY (p, 4, 3, 10, 6, 4); return ok; From abfdb4befc0224a447894acc2239142c801160e9 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 11:17:59 +0200 Subject: [PATCH 025/116] test payload --- src/common/packet-history.cc | 84 ++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 3b92ef0bc..ea96ab755 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1032,7 +1032,7 @@ PacketHistoryTest::PrintPayload (std::ostream &os,uint32_t packetUid, uint32_t size, struct PacketPrinter::FragmentInformation info) { - //m_prints.push_back (info.end - info.start); + m_prints.push_back (info.end - info.start); } @@ -1144,28 +1144,28 @@ PacketHistoryTest::RunTests (void) p = Packet (10); ADD_TRAILER (p, 100); - CHECK_HISTORY (p, 1, 100); + CHECK_HISTORY (p, 2, 10, 100); p = Packet (10); ADD_HEADER (p, 1); ADD_HEADER (p, 2); ADD_HEADER (p, 3); - CHECK_HISTORY (p, 3, - 3, 2, 1); - ADD_HEADER (p, 5); CHECK_HISTORY (p, 4, - 5, 3, 2, 1); - ADD_HEADER (p, 6); + 3, 2, 1, 10); + ADD_HEADER (p, 5); CHECK_HISTORY (p, 5, - 6, 5, 3, 2, 1); + 5, 3, 2, 1, 10); + ADD_HEADER (p, 6); + CHECK_HISTORY (p, 6, + 6, 5, 3, 2, 1, 10); p = Packet (10); ADD_HEADER (p, 1); ADD_HEADER (p, 2); ADD_HEADER (p, 3); REM_HEADER (p, 3); - CHECK_HISTORY (p, 2, - 2, 1); + CHECK_HISTORY (p, 3, + 2, 1, 10); p = Packet (10); ADD_HEADER (p, 1); @@ -1173,8 +1173,8 @@ PacketHistoryTest::RunTests (void) ADD_HEADER (p, 3); REM_HEADER (p, 3); REM_HEADER (p, 2); - CHECK_HISTORY (p, 1, - 1); + CHECK_HISTORY (p, 2, + 1, 10); p = Packet (10); ADD_HEADER (p, 1); @@ -1183,7 +1183,7 @@ PacketHistoryTest::RunTests (void) REM_HEADER (p, 3); REM_HEADER (p, 2); REM_HEADER (p, 1); - CHECK_HISTORY (p, 0); + CHECK_HISTORY (p, 1, 10); p = Packet (10); ADD_HEADER (p, 1); @@ -1193,47 +1193,47 @@ PacketHistoryTest::RunTests (void) REM_HEADER (p1, 3); REM_HEADER (p1, 2); REM_HEADER (p1, 1); - CHECK_HISTORY (p1, 0); - CHECK_HISTORY (p, 3, - 3, 2, 1); + CHECK_HISTORY (p1, 1, 10); + CHECK_HISTORY (p, 4, + 3, 2, 1, 10); ADD_HEADER (p1, 1); ADD_HEADER (p1, 2); - CHECK_HISTORY (p1, 2, - 2, 1); - CHECK_HISTORY (p, 3, - 3, 2, 1); + CHECK_HISTORY (p1, 3, + 2, 1, 10); + CHECK_HISTORY (p, 4, + 3, 2, 1, 10); ADD_HEADER (p, 3); - CHECK_HISTORY (p, 4, - 3, 3, 2, 1); + CHECK_HISTORY (p, 5, + 3, 3, 2, 1, 10); ADD_TRAILER (p, 4); - CHECK_HISTORY (p, 5, - 3, 3, 2, 1, 4); - ADD_TRAILER (p, 5); CHECK_HISTORY (p, 6, - 3, 3, 2, 1, 4, 5); + 3, 3, 2, 1, 10, 4); + ADD_TRAILER (p, 5); + CHECK_HISTORY (p, 7, + 3, 3, 2, 1, 10, 4, 5); REM_HEADER (p, 3); - CHECK_HISTORY (p, 5, - 3, 2, 1, 4, 5); + CHECK_HISTORY (p, 6, + 3, 2, 1, 10, 4, 5); REM_TRAILER (p, 5); - CHECK_HISTORY (p, 4, - 3, 2, 1, 4); + CHECK_HISTORY (p, 5, + 3, 2, 1, 10, 4); p1 = p; REM_TRAILER (p, 4); - CHECK_HISTORY (p, 3, - 3, 2, 1); - CHECK_HISTORY (p1, 4, - 3, 2, 1, 4); + CHECK_HISTORY (p, 4, + 3, 2, 1, 10); + CHECK_HISTORY (p1, 5, + 3, 2, 1, 10, 4); p1.RemoveAtStart (3); - CHECK_HISTORY (p1, 3, - 2, 1, 4); + CHECK_HISTORY (p1, 4, + 2, 1, 10, 4); p1.RemoveAtStart (2); - CHECK_HISTORY (p1, 2, - 1, 4); + CHECK_HISTORY (p1, 3, + 1, 10, 4); p1.RemoveAtEnd (4); - CHECK_HISTORY (p1, 1, - 1); + CHECK_HISTORY (p1, 2, + 1, 10); p1.RemoveAtStart (1); - CHECK_HISTORY (p1, 0); + CHECK_HISTORY (p1, 1, 10); p = Packet (10); ADD_HEADER (p, 8); @@ -1251,7 +1251,7 @@ PacketHistoryTest::RunTests (void) ADD_TRAILER (p, 9); p.RemoveAtStart (5); p.RemoveAtEnd (12); - CHECK_HISTORY (p, 4, 3, 10, 6, 4); + CHECK_HISTORY (p, 5, 3, 10, 10, 6, 4); return ok; From 4bfd1c4a2a533fc0c9b728cf9921ea98126da39e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 11:37:19 +0200 Subject: [PATCH 026/116] Packet API must call Trailer::DoSerialize on end of trailer, not start of trailer --- src/common/packet.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/packet.h b/src/common/packet.h index 98caf46a5..db4d8cb74 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -307,7 +307,6 @@ Packet::AddTrailer (T const &trailer) uint32_t size = trailer.GetSize (); m_buffer.AddAtEnd (size); Buffer::Iterator start = m_buffer.End (); - start.Prev (size); trailer.Serialize (start); m_history.AddTrailer (trailer, size); } From 438e58cc1c587fec4d0de64047920ac216a2d350 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 12:42:29 +0200 Subject: [PATCH 027/116] add test and fix buggy assert --- src/common/buffer.cc | 8 ++++++++ src/common/buffer.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index e725ecd2a..2c64f8920 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -655,6 +655,14 @@ BufferTest::RunTests (void) i.Prev (1); i.WriteU8 (1, 1); + buffer = Buffer (6); + buffer.AddAtStart (3); + buffer.RemoveAtEnd (8); + buffer.AddAtEnd (4); + i = buffer.End (); + i.Prev (4); + i.WriteU8 (1, 4); + return ok; } diff --git a/src/common/buffer.h b/src/common/buffer.h index 500e11f7c..4986d4998 100644 --- a/src/common/buffer.h +++ b/src/common/buffer.h @@ -522,7 +522,8 @@ Buffer::Iterator::GetIndex (uint32_t n) NS_ASSERT ( (m_current + n <= m_dataEnd) && ((m_current + n <= m_zeroStart) || - (m_current >= m_zeroEnd)) + (m_current >= m_zeroEnd) || + m_zeroStart == m_zeroEnd) ); uint32_t index; if (m_current < m_zeroStart) From 99c235760ea63af23a806e80ba54657e8d052216 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 12:46:23 +0200 Subject: [PATCH 028/116] new test and fix to make it pass --- src/common/packet-history.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index ea96ab755..d143b0eec 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -145,10 +145,11 @@ ItemList::RemAtStart (uint32_t toRemove) while (!m_itemList.empty () && leftToRemove > 0) { struct Item &item = m_itemList.front (); - if (item.m_fragmentEnd - item.m_fragmentStart <= leftToRemove) + uint32_t itemRealSize = item.m_fragmentEnd - item.m_fragmentStart; + if (itemRealSize <= leftToRemove) { m_itemList.pop_front (); - leftToRemove -= item.m_size; + leftToRemove -= itemRealSize; } else { @@ -167,10 +168,11 @@ ItemList::RemAtEnd (uint32_t toRemove) while (!m_itemList.empty () && leftToRemove > 0) { struct Item &item = m_itemList.back (); - if (item.m_fragmentEnd - item.m_fragmentStart <= leftToRemove) + uint32_t itemRealSize = item.m_fragmentEnd - item.m_fragmentStart; + if (itemRealSize <= leftToRemove) { m_itemList.pop_back (); - leftToRemove -= item.m_size; + leftToRemove -= itemRealSize; } else { @@ -900,6 +902,7 @@ template void HistoryTrailer::SerializeTo (Buffer::Iterator start) const { + start.Prev (N); start.WriteU8 (N, N); } template @@ -1242,7 +1245,6 @@ PacketHistoryTest::RunTests (void) p.RemoveAtStart (8+10+8); CHECK_HISTORY (p, 1, 8); - p = Packet (10); ADD_HEADER (p, 10); ADD_HEADER (p, 8); @@ -1253,6 +1255,17 @@ PacketHistoryTest::RunTests (void) p.RemoveAtEnd (12); CHECK_HISTORY (p, 5, 3, 10, 10, 6, 4); + p = Packet (10); + ADD_HEADER (p, 10); + ADD_TRAILER (p, 6); + p.RemoveAtEnd (18); + ADD_TRAILER (p, 5); + ADD_HEADER (p, 3); + CHECK_HISTORY (p, 3, 3, 8, 5); + p.RemoveAtStart (12); + CHECK_HISTORY (p, 1, 4); + + return ok; } From 26e52f0da47679fb20f077f693cd844907da224f Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 12:49:10 +0200 Subject: [PATCH 029/116] more tests --- src/common/packet-history.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index d143b0eec..b4ef9becd 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1264,6 +1264,12 @@ PacketHistoryTest::RunTests (void) CHECK_HISTORY (p, 3, 3, 8, 5); p.RemoveAtStart (12); CHECK_HISTORY (p, 1, 4); + p.RemoveAtEnd (2); + CHECK_HISTORY (p, 1, 2); + ADD_HEADER (p, 10); + CHECK_HISTORY (p, 2, 10, 2); + p.RemoveAtEnd (5); + CHECK_HISTORY (p, 1, 7); From 89fc9310dbcd9b23bcd0a32460200e2044b53c04 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 13:06:21 +0200 Subject: [PATCH 030/116] calculate the correct size of header and trailer to remove from buffer --- src/common/packet.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/packet.cc b/src/common/packet.cc index a2d4fc80c..e0ba34236 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -63,7 +63,8 @@ Packet Packet::CreateFragment (uint32_t start, uint32_t length) const { Buffer buffer = m_buffer.CreateFragment (start, length); - uint32_t end = buffer.GetSize () - (start + length); + NS_ASSERT (m_buffer.GetSize () >= start + length); + uint32_t end = m_buffer.GetSize () - (start + length); PacketHistory history = m_history.CreateFragment (start, end); return Packet (buffer, m_tags, history, m_uid); } From 00d6bb5c8ad9f15819c754905908031305cdabec Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 13:06:35 +0200 Subject: [PATCH 031/116] add more tests --- src/common/packet-history.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index b4ef9becd..23a5df594 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1271,6 +1271,19 @@ PacketHistoryTest::RunTests (void) p.RemoveAtEnd (5); CHECK_HISTORY (p, 1, 7); + Packet p2 = Packet (0); + Packet p3 = Packet (0); + + p = Packet (40); + ADD_HEADER (p, 5); + ADD_HEADER (p, 8); + p1 = p.CreateFragment (0, 5); + p2 = p.CreateFragment (5, 5); + p3 = p.CreateFragment (10, 43); + CHECK_HISTORY (p1, 1, 5); + CHECK_HISTORY (p2, 2, 3, 2); + CHECK_HISTORY (p3, 2, 3, 40); + return ok; From 3485d9829cb857bacc526f4abf8206a3851a3b36 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 14:35:18 +0200 Subject: [PATCH 032/116] more tests --- src/common/packet-history.cc | 25 ++++++++++++++++++------- src/common/packet-history.h | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 23a5df594..ac17836ec 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -655,15 +655,16 @@ PacketHistory::AddAtEnd (PacketHistory const&o) m_aggregated = true; uint32_t n = GetUleb128Size (PacketHistory::ADD_AT_END); n += GetUleb128Size (o.m_end); + n += GetUleb128Size (o.m_n); n += o.m_end; Reserve (n); + AppendOneCommand (PacketHistory::ADD_AT_END, o.m_end, o.m_n); memcpy (&m_data->m_data[m_end], o.m_data->m_data, o.m_end); m_end += o.m_end; if (m_end > m_data->m_dirtyEnd) { m_data->m_dirtyEnd = m_end; } - AppendOneCommand (PacketHistory::ADD_AT_END, o.m_end); } } void @@ -698,17 +699,17 @@ PacketHistory::PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinte // which are stored in this packet. uint8_t *dataBuffer = &m_data->m_data[0]; ItemList itemList; - BuildItemList (&itemList, dataBuffer, m_end); + BuildItemList (&itemList, &dataBuffer, m_end, m_n); itemList.Print (os, buffer, printer); } void -PacketHistory::BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) const +PacketHistory::BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, uint32_t n) const { // we need to build a linked list of the different fragments // which are stored in this packet. - uint8_t *dataBuffer = buffer; - for (uint32_t i = 0; i < m_n; i++) + uint8_t *dataBuffer = *buffer; + for (uint32_t i = 0; i < n; i++) { uint32_t type = ReadForwardValue (&dataBuffer); uint32_t data = ReadForwardValue (&dataBuffer); @@ -735,8 +736,9 @@ PacketHistory::BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) co list->RemTrailer (data, size); } break; case ADD_AT_END: { + uint32_t nCommands = ReadForwardValue (&dataBuffer); ItemList other; - BuildItemList (&other, dataBuffer, data); + BuildItemList (&other, &dataBuffer, data, nCommands); list->AddAtEnd (&other); } break; case REM_AT_START: { @@ -1277,13 +1279,22 @@ PacketHistoryTest::RunTests (void) p = Packet (40); ADD_HEADER (p, 5); ADD_HEADER (p, 8); + CHECK_HISTORY (p, 3, 8, 5, 40); p1 = p.CreateFragment (0, 5); p2 = p.CreateFragment (5, 5); p3 = p.CreateFragment (10, 43); CHECK_HISTORY (p1, 1, 5); CHECK_HISTORY (p2, 2, 3, 2); CHECK_HISTORY (p3, 2, 3, 40); - + p1.AddAtEnd (p2); + CHECK_HISTORY (p1, 2, 8, 2); + CHECK_HISTORY (p2, 2, 3, 2); +#if 0 + p1.AddAtEnd (p3); + CHECK_HISTORY (p1, 3, 8, 5, 40); + CHECK_HISTORY (p2, 2, 3, 2); + CHECK_HISTORY (p3, 2, 3, 40); +#endif return ok; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index bcd29d6ce..6d2fc6834 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -102,7 +102,7 @@ private: void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const; - void BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) const; + void BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, uint32_t n) const; static struct PacketHistory::CommandData *Create (uint32_t size); static void Recycle (struct CommandData *data); From 5f2b9525213151ef299618da1ad9a70996272eee Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 14:50:04 +0200 Subject: [PATCH 033/116] enable more tests --- src/common/packet-history.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index ac17836ec..8279a5a6e 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -189,11 +189,11 @@ ItemList::RemAtEnd (uint32_t toRemove) void ItemList::AddAtEnd (ItemList const *other) { + ItemList::Item &last = m_itemList.back (); for (std::list::const_iterator i = other->m_itemList.begin (); i != other->m_itemList.end (); i++) { const ItemList::Item &item = *i; - ItemList::Item &last = m_itemList.back (); if (item.m_packetUid == last.m_packetUid && item.m_type == last.m_type && item.m_chunkType == last.m_chunkType && @@ -751,6 +751,7 @@ PacketHistory::BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, u break; } } + *buffer = dataBuffer; } void @@ -1289,12 +1290,10 @@ PacketHistoryTest::RunTests (void) p1.AddAtEnd (p2); CHECK_HISTORY (p1, 2, 8, 2); CHECK_HISTORY (p2, 2, 3, 2); -#if 0 p1.AddAtEnd (p3); CHECK_HISTORY (p1, 3, 8, 5, 40); CHECK_HISTORY (p2, 2, 3, 2); CHECK_HISTORY (p3, 2, 3, 40); -#endif return ok; From 4c92dfe9149cfbaa048f774f7070448998b00a08 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 15:23:07 +0200 Subject: [PATCH 034/116] add more asserts, make TransformIntoRealBuffer public for Packet class --- src/common/buffer.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/common/buffer.h b/src/common/buffer.h index 4986d4998..02f1f69f2 100644 --- a/src/common/buffer.h +++ b/src/common/buffer.h @@ -320,6 +320,8 @@ public: */ inline Buffer::Iterator End (void) const; + void TransformIntoRealBuffer (void) const; + inline Buffer (Buffer const &o); inline Buffer &operator = (Buffer const &o); inline Buffer (); @@ -337,7 +339,6 @@ private: typedef std::vector BufferDataList; inline uint8_t *GetStart (void) const; - void TransformIntoRealBuffer (void) const; static void Recycle (struct Buffer::BufferData *data); static struct Buffer::BufferData *Create (void); static struct Buffer::BufferData *Allocate (uint32_t size, uint32_t start); @@ -543,6 +544,8 @@ Buffer::Iterator::Write (Iterator start, Iterator end) { NS_ASSERT (start.m_data == end.m_data); NS_ASSERT (start.m_current <= end.m_current); + NS_ASSERT (start.m_zeroStart == end.m_zeroStart); + NS_ASSERT (start.m_zeroEnd == end.m_zeroEnd); NS_ASSERT (m_data != start.m_data); uint32_t size = end.m_current - start.m_current; uint8_t *src = start.m_data + start.GetIndex (size); From 8a62c228b2afc18a224a3576c464bb3d347566fc Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 15:23:30 +0200 Subject: [PATCH 035/116] ensure that packets are real buffers before concatenating them --- src/common/packet.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/packet.cc b/src/common/packet.cc index e0ba34236..4796d86e6 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -78,6 +78,9 @@ Packet::GetSize (void) const void Packet::AddAtEnd (Packet packet) { + packet.m_buffer.TransformIntoRealBuffer (); + m_buffer.TransformIntoRealBuffer (); + Buffer src = packet.m_buffer; m_buffer.AddAtEnd (src.GetSize ()); Buffer::Iterator destStart = m_buffer.End (); From 34c6957f95d455b52d98a43cc4aad08ce92e0032 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 1 Jun 2007 15:26:21 +0200 Subject: [PATCH 036/116] more tests --- src/common/packet-history.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 8279a5a6e..52a7f5aa8 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1294,6 +1294,29 @@ PacketHistoryTest::RunTests (void) CHECK_HISTORY (p1, 3, 8, 5, 40); CHECK_HISTORY (p2, 2, 3, 2); CHECK_HISTORY (p3, 2, 3, 40); + p1 = p.CreateFragment (0, 5); + CHECK_HISTORY (p1, 1, 5); + + p3 = Packet (50); + ADD_HEADER (p3, 8); + CHECK_HISTORY (p3, 2, 8, 50); + CHECK_HISTORY (p1, 1, 5); + p1.AddAtEnd (p3); + CHECK_HISTORY (p1, 3, 5, 8, 50); + ADD_HEADER (p1, 5); + CHECK_HISTORY (p1, 4, 5, 5, 8, 50); + ADD_TRAILER (p1, 2); + CHECK_HISTORY (p1, 5, 5, 5, 8, 50, 2); + REM_HEADER (p1, 5); + CHECK_HISTORY (p1, 4, 5, 8, 50, 2); + p1.RemoveAtEnd (60); + CHECK_HISTORY (p1, 1, 5); + p1.AddAtEnd (p2); + CHECK_HISTORY (p1, 2, 8, 2); + CHECK_HISTORY (p2, 2, 3, 2); + + + return ok; From bebb4eb281d12b84817f50da392891810320bd87 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 2 Jun 2007 18:08:04 +0200 Subject: [PATCH 037/116] fix build for g++ 4.1 --- src/common/packet-printer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 2a0c36d3f..fbea25d26 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -94,7 +94,7 @@ public: private: friend class PacketHistory; - friend class ItemList; + friend class ::ItemList; struct Printer { uint32_t m_chunkUid; From b9899de6df7e15babeb49dfafc6707c1cdb5a3b0 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 2 Jun 2007 18:13:19 +0200 Subject: [PATCH 038/116] more tests --- src/common/packet-history.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 52a7f5aa8..02411c071 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1314,6 +1314,17 @@ PacketHistoryTest::RunTests (void) p1.AddAtEnd (p2); CHECK_HISTORY (p1, 2, 8, 2); CHECK_HISTORY (p2, 2, 3, 2); + + p3 = Packet (40); + ADD_HEADER (p3, 5); + ADD_HEADER (p3, 5); + CHECK_HISTORY (p3, 3, 5, 5, 40); + p1 = p3.CreateFragment (0, 5); + p2 = p3.CreateFragment (5, 5); + CHECK_HISTORY (p1, 1, 5); + CHECK_HISTORY (p2, 1, 5); + p1.AddAtEnd (p2); + CHECK_HISTORY (p1, 2, 5, 5); From a986e813537c3a8aee1192567bed34b32ff839be Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 2 Jun 2007 18:24:44 +0200 Subject: [PATCH 039/116] more tests, initial fix. --- src/common/packet-history.cc | 43 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 02411c071..82afac68b 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -61,20 +61,25 @@ private: uint32_t m_packetUid; }; std::list m_itemList; + uint32_t m_packetUid; }; void ItemList::InitPayload (uint32_t packetUid, uint32_t size) { NS_ASSERT (m_itemList.empty ()); - struct Item item; - item.m_type = ItemList::PAYLOAD; - item.m_chunkType = 0; - item.m_size = size; - item.m_fragmentStart = 0; - item.m_fragmentEnd = item.m_size; - item.m_packetUid = packetUid; - m_itemList.push_back (item); + if (size > 0) + { + struct Item item; + item.m_type = ItemList::PAYLOAD; + item.m_chunkType = 0; + item.m_size = size; + item.m_fragmentStart = 0; + item.m_fragmentEnd = item.m_size; + item.m_packetUid = packetUid; + m_itemList.push_back (item); + } + m_packetUid = packetUid; } void @@ -86,7 +91,7 @@ ItemList::AddHeader (uint32_t type, uint32_t size) item.m_size = size; item.m_fragmentStart = 0; item.m_fragmentEnd = size; - item.m_packetUid = m_itemList.front ().m_packetUid; + item.m_packetUid = m_packetUid; m_itemList.push_front (item); } @@ -99,7 +104,7 @@ ItemList::AddTrailer (uint32_t type, uint32_t size) item.m_size = size; item.m_fragmentStart = 0; item.m_fragmentEnd = size; - item.m_packetUid = m_itemList.back ().m_packetUid; + item.m_packetUid = m_packetUid; m_itemList.push_back (item); } @@ -213,7 +218,6 @@ ItemList::AddAtEnd (ItemList const *other) void ItemList::Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter &printer) const { - NS_ASSERT (!m_itemList.empty ()); uint32_t totalSize = 0; for (std::list::const_iterator i = m_itemList.begin (); i != m_itemList.end (); i++) @@ -1325,7 +1329,22 @@ PacketHistoryTest::RunTests (void) CHECK_HISTORY (p2, 1, 5); p1.AddAtEnd (p2); CHECK_HISTORY (p1, 2, 5, 5); - + + p = Packet (0); + CHECK_HISTORY (p, 0); + +#if 0 + p3 = Packet (0); + ADD_HEADER (p3, 5); + ADD_HEADER (p3, 5); + CHECK_HISTORY (p3, 2, 5, 5); + p1 = p3.CreateFragment (0, 4); + p2 = p3.CreateFragment (9, 1); + CHECK_HISTORY (p1, 1, 4); + CHECK_HISTORY (p2, 1, 1); + p1.AddAtEnd (p2); + CHECK_HISTORY (p1, 2, 4, 1); +#endif From a88ff1f2c450726b251571ec8a9685fb85f51fc8 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 2 Jun 2007 18:32:31 +0200 Subject: [PATCH 040/116] more tests, fix --- src/common/packet-history.cc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 82afac68b..2a5843ff5 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -59,15 +59,20 @@ private: uint32_t m_fragmentStart; uint32_t m_fragmentEnd; uint32_t m_packetUid; + uint32_t m_chunkUid; }; std::list m_itemList; uint32_t m_packetUid; + uint32_t m_chunkUid; }; + void ItemList::InitPayload (uint32_t packetUid, uint32_t size) { NS_ASSERT (m_itemList.empty ()); + m_packetUid = packetUid; + m_chunkUid = 1; if (size > 0) { struct Item item; @@ -76,10 +81,10 @@ ItemList::InitPayload (uint32_t packetUid, uint32_t size) item.m_size = size; item.m_fragmentStart = 0; item.m_fragmentEnd = item.m_size; - item.m_packetUid = packetUid; + item.m_packetUid = m_packetUid; + item.m_chunkUid = m_chunkUid; m_itemList.push_back (item); } - m_packetUid = packetUid; } void @@ -92,7 +97,9 @@ ItemList::AddHeader (uint32_t type, uint32_t size) item.m_fragmentStart = 0; item.m_fragmentEnd = size; item.m_packetUid = m_packetUid; + item.m_chunkUid = m_chunkUid; m_itemList.push_front (item); + m_chunkUid++; } void @@ -105,7 +112,9 @@ ItemList::AddTrailer (uint32_t type, uint32_t size) item.m_fragmentStart = 0; item.m_fragmentEnd = size; item.m_packetUid = m_packetUid; + item.m_chunkUid = m_chunkUid; m_itemList.push_back (item); + m_chunkUid++; } void @@ -204,7 +213,8 @@ ItemList::AddAtEnd (ItemList const *other) item.m_chunkType == last.m_chunkType && item.m_size == last.m_size && last.m_fragmentEnd != last.m_size && - item.m_fragmentStart == last.m_fragmentEnd) + item.m_fragmentStart == last.m_fragmentEnd && + item.m_chunkUid == last.m_chunkUid) { last.m_fragmentEnd = item.m_fragmentEnd; } @@ -1333,7 +1343,6 @@ PacketHistoryTest::RunTests (void) p = Packet (0); CHECK_HISTORY (p, 0); -#if 0 p3 = Packet (0); ADD_HEADER (p3, 5); ADD_HEADER (p3, 5); @@ -1344,7 +1353,6 @@ PacketHistoryTest::RunTests (void) CHECK_HISTORY (p2, 1, 1); p1.AddAtEnd (p2); CHECK_HISTORY (p1, 2, 4, 1); -#endif From ce4bcba2e66caa4c7126f507ccb1c3eb0dc39da7 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 2 Jun 2007 18:36:56 +0200 Subject: [PATCH 041/116] Added tag packet-history-working for changeset 0dc81e76166c --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index b812011d2..f97351e5b 100644 --- a/.hgtags +++ b/.hgtags @@ -1,2 +1,3 @@ 56928998e05c9c11f5f3aefe79be8d2843e0db88 release ns-3.0.1 7ac5a4b0969b255c4824c926c2b37ef450136ce9 release ns-3.0.2 +0dc81e76166c56aaae64da48b673b62155943aad packet-history-working From a6c8a118815e93b620cf7fcc50e30235a10e3960 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sat, 2 Jun 2007 19:10:35 +0200 Subject: [PATCH 042/116] fix the packet benchmark and enable it --- SConstruct | 4 +- utils/bench-packets.cc | 140 ++++++++++++++++++++++++++++------------- 2 files changed, 99 insertions(+), 45 deletions(-) diff --git a/SConstruct b/SConstruct index e882b64b1..4cf009bf1 100644 --- a/SConstruct +++ b/SConstruct @@ -368,9 +368,9 @@ run_tests.add_deps(['core', 'simulator', 'common']) run_tests.add_source('run-tests.cc') bench_packets = build.Ns3Module('bench-packets', 'utils') -#ns3.add(bench_packets) +ns3.add(bench_packets) bench_packets.set_executable() -bench_packets.add_dep('core') +bench_packets.add_deps (['core', 'common']) bench_packets.add_source('bench-packets.cc') bench_simu = build.Ns3Module('bench-simulator', 'utils') diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index b99274b94..9d44a557f 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -18,85 +18,139 @@ * * Author: Mathieu Lacage */ -#include "ns3/wall-clock-ms.h" +#include "ns3/system-wall-clock-ms.h" #include "ns3/packet.h" -#include "ns3/chunk-constant-data.h" -#include "ns3/chunk-udp.h" -#include "ns3/chunk-ipv4.h" #include +#include using namespace ns3; +template +class BenchHeader : public Header +{ +public: + BenchHeader (); + bool IsOk (void) const; +private: + virtual std::string DoGetName (void) const; + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); + bool m_ok; +}; + +template +BenchHeader::BenchHeader () + : m_ok (false) +{} + +template +bool +BenchHeader::IsOk (void) const +{ + return m_ok; +} + +template +std::string +BenchHeader::DoGetName (void) const +{ + std::ostringstream oss; + oss << N; + return oss.str (); +} + +template +void +BenchHeader::PrintTo (std::ostream &os) const +{ + NS_ASSERT (false); +} +template +uint32_t +BenchHeader::GetSerializedSize (void) const +{ + return N; +} +template +void +BenchHeader::SerializeTo (Buffer::Iterator start) const +{ + start.WriteU8 (N, N); +} +template +uint32_t +BenchHeader::DeserializeFrom (Buffer::Iterator start) +{ + m_ok = true; + for (int i = 0; i < N; i++) + { + if (start.ReadU8 () != N) + { + m_ok = false; + } + } + return N; +} + + + static void benchPtrA (uint32_t n) { - ChunkConstantData data = ChunkConstantData (2000, 1); - ChunkUdp udp; - ChunkIpv4 ipv4; + BenchHeader<25> ipv4; + BenchHeader<8> udp; for (uint32_t i = 0; i < n; i++) { - Packet p; - p.add (&data); - p.add (&udp); - p.add (&ipv4); + Packet p (2000); + p.AddHeader (udp); + p.AddHeader (ipv4); Packet o = p; - o.peek (&ipv4); - o.remove (&ipv4); - o.peek (&udp); - o.remove (&udp); - o.peek (&data); - o.remove (&data); + o.RemoveHeader (ipv4); + o.RemoveHeader (udp); } } static void benchPtrB (uint32_t n) { - ChunkConstantData data = ChunkConstantData (2000, 1); - ChunkUdp udp; - ChunkIpv4 ipv4; + BenchHeader<25> ipv4; + BenchHeader<8> udp; for (uint32_t i = 0; i < n; i++) { - Packet p; - p.add (&data); - p.add (&udp); - p.add (&ipv4); + Packet p (2000); + p.AddHeader (udp); + p.AddHeader (ipv4); } } static void ptrC2 (Packet p) { - ChunkConstantData data = ChunkConstantData (2000, 1); - ChunkUdp udp; + BenchHeader<8> udp; - p.peek (&udp); - p.remove (&udp); - p.peek (&data); - p.remove (&data); + p.RemoveHeader (udp); } static void ptrC1 (Packet p) { - ChunkIpv4 ipv4; - p.peek (&ipv4); - p.remove (&ipv4); + BenchHeader<25> ipv4; + p.RemoveHeader (ipv4); ptrC2 (p); } static void benchPtrC (uint32_t n) { - ChunkConstantData data = ChunkConstantData (2000, 1); - ChunkUdp udp; - ChunkIpv4 ipv4; + BenchHeader<25> ipv4; + BenchHeader<8> udp; for (uint32_t i = 0; i < n; i++) { - Packet p; - p.add (&data); - p.add (&udp); - p.add (&ipv4); + Packet p (2000); + p.AddHeader (udp); + p.AddHeader (ipv4); ptrC1 (p); } } @@ -105,10 +159,10 @@ benchPtrC (uint32_t n) static void runBench (void (*bench) (uint32_t), uint32_t n, char const *name) { - WallClockMs time; - time.start (); + SystemWallClockMs time; + time.Start (); (*bench) (n); - unsigned long long deltaMs = time.end (); + unsigned long long deltaMs = time.End (); double ps = n; ps *= 1000; ps /= deltaMs; From a4f727f68df3f904f94ecc6c3a2a548e6858cb7e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sun, 3 Jun 2007 20:09:56 +0200 Subject: [PATCH 043/116] a bunch of optimizations --- src/common/packet-history.cc | 469 +++++++++++++++++++++-------------- src/common/packet-history.h | 82 +++++- utils/bench-packets.cc | 15 +- 3 files changed, 364 insertions(+), 202 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 2a5843ff5..b5b70af03 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -22,10 +22,15 @@ #include #include "ns3/assert.h" #include "ns3/fatal-error.h" +#include "ns3/debug.h" #include "packet-history.h" #include "chunk.h" #include "buffer.h" +NS_DEBUG_COMPONENT_DEFINE ("PacketHistory"); + +#define noUSE_ULEB 1 + namespace { class ItemList @@ -278,6 +283,44 @@ namespace ns3 { bool PacketHistory::m_enable = false; uint32_t PacketHistory::m_maxSize = 0; PacketHistory::DataFreeList PacketHistory::m_freeList; +uint32_t g_nAllocs = 0; +uint32_t g_nDeAllocs = 0; +uint32_t g_nRecycle = 0; +uint32_t g_nCreate = 0; + uint32_t g_one = 0; + uint32_t g_two = 0; + uint32_t g_three = 0; + uint32_t g_four = 0; + uint32_t g_five = 0; + +void +PacketHistory::PrintStats (void) +{ + std::cout << "allocs="<m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + uint8_t *start = &m_data->m_data[m_end]; + uint8_t *current = start; + if (TryToAppendSmallValue (type, ¤t) && + TryToAppendSmallValue (data0, ¤t) && + TryToAppendValue (data1, ¤t)) + { + uintptr_t written = current - start; + m_end += written; + m_data->m_dirtyEnd = m_end; + m_n++; + g_one++; + return; + } + } + + g_two++; + uint32_t n = GetUleb128Size (type); + n += GetUleb128Size (data0); + n += GetUleb128Size (data1); + Reserve (n); + AppendValue (type); + AppendValue (data0); + AppendValue (data1); + m_n++; + +#else + restart: + if (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + uint32_t *start = (uint32_t *)&m_data->m_data[m_end]; + uint32_t *end = (uint32_t *)&m_data->m_data[m_data->m_size]; + if (start + 2 < end) + { + start[0] = type; + start[1] = data0; + start[2] = data1; + m_end += 12; + m_data->m_dirtyEnd = m_end; + m_n++; + g_one++; + return; + } + } + g_two++; + Reserve (12); + goto restart; +#endif +} + +void +PacketHistory::AppendOneCommand (uint32_t type, uint32_t data) +{ + NS_ASSERT (m_data != 0); +#ifdef USE_ULEB + if (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + uint8_t *start = &m_data->m_data[m_end]; + uint8_t *current = start; + if (TryToAppendSmallValue (type, ¤t) && + TryToAppendSmallValue (data, ¤t)) + { + uintptr_t written = current - start; + m_end += written; + m_data->m_dirtyEnd = m_end; + m_n++; + g_one++; + return; + } + } + + g_two++; + uint32_t n = GetUleb128Size (data); + n += GetUleb128Size (type); + Reserve (n); + AppendValue (type); + AppendValue (data); + m_n++; +#else + restart: + if (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + uint32_t *start = (uint32_t *)&m_data->m_data[m_end]; + uint32_t *end = (uint32_t *)&m_data->m_data[m_data->m_size]; + if (start + 1 < end) + { + start[0] = type; + start[1] = data; + m_end += 8; + m_data->m_dirtyEnd = m_end; + m_n++; + g_one++; + return; + } + } + g_two++; + Reserve (8); + goto restart; +#endif +} +void +PacketHistory::ReserveCopy (uint32_t size) +{ + struct CommandData *newData = PacketHistory::Create (m_end + size); + memcpy (newData->m_data, m_data->m_data, m_end); + newData->m_dirtyEnd = m_end; + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + m_data = newData; +} +void +PacketHistory::Reserve (uint32_t size) +{ + NS_ASSERT (m_data != 0); + if (m_data->m_size >= m_end + size && + (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end)) + { + /* enough room, not dirty. */ + g_four++; + } + else + { + /* (enough room and dirty) or (not enough room) */ + ReserveCopy (size); + g_five++; + } } uint32_t @@ -666,7 +750,6 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { if (m_enable) { - m_aggregated = true; uint32_t n = GetUleb128Size (PacketHistory::ADD_AT_END); n += GetUleb128Size (o.m_end); n += GetUleb128Size (o.m_n); diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 6d2fc6834..99ebf794b 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -39,10 +39,10 @@ class PacketHistory { public: static void Enable (void); - PacketHistory (uint32_t uid, uint32_t size); - PacketHistory (PacketHistory const &o); - PacketHistory &operator = (PacketHistory const& o); - ~PacketHistory (); + inline PacketHistory (uint32_t uid, uint32_t size); + inline PacketHistory (PacketHistory const &o); + inline PacketHistory &operator = (PacketHistory const& o); + inline ~PacketHistory (); template void AddHeader (T const &header, uint32_t size); @@ -63,6 +63,8 @@ public: void PrintDefault (std::ostream &os, Buffer buffer) const; void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const; + static void PrintStats (void); + private: enum CommandType { INIT = 0, @@ -88,9 +90,8 @@ private: PacketHistory (); void Reserve (uint32_t n); - void Construct (uint32_t uid, uint32_t size); + inline void Construct (uint32_t uid, uint32_t size); uint32_t GetUleb128Size (uint32_t value) const; - uint32_t GetReverseUleb128Size (uint8_t *buffer) const; void AppendValue (uint32_t value); uint32_t ReadForwardValue (uint8_t **pBuffer) const; uint32_t ReadValue (uint8_t *buffer, uint32_t *n) const; @@ -103,6 +104,8 @@ private: void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const; void BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, uint32_t n) const; + inline bool TryToAppendValue (uint32_t value, uint8_t **buffer); + inline bool TryToAppendSmallValue (uint32_t value, uint8_t **buffer); static struct PacketHistory::CommandData *Create (uint32_t size); static void Recycle (struct CommandData *data); @@ -116,7 +119,6 @@ private: struct CommandData *m_data; uint32_t m_end; uint32_t m_n; - bool m_aggregated; }; }; // namespace ns3 @@ -149,6 +151,72 @@ PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) RemoveTrailer (PacketPrinter::GetUid (), trailer, size); } + +PacketHistory::PacketHistory (uint32_t uid, uint32_t size) + : m_data (0), + m_end (0), + m_n (0) +{ + Construct (uid, size); +} +void +PacketHistory::Construct (uint32_t uid, uint32_t size) +{ + if (m_enable) + { + m_data = PacketHistory::Create (0); + AppendOneCommand (PacketHistory::INIT, + size, uid); + } +} +PacketHistory::PacketHistory (PacketHistory const &o) + : m_data (o.m_data), + m_end (o.m_end), + m_n (o.m_n) +{ + if (m_data != 0) + { + m_data->m_count++; + } +} +PacketHistory & +PacketHistory::operator = (PacketHistory const& o) +{ + if (m_data == o.m_data) + { + // self assignment + return *this; + } + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } + m_data = o.m_data; + m_end = o.m_end; + m_n = o.m_n; + if (m_data != 0) + { + m_data->m_count++; + } + return *this; +} +PacketHistory::~PacketHistory () +{ + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } +} + + }; // namespace ns3 diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index 9d44a557f..74daa70fd 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -20,6 +20,7 @@ */ #include "ns3/system-wall-clock-ms.h" #include "ns3/packet.h" +#include "ns3/packet-history.h" #include #include @@ -173,17 +174,27 @@ int main (int argc, char *argv[]) { uint32_t n = 0; while (argc > 0) { - if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) { + if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) + { char const *nAscii = argv[0] + strlen ("--n="); n = atoi (nAscii); - } + } + if (strncmp ("--enable-history", argv[0], strlen ("--enable-history")) == 0) + { + PacketHistory::Enable (); + } argc--; argv++; } + + runBench (&benchPtrA, n, "a"); + PacketHistory::PrintStats (); runBench (&benchPtrB, n, "b"); + PacketHistory::PrintStats (); runBench (&benchPtrC, n, "c"); + PacketHistory::PrintStats (); return 0; } From 62aa29999b1fc948c90231bf7b2f5c2a57e2a8b1 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 4 Jun 2007 09:33:38 +0200 Subject: [PATCH 044/116] remove dead typedef --- src/common/packet-history.cc | 2 +- src/common/packet-history.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index b5b70af03..ad2d31d40 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -29,7 +29,7 @@ NS_DEBUG_COMPONENT_DEFINE ("PacketHistory"); -#define noUSE_ULEB 1 +#define USE_ULEB 1 namespace { diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 99ebf794b..c60665f2b 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -84,8 +84,6 @@ private: uint32_t m_dirtyEnd; uint8_t m_data[8]; }; - typedef std::vector > HeadersToPrint; - typedef std::vector > TrailersToPrint; typedef std::vector DataFreeList; PacketHistory (); From 47f2db1e23535ea771b72755cd5c99a2665338a3 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 13:44:43 +0200 Subject: [PATCH 045/116] a new implementation of the PacketHistory API --- src/common/packet-history.cc | 861 ++++++++++++++++++----------------- src/common/packet-history.h | 152 ++----- 2 files changed, 497 insertions(+), 516 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index ad2d31d40..02efc2e8f 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -282,6 +282,7 @@ namespace ns3 { bool PacketHistory::m_enable = false; uint32_t PacketHistory::m_maxSize = 0; +uint16_t PacketHistory::m_chunkUid = 0; PacketHistory::DataFreeList PacketHistory::m_freeList; uint32_t g_nAllocs = 0; uint32_t g_nDeAllocs = 0; @@ -328,7 +329,321 @@ PacketHistory::Enable (void) m_enable = true; } -struct PacketHistory::CommandData * +PacketHistory::PacketHistory (uint32_t uid, uint32_t size) + : m_data (0), + m_begin (0), + m_end (0), + m_used (0), + m_packetUid (uid) +{ + if (size > 0) + { + AddSmall (true, 0, size); + } +} +PacketHistory::PacketHistory (PacketHistory const &o) + : m_data (o.m_data), + m_begin (o.m_begin), + m_end (o.m_end), + m_used (o.m_used), + m_packetUid (o.m_packetUid) +{ + if (m_data != 0) + { + m_data->m_count++; + } +} +PacketHistory & +PacketHistory::operator = (PacketHistory const& o) +{ + if (m_data == o.m_data) + { + // self assignment + return *this; + } + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } + m_data = o.m_data; + m_begin = o.m_begin; + m_end = o.m_end; + m_used = o.m_used; + m_packetUid = o.m_packetUid; + if (m_data != 0) + { + m_data->m_count++; + } + return *this; +} +PacketHistory::~PacketHistory () +{ + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } +} + +void +PacketHistory::ReserveCopy (uint32_t size) +{ + struct PacketHistory::Data *newData = PacketHistory::Create (m_used + size); + memcpy (newData->m_data, m_data->m_data, m_end); + newData->m_dirtyEnd = m_end; + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + m_data = newData; +} +void +PacketHistory::Reserve (uint32_t size) +{ + NS_ASSERT (m_data != 0); + if (m_data->m_size >= m_used + size && + (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_used)) + { + /* enough room, not dirty. */ + g_four++; + } + else + { + /* (enough room and dirty) or (not enough room) */ + ReserveCopy (size); + g_five++; + } +} + +uint32_t +PacketHistory::GetUleb128Size (uint32_t value) const +{ + uint32_t n = 0; + uint32_t tmp = value; + do { + tmp >>= 7; + n++; + } while (tmp != 0); + return n; +} +uint32_t +PacketHistory::ReadUleb128 (uint8_t **pBuffer) const +{ + uint8_t *buffer = *pBuffer; + uint32_t result = 0; + uint8_t byte; + result = 0; + byte = buffer[0]; + result = (byte & (~0x80)); + if (!(byte & 0x80)) + { + *pBuffer = buffer + 1; + return result; + } + byte = buffer[1]; + result = (byte & (~0x80)) << 7; + if (!(byte & 0x80)) + { + *pBuffer = buffer + 2; + return result; + } + byte = buffer[2]; + result = (byte & (~0x80)) << 14; + if (!(byte & 0x80)) + { + *pBuffer = buffer + 3; + return result; + } + byte = buffer[3]; + result = (byte & (~0x80)) << 21; + if (!(byte & 0x80)) + { + *pBuffer = buffer + 4; + return result; + } + byte = buffer[4]; + result = (byte & (~0x80)) << 28; + if (!(byte & 0x80)) + { + *pBuffer = buffer + 5; + return result; + } + /* This means that the LEB128 number was not valid. + * ie: the last (5th) byte did not have the high-order bit zeroed. + */ + NS_ASSERT (false); + return 0; +} + +void +PacketHistory::Append16 (uint16_t value, uint8_t **pBuffer) +{ + uint8_t *buffer = *pBuffer; + buffer[0] = value & 0xff; + value >>= 8; + buffer[1] = value; + *pBuffer = buffer + 2; +} +bool +PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) +{ + uint8_t *start = *pBuffer; + if (value < 0x80 && start < end) + { + start[0] = value; + *pBuffer = start + 1; + return true; + } + if (value < 0x4000 && start + 1 < end) + { + uint8_t byte = value & (~0x80); + start[0] = 0x80 | byte; + value >>= 7; + start[1] = value; + *pBuffer = start + 2; + return true; + } + if (value < 0x200000 && start + 2 < end) + { + uint8_t byte = value & (~0x80); + start[0] = 0x80 | byte; + value >>= 7; + start[1] = 0x80 | byte; + value >>= 7; + start[2] = value; + *pBuffer = start + 3; + return true; + } + if (start + 3 < end) + { + uint8_t byte = value & (~0x80); + start[0] = 0x80 | byte; + value >>= 7; + start[1] = 0x80 | byte; + value >>= 7; + start[2] = 0x80 | byte; + value >>= 7; + start[3] = value; + *pBuffer = start + 4; + return true; + } + return false; +} + +bool +PacketHistory::IsZero16 (uint16_t index) +{ + return m_data->m_data[index] == 0 && m_data->m_data[index+1] == 0; +} + +bool +PacketHistory::CanAdd (bool atStart) +{ + if (atStart) + { + return IsZero16 (m_begin+2); + } + else + { + return IsZero16 (m_end); + } +} + +void +PacketHistory::AddSmall (bool atStart, + uint32_t typeUid, uint32_t size) +{ + if (m_data == 0) + { + m_data = PacketHistory::Create (10); + } + NS_ASSERT (m_data != 0); + uint16_t chunkUid = m_chunkUid; + m_chunkUid++; + append: + uint8_t *start = &m_data->m_data[m_used]; + uint8_t *end = &m_data->m_data[m_data->m_size]; + if (end - start >= 7 && + CanAdd (atStart) && + (m_data->m_count == 1 || + m_used == m_data->m_dirtyEnd)) + { + uint8_t *buffer = start; + uint16_t next, prev; + if (atStart) + { + next = m_begin; + prev = 0; + } + else + { + next = 0; + prev = m_end; + } + + Append16 (next, &buffer); + Append16 (prev, &buffer); + if (TryToAppend (typeUid, &buffer, end) && + TryToAppend (chunkUid, &buffer, end) && + TryToAppend (size, &buffer, end)) + { + uintptr_t written = buffer - start; + NS_ASSERT (written <= 0xffff); + if (atStart) + { + m_begin = m_used; + } + else + { + m_end = m_used; + } + m_used += written; + m_data->m_dirtyEnd = m_used; + return; + } + } + + uint32_t n = GetUleb128Size (typeUid); + n += GetUleb128Size (chunkUid); + n += GetUleb128Size (size); + n += 2 + 2; + Reserve (n); + goto append; +} + +void +PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, uint8_t **pBuffer) +{ + uint8_t *buffer = *pBuffer; + item->next = buffer[0]; + item->next |= (buffer[1]) << 8; + item->prev = buffer[2]; + item->prev |= (buffer[3]) << 8; + *pBuffer = *pBuffer + 4; + item->typeUid = ReadUleb128 (pBuffer); + item->size = ReadUleb128 (pBuffer); + item->chunkUid = ReadUleb128 (pBuffer); +} + +void +PacketHistory::ReadExtra (struct PacketHistory::ExtraItem *item, uint8_t **pBuffer) +{ + item->fragmentStart = ReadUleb128 (pBuffer); + item->fragmentEnd = ReadUleb128 (pBuffer); + item->packetUid = ReadUleb128 (pBuffer); +} + + +struct PacketHistory::Data * PacketHistory::Create (uint32_t size) { g_nCreate++; @@ -339,7 +654,7 @@ PacketHistory::Create (uint32_t size) } while (!m_freeList.empty ()) { - struct PacketHistory::CommandData *data = m_freeList.back (); + struct PacketHistory::Data *data = m_freeList.back (); m_freeList.pop_back (); if (data->m_size >= size) { @@ -355,7 +670,7 @@ PacketHistory::Create (uint32_t size) } void -PacketHistory::Recycle (struct CommandData *data) +PacketHistory::Recycle (struct PacketHistory::Data *data) { g_nRecycle++; NS_DEBUG ("recycle size="<m_size<<", list="<m_size = n; data->m_count = 1; + data->m_dirtyEnd = 0; return data; } void -PacketHistory::Deallocate (struct CommandData *data) +PacketHistory::Deallocate (struct PacketHistory::Data *data) { g_nDeAllocs++; uint8_t *buf = (uint8_t *)data; delete [] buf; } -bool -PacketHistory::TryToAppendSmallValue (uint32_t value, uint8_t **buffer) -{ - uint8_t *start = *buffer; - uint8_t *end = &m_data->m_data[m_data->m_size]; - if (value < 0x80 && start < end) - { - start[0] = value; - *buffer = start + 1; - return true; - } - if (value < 0x4000 && start + 1 < end) - { - uint8_t byte = value & (~0x80); - start[0] = 0x80 | byte; - value >>= 7; - start[1] = value; - *buffer = start + 2; - return true; - } - return false; -} -bool -PacketHistory::TryToAppendValue (uint32_t value, uint8_t **buffer) -{ - uint8_t *start = *buffer; - uint8_t *end = &m_data->m_data[m_data->m_size]; - if (value < 0x80 && start < end) - { - start[0] = value; - *buffer = start + 1; - return true; - } - if (value < 0x4000 && start + 1 < end) - { - uint8_t byte = value & (~0x80); - start[0] = 0x80 | byte; - value >>= 7; - start[1] = value; - *buffer = start + 2; - return true; - } - if (value < 0x200000 && start + 2 < end) - { - uint8_t byte = value & (~0x80); - start[0] = 0x80 | byte; - value >>= 7; - start[1] = 0x80 | byte; - value >>= 7; - start[2] = value; - *buffer = start + 3; - return true; - } - if (start + 3 < end) - { - uint8_t byte = value & (~0x80); - start[0] = 0x80 | byte; - value >>= 7; - start[1] = 0x80 | byte; - value >>= 7; - start[2] = 0x80 | byte; - value >>= 7; - start[3] = value; - *buffer = start + 4; - return true; - } - return false; -#if 0 - // more generic version of the above. - do { - uint8_t byte = value & (~0x80); - value >>= 7; - if (value != 0) - { - /* more bytes to come */ - byte |= 0x80; - } - *current = byte; - current++; - } while (value != 0 && current != end); - if (value != 0 && current == end) - { - return false; - } - *buffer = current; - return true; -#endif -} - -uint32_t -PacketHistory::GetUleb128Size (uint32_t value) const -{ - uint32_t n = 0; - uint32_t tmp = value; - do { - tmp >>= 7; - n++; - } while (tmp != 0); - return n; -} - -void -PacketHistory::AppendValue (uint32_t value) -{ - uint32_t n = 0; - uint8_t *buffer = &m_data->m_data[m_end]; - do { - uint8_t byte = value & (~0x80); - value >>= 7; - if (value != 0) - { - /* more bytes to come */ - byte |= 0x80; - } - n++; - *buffer = byte; - buffer++; - } while (value != 0); - m_end += n; - if (m_end > m_data->m_dirtyEnd) - { - m_data->m_dirtyEnd = m_end; - } -} - -uint32_t -PacketHistory::ReadValue (uint8_t *buffer, uint32_t *n) const -{ -#ifdef USE_ULEB - uint32_t result = 0; - uint8_t shift, byte; - result = 0; - shift = 0; - do { - byte = *buffer; - buffer++; - result |= (byte & (~0x80))<m_count == 1 || - m_data->m_dirtyEnd == m_end) - { - uint8_t *start = &m_data->m_data[m_end]; - uint8_t *current = start; - if (TryToAppendSmallValue (type, ¤t) && - TryToAppendSmallValue (data0, ¤t) && - TryToAppendValue (data1, ¤t)) - { - uintptr_t written = current - start; - m_end += written; - m_data->m_dirtyEnd = m_end; - m_n++; - g_one++; - return; - } - } - - g_two++; - uint32_t n = GetUleb128Size (type); - n += GetUleb128Size (data0); - n += GetUleb128Size (data1); - Reserve (n); - AppendValue (type); - AppendValue (data0); - AppendValue (data1); - m_n++; - -#else - restart: - if (m_data->m_count == 1 || - m_data->m_dirtyEnd == m_end) - { - uint32_t *start = (uint32_t *)&m_data->m_data[m_end]; - uint32_t *end = (uint32_t *)&m_data->m_data[m_data->m_size]; - if (start + 2 < end) - { - start[0] = type; - start[1] = data0; - start[2] = data1; - m_end += 12; - m_data->m_dirtyEnd = m_end; - m_n++; - g_one++; - return; - } - } - g_two++; - Reserve (12); - goto restart; -#endif -} - -void -PacketHistory::AppendOneCommand (uint32_t type, uint32_t data) -{ - NS_ASSERT (m_data != 0); -#ifdef USE_ULEB - if (m_data->m_count == 1 || - m_data->m_dirtyEnd == m_end) - { - uint8_t *start = &m_data->m_data[m_end]; - uint8_t *current = start; - if (TryToAppendSmallValue (type, ¤t) && - TryToAppendSmallValue (data, ¤t)) - { - uintptr_t written = current - start; - m_end += written; - m_data->m_dirtyEnd = m_end; - m_n++; - g_one++; - return; - } - } - - g_two++; - uint32_t n = GetUleb128Size (data); - n += GetUleb128Size (type); - Reserve (n); - AppendValue (type); - AppendValue (data); - m_n++; -#else - restart: - if (m_data->m_count == 1 || - m_data->m_dirtyEnd == m_end) - { - uint32_t *start = (uint32_t *)&m_data->m_data[m_end]; - uint32_t *end = (uint32_t *)&m_data->m_data[m_data->m_size]; - if (start + 1 < end) - { - start[0] = type; - start[1] = data; - m_end += 8; - m_data->m_dirtyEnd = m_end; - m_n++; - g_one++; - return; - } - } - g_two++; - Reserve (8); - goto restart; -#endif -} -void -PacketHistory::ReserveCopy (uint32_t size) -{ - struct CommandData *newData = PacketHistory::Create (m_end + size); - memcpy (newData->m_data, m_data->m_data, m_end); - newData->m_dirtyEnd = m_end; - m_data->m_count--; - if (m_data->m_count == 0) - { - PacketHistory::Recycle (m_data); - } - m_data = newData; -} -void -PacketHistory::Reserve (uint32_t size) -{ - NS_ASSERT (m_data != 0); - if (m_data->m_size >= m_end + size && - (m_data->m_count == 1 || - m_data->m_dirtyEnd == m_end)) - { - /* enough room, not dirty. */ - g_four++; - } - else - { - /* (enough room and dirty) or (not enough room) */ - ReserveCopy (size); - g_five++; - } -} - -uint32_t -PacketHistory::ReadForwardValue (uint8_t **pBuffer) const -{ - uint32_t read = 0; - uint32_t result = ReadValue (*pBuffer, &read); - *pBuffer = *pBuffer + read; - return result; -} PacketHistory PacketHistory::CreateFragment (uint32_t start, uint32_t end) const @@ -716,141 +724,177 @@ PacketHistory::CreateFragment (uint32_t start, uint32_t end) const void PacketHistory::AddHeader (uint32_t uid, Chunk const & header, uint32_t size) { - if (m_enable) + if (!m_enable) { - AppendOneCommand (PacketHistory::ADD_HEADER, uid, size); - } + return; + } + AddSmall (true, uid, size); } void PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) { - if (m_enable) + if (!m_enable) { - AppendOneCommand (PacketHistory::REM_HEADER, uid, size); + return; + } + if (m_data == 0) + { + NS_FATAL_ERROR ("Removing header from empty packet."); + } + struct PacketHistory::SmallItem item; + uint8_t *buffer = &m_data->m_data[m_begin]; + ReadSmall (&item, &buffer); + NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + if ((item.typeUid & 0xfffffffd) != uid || + item.size != size) + { + NS_FATAL_ERROR ("Removing unexpected header."); + } + else if (item.typeUid != uid) + { + // this is a "big" item + struct PacketHistory::ExtraItem extraItem; + ReadExtra (&extraItem, &buffer); + NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + if (extraItem.fragmentStart != 0 || + extraItem.fragmentEnd != size) + { + NS_FATAL_ERROR ("Removing incomplete header."); + } + } + m_begin = item.next; + if (m_begin > m_end) + { + m_used = m_begin; } } void PacketHistory::AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) { - if (m_enable) + if (!m_enable) { - AppendOneCommand (PacketHistory::ADD_TRAILER, uid, size); + return; } + AddSmall (true, uid, size); } void PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) { - if (m_enable) + if (!m_enable) { - AppendOneCommand (PacketHistory::REM_TRAILER, uid, size); + return; + } + if (m_data == 0) + { + NS_FATAL_ERROR ("Removing trailer from empty packet."); + } + struct PacketHistory::SmallItem item; + uint8_t *buffer = &m_data->m_data[m_end]; + ReadSmall (&item, &buffer); + NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + if ((item.typeUid & 0xfffffffd) != uid || + item.size != size) + { + NS_FATAL_ERROR ("Removing unexpected trailer."); + } + else if (item.typeUid != uid) + { + // this is a "big" item + struct PacketHistory::ExtraItem extraItem; + ReadExtra (&extraItem, &buffer); + NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + if (extraItem.fragmentStart != 0 || + extraItem.fragmentEnd != size) + { + NS_FATAL_ERROR ("Removing incomplete trailer."); + } + } + m_end = item.prev; + if (m_end > m_begin) + { + m_used = m_end; } } void PacketHistory::AddAtEnd (PacketHistory const&o) { - if (m_enable) + if (!m_enable) { - uint32_t n = GetUleb128Size (PacketHistory::ADD_AT_END); - n += GetUleb128Size (o.m_end); - n += GetUleb128Size (o.m_n); - n += o.m_end; - Reserve (n); - AppendOneCommand (PacketHistory::ADD_AT_END, o.m_end, o.m_n); - memcpy (&m_data->m_data[m_end], o.m_data->m_data, o.m_end); - m_end += o.m_end; - if (m_end > m_data->m_dirtyEnd) - { - m_data->m_dirtyEnd = m_end; - } + return; } } void PacketHistory::AddPaddingAtEnd (uint32_t end) { - if (m_enable) + if (!m_enable) { - AppendOneCommand (PacketHistory::PADDING_AT_END, end); + return; } } void PacketHistory::RemoveAtStart (uint32_t start) { - if (m_enable) + if (!m_enable) { - AppendOneCommand (PacketHistory::REM_AT_START, start); + return; } +#if 0 + if (m_data == 0) + { + NS_FATAL_ERROR ("Removing header from empty packet."); + } + struct PacketHistory::SmallItem item; + uint8_t *buffer = &m_data->m_data[m_begin]; + bool ok = ReadSmall (&item, &buffer); + NS_ASSERT (ok); + if ((item.typeUid & 0xfffffffd) != uid || + item.size != size) + { + NS_FATAL_ERROR ("Removing unexpected header."); + } + else if (item.typeUid != uid) + { + // this is a "big" item + struct PacketHistory::ExtraItem extraItem; + ok = ReadExtra (&extraItem, &buffer); + NS_ASSERT (ok); + if (extraItem.fragmentStart != 0 || + extraItem.fragmentEnd != size) + { + NS_FATAL_ERROR ("Removing incomplete header."); + } + } + + uint32_t leftToRemove = start; + while (!m_itemList.empty () && leftToRemove > 0) + { + struct Item &item = m_itemList.front (); + uint32_t itemRealSize = item.m_fragmentEnd - item.m_fragmentStart; + if (itemRealSize <= leftToRemove) + { + m_itemList.pop_front (); + leftToRemove -= itemRealSize; + } + else + { + item.m_fragmentStart += leftToRemove; + leftToRemove = 0; + NS_ASSERT (item.m_size >= item.m_fragmentEnd - item.m_fragmentStart && + item.m_fragmentStart <= item.m_fragmentEnd); + } + } + NS_ASSERT (leftToRemove == 0); +#endif } void PacketHistory::RemoveAtEnd (uint32_t end) { - if (m_enable) + if (!m_enable) { - AppendOneCommand (PacketHistory::REM_AT_END, end); + return; } } -void -PacketHistory::PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const -{ - // we need to build a linked list of the different fragments - // which are stored in this packet. - uint8_t *dataBuffer = &m_data->m_data[0]; - ItemList itemList; - BuildItemList (&itemList, &dataBuffer, m_end, m_n); - itemList.Print (os, buffer, printer); -} - -void -PacketHistory::BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, uint32_t n) const -{ - // we need to build a linked list of the different fragments - // which are stored in this packet. - uint8_t *dataBuffer = *buffer; - for (uint32_t i = 0; i < n; i++) - { - uint32_t type = ReadForwardValue (&dataBuffer); - uint32_t data = ReadForwardValue (&dataBuffer); - switch (type) - { - case INIT: { - uint32_t uid = ReadForwardValue (&dataBuffer); - list->InitPayload (uid, data); - } break; - case ADD_HEADER: { - uint32_t size = ReadForwardValue (&dataBuffer); - list->AddHeader (data, size); - } break; - case REM_HEADER: { - uint32_t size = ReadForwardValue (&dataBuffer); - list->RemHeader (data, size); - } break; - case ADD_TRAILER: { - uint32_t size = ReadForwardValue (&dataBuffer); - list->AddTrailer (data, size); - } break; - case REM_TRAILER: { - uint32_t size = ReadForwardValue (&dataBuffer); - list->RemTrailer (data, size); - } break; - case ADD_AT_END: { - uint32_t nCommands = ReadForwardValue (&dataBuffer); - ItemList other; - BuildItemList (&other, &dataBuffer, data, nCommands); - list->AddAtEnd (&other); - } break; - case REM_AT_START: { - list->RemAtStart (data); - } break; - case REM_AT_END: { - list->RemAtEnd (data); - } break; - case PADDING_AT_END: - break; - } - } - *buffer = dataBuffer; -} - void PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const { @@ -865,7 +909,6 @@ PacketHistory::Print (std::ostream &os, Buffer buffer, const PacketPrinter &prin return; } - PrintComplex (os, buffer, printer); } diff --git a/src/common/packet-history.h b/src/common/packet-history.h index c60665f2b..5e4fc0f33 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -39,10 +39,10 @@ class PacketHistory { public: static void Enable (void); - inline PacketHistory (uint32_t uid, uint32_t size); - inline PacketHistory (PacketHistory const &o); - inline PacketHistory &operator = (PacketHistory const& o); - inline ~PacketHistory (); + PacketHistory (uint32_t uid, uint32_t size); + PacketHistory (PacketHistory const &o); + PacketHistory &operator = (PacketHistory const& o); + ~PacketHistory (); template void AddHeader (T const &header, uint32_t size); @@ -66,57 +66,61 @@ public: static void PrintStats (void); private: - enum CommandType { - INIT = 0, - ADD_HEADER = 1, - REM_HEADER = 2, - ADD_TRAILER = 3, - REM_TRAILER = 4, - ADD_AT_END = 5, - REM_AT_START = 6, - REM_AT_END = 7, - PADDING_AT_END = 9, - LAST + struct Data { + uint16_t m_count; + uint16_t m_size; + uint16_t m_dirtyEnd; + uint8_t m_data[10]; }; - struct CommandData { - uint32_t m_count; - uint32_t m_size; - uint32_t m_dirtyEnd; - uint8_t m_data[8]; + struct SmallItem { + uint16_t next; + uint16_t prev; + uint32_t typeUid; + uint32_t size; + uint16_t chunkUid; }; - typedef std::vector DataFreeList; + struct ExtraItem { + uint32_t fragmentStart; + uint32_t fragmentEnd; + uint32_t packetUid; + }; + + typedef std::vector DataFreeList; PacketHistory (); - void Reserve (uint32_t n); - inline void Construct (uint32_t uid, uint32_t size); - uint32_t GetUleb128Size (uint32_t value) const; - void AppendValue (uint32_t value); - uint32_t ReadForwardValue (uint8_t **pBuffer) const; - uint32_t ReadValue (uint8_t *buffer, uint32_t *n) const; - void AppendOneCommand (uint32_t type, uint32_t data); - void AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1); - void ReserveCopy (uint32_t size); void AddHeader (uint32_t uid, Chunk const & header, uint32_t size); void RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size); void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); - void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const; - void BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, uint32_t n) const; - inline bool TryToAppendValue (uint32_t value, uint8_t **buffer); - inline bool TryToAppendSmallValue (uint32_t value, uint8_t **buffer); - static struct PacketHistory::CommandData *Create (uint32_t size); - static void Recycle (struct CommandData *data); - static struct PacketHistory::CommandData *Allocate (uint32_t n); - static void Deallocate (struct CommandData *data); + void AddSmall (bool atStart, + uint32_t typeUid, uint32_t size); + uint32_t GetUleb128Size (uint32_t value) const; + uint32_t ReadUleb128 (uint8_t **pBuffer) const; + void Append16 (uint16_t value, uint8_t **pBuffer); + bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); + bool IsZero16 (uint16_t index); + bool CanAdd (bool atStart); + void ReadSmall (struct PacketHistory::SmallItem *item, uint8_t **pBuffer); + void ReadExtra (struct PacketHistory::ExtraItem *item, uint8_t **pBuffer); + void Reserve (uint32_t n); + void ReserveCopy (uint32_t n); + + static struct PacketHistory::Data *Create (uint32_t size); + static void Recycle (struct PacketHistory::Data *data); + static struct PacketHistory::Data *Allocate (uint32_t n); + static void Deallocate (struct PacketHistory::Data *data); static DataFreeList m_freeList; static bool m_enable; static uint32_t m_maxSize; + static uint16_t m_chunkUid; - struct CommandData *m_data; - uint32_t m_end; - uint32_t m_n; + struct Data *m_data; + uint16_t m_begin; + uint16_t m_end; + uint16_t m_used; + uint32_t m_packetUid; }; }; // namespace ns3 @@ -149,72 +153,6 @@ PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) RemoveTrailer (PacketPrinter::GetUid (), trailer, size); } - -PacketHistory::PacketHistory (uint32_t uid, uint32_t size) - : m_data (0), - m_end (0), - m_n (0) -{ - Construct (uid, size); -} -void -PacketHistory::Construct (uint32_t uid, uint32_t size) -{ - if (m_enable) - { - m_data = PacketHistory::Create (0); - AppendOneCommand (PacketHistory::INIT, - size, uid); - } -} -PacketHistory::PacketHistory (PacketHistory const &o) - : m_data (o.m_data), - m_end (o.m_end), - m_n (o.m_n) -{ - if (m_data != 0) - { - m_data->m_count++; - } -} -PacketHistory & -PacketHistory::operator = (PacketHistory const& o) -{ - if (m_data == o.m_data) - { - // self assignment - return *this; - } - if (m_data != 0) - { - m_data->m_count--; - if (m_data->m_count == 0) - { - PacketHistory::Recycle (m_data); - } - } - m_data = o.m_data; - m_end = o.m_end; - m_n = o.m_n; - if (m_data != 0) - { - m_data->m_count++; - } - return *this; -} -PacketHistory::~PacketHistory () -{ - if (m_data != 0) - { - m_data->m_count--; - if (m_data->m_count == 0) - { - PacketHistory::Recycle (m_data); - } - } -} - - }; // namespace ns3 From dc62fabc0bcaab35a32f105cb489350b516ff8eb Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 14:06:58 +0200 Subject: [PATCH 046/116] fix addition of a trailer or a header --- src/common/packet-history.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 02efc2e8f..f3a3770d0 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -396,8 +396,8 @@ void PacketHistory::ReserveCopy (uint32_t size) { struct PacketHistory::Data *newData = PacketHistory::Create (m_used + size); - memcpy (newData->m_data, m_data->m_data, m_end); - newData->m_dirtyEnd = m_end; + memcpy (newData->m_data, m_data->m_data, m_used); + newData->m_dirtyEnd = m_used; m_data->m_count--; if (m_data->m_count == 0) { @@ -565,6 +565,7 @@ PacketHistory::AddSmall (bool atStart, if (m_data == 0) { m_data = PacketHistory::Create (10); + memset (m_data->m_data, 0, 4); } NS_ASSERT (m_data != 0); uint16_t chunkUid = m_chunkUid; @@ -616,7 +617,7 @@ PacketHistory::AddSmall (bool atStart, n += GetUleb128Size (chunkUid); n += GetUleb128Size (size); n += 2 + 2; - Reserve (n); + ReserveCopy (n); goto append; } From 35dbade0a96d088e90d91da03dafeb7acb6ee3c1 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 15:47:29 +0200 Subject: [PATCH 047/116] implement PacketHistory::Print --- src/common/packet-history.cc | 194 ++++++++++++++++++++++++++++++----- src/common/packet-history.h | 20 ++-- src/common/packet-printer.cc | 24 ++++- src/common/packet-printer.h | 74 ++++++++++--- 4 files changed, 261 insertions(+), 51 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index f3a3770d0..60ab5efcf 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -331,8 +331,8 @@ PacketHistory::Enable (void) PacketHistory::PacketHistory (uint32_t uid, uint32_t size) : m_data (0), - m_begin (0), - m_end (0), + m_begin (0xffff), + m_end (0xffff), m_used (0), m_packetUid (uid) { @@ -436,9 +436,9 @@ PacketHistory::GetUleb128Size (uint32_t value) const return n; } uint32_t -PacketHistory::ReadUleb128 (uint8_t **pBuffer) const +PacketHistory::ReadUleb128 (const uint8_t **pBuffer) const { - uint8_t *buffer = *pBuffer; + const uint8_t *buffer = *pBuffer; uint32_t result = 0; uint8_t byte; result = 0; @@ -540,21 +540,25 @@ PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) } bool -PacketHistory::IsZero16 (uint16_t index) +PacketHistory::IsFF16 (uint16_t index) { - return m_data->m_data[index] == 0 && m_data->m_data[index+1] == 0; + return m_data->m_data[index] == 0xff && m_data->m_data[index+1] == 0xff; } bool PacketHistory::CanAdd (bool atStart) { - if (atStart) + if (atStart && m_begin != 0xffff) { - return IsZero16 (m_begin+2); + return IsFF16 (m_begin+2); + } + else if (!atStart && m_end != 0xffff) + { + return IsFF16 (m_end); } else { - return IsZero16 (m_end); + return false; } } @@ -565,7 +569,7 @@ PacketHistory::AddSmall (bool atStart, if (m_data == 0) { m_data = PacketHistory::Create (10); - memset (m_data->m_data, 0, 4); + memset (m_data->m_data, 0xff, 4); } NS_ASSERT (m_data != 0); uint16_t chunkUid = m_chunkUid; @@ -583,11 +587,11 @@ PacketHistory::AddSmall (bool atStart, if (atStart) { next = m_begin; - prev = 0; + prev = 0xffff; } else { - next = 0; + next = 0xffff; prev = m_end; } @@ -599,7 +603,13 @@ PacketHistory::AddSmall (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); - if (atStart) + if (m_begin == 0xffff) + { + NS_ASSERT (m_end == 0xffff); + m_begin = m_used; + m_end = m_used; + } + else if (atStart) { m_begin = m_used; } @@ -607,6 +617,8 @@ PacketHistory::AddSmall (bool atStart, { m_end = m_used; } + NS_ASSERT (m_end != 0xffff); + NS_ASSERT (m_begin != 0xffff); m_used += written; m_data->m_dirtyEnd = m_used; return; @@ -622,9 +634,9 @@ PacketHistory::AddSmall (bool atStart, } void -PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, uint8_t **pBuffer) +PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const { - uint8_t *buffer = *pBuffer; + const uint8_t *buffer = *pBuffer; item->next = buffer[0]; item->next |= (buffer[1]) << 8; item->prev = buffer[2]; @@ -636,7 +648,7 @@ PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, uint8_t **pBuff } void -PacketHistory::ReadExtra (struct PacketHistory::ExtraItem *item, uint8_t **pBuffer) +PacketHistory::ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const { item->fragmentStart = ReadUleb128 (pBuffer); item->fragmentEnd = ReadUleb128 (pBuffer); @@ -743,7 +755,7 @@ PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) NS_FATAL_ERROR ("Removing header from empty packet."); } struct PacketHistory::SmallItem item; - uint8_t *buffer = &m_data->m_data[m_begin]; + const uint8_t *buffer = &m_data->m_data[m_begin]; ReadSmall (&item, &buffer); NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); if ((item.typeUid & 0xfffffffd) != uid || @@ -790,7 +802,7 @@ PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size NS_FATAL_ERROR ("Removing trailer from empty packet."); } struct PacketHistory::SmallItem item; - uint8_t *buffer = &m_data->m_data[m_end]; + const uint8_t *buffer = &m_data->m_data[m_end]; ReadSmall (&item, &buffer); NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); if ((item.typeUid & 0xfffffffd) != uid || @@ -902,14 +914,148 @@ PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const Print (os, buffer, PacketPrinter::GetDefault ()); } +uint32_t +PacketHistory::DoPrint (struct PacketHistory::SmallItem *item, uint8_t const*buffer, + Buffer data, uint32_t offset, const PacketPrinter &printer, + std::ostream &os) const +{ + ReadSmall (item, &buffer); + bool isExtra = (item->typeUid & 0x1) == 0x1; + uint32_t uid = item->typeUid & 0xfffffffd; + uint32_t fragmentStart, fragmentEnd; + uint32_t packetUid; + if (isExtra) + { + PacketHistory::ExtraItem extraItem; + ReadExtra (&extraItem, &buffer); + fragmentStart = extraItem.fragmentStart; + fragmentEnd = extraItem.fragmentEnd; + packetUid = extraItem.packetUid; + } + else + { + fragmentStart = 0; + fragmentEnd = item->size; + packetUid = m_packetUid; + } + NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + if (uid == 0) + { + // payload. + printer.PrintPayload (os, packetUid, item->size, + fragmentStart, + fragmentEnd); + } + else if (fragmentStart != 0 && + fragmentEnd != item->size) + { + printer.PrintChunkFragment (uid, os, packetUid, item->size, + fragmentStart, fragmentEnd); + } + else if (PacketPrinter::IsHeader (uid)) + { + ns3::Buffer::Iterator j = data.Begin (); + j.Next (offset); + printer.PrintChunk (uid, j, os, packetUid, item->size); + } + else if (PacketPrinter::IsTrailer (uid)) + { + ns3::Buffer::Iterator j = data.End (); + j.Prev (data.GetSize () - (offset + item->size)); + printer.PrintChunk (uid, j, os, packetUid, item->size); + } + else + { + NS_ASSERT (false); + } + return fragmentEnd - fragmentStart; +} + +uint32_t +PacketHistory::GetTotalSize (void) const +{ + uint32_t totalSize = 0; + uint16_t current = m_begin; + uint16_t end = m_end; + while (current != 0xffff) + { + const uint8_t *buffer = &m_data->m_data[current]; + struct PacketHistory::SmallItem item; + ReadSmall (&item, &buffer); + bool isExtra = (item.typeUid & 0x1) == 0x1; + uint32_t fragmentStart, fragmentEnd; + if (isExtra) + { + PacketHistory::ExtraItem extraItem; + ReadExtra (&extraItem, &buffer); + fragmentStart = extraItem.fragmentStart; + fragmentEnd = extraItem.fragmentEnd; + } + else + { + fragmentStart = 0; + fragmentEnd = item.size; + } + totalSize += fragmentEnd - fragmentStart; + current = item.next; + if (current == end) + { + break; + } + } + return totalSize; +} + void -PacketHistory::Print (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const +PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printer) const { if (!m_enable) { return; } - + if (m_data == 0) + { + return; + } + NS_ASSERT (GetTotalSize () == data.GetSize ()); + if (printer.m_forward) + { + uint32_t end = m_end; + uint32_t begin = m_begin; + uint32_t current = begin; + uint32_t offset = 0; + while (current != 0xffff) + { + uint8_t *buffer = &m_data->m_data[current]; + struct PacketHistory::SmallItem item; + uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os); + offset += realSize; + current = item.next; + if (current == end) + { + break; + } + } + } + else + { + uint32_t end = m_begin; + uint32_t begin = m_end; + uint32_t current = begin; + uint32_t offset = 0; + while (current != 0xffff) + { + uint8_t *buffer = &m_data->m_data[current]; + struct PacketHistory::SmallItem item; + uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os); + offset -= realSize; + current = item.prev; + if (current == end) + { + break; + } + } + } } @@ -1117,8 +1263,8 @@ PacketHistoryTest::RegisterHeader (void) static bool registered = false; if (!registered) { - m_printer.AddPrinter (MakeCallback (&PacketHistoryTest::PrintHeader, this), - MakeCallback (&PacketHistoryTest::PrintFragment, this)); + m_printer.AddHeaderPrinter (MakeCallback (&PacketHistoryTest::PrintHeader, this), + MakeCallback (&PacketHistoryTest::PrintFragment, this)); registered = true; } } @@ -1130,8 +1276,8 @@ PacketHistoryTest::RegisterTrailer (void) static bool registered = false; if (!registered) { - m_printer.AddPrinter (MakeCallback (&PacketHistoryTest::PrintTrailer, this), - MakeCallback (&PacketHistoryTest::PrintFragment, this)); + m_printer.AddTrailerPrinter (MakeCallback (&PacketHistoryTest::PrintTrailer, this), + MakeCallback (&PacketHistoryTest::PrintFragment, this)); registered = true; } } diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 5e4fc0f33..579522a6e 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -96,15 +96,19 @@ private: void AddSmall (bool atStart, uint32_t typeUid, uint32_t size); uint32_t GetUleb128Size (uint32_t value) const; - uint32_t ReadUleb128 (uint8_t **pBuffer) const; + uint32_t ReadUleb128 (const uint8_t **pBuffer) const; void Append16 (uint16_t value, uint8_t **pBuffer); bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); - bool IsZero16 (uint16_t index); + bool IsFF16 (uint16_t index); bool CanAdd (bool atStart); - void ReadSmall (struct PacketHistory::SmallItem *item, uint8_t **pBuffer); - void ReadExtra (struct PacketHistory::ExtraItem *item, uint8_t **pBuffer); + void ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const; + void ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const; void Reserve (uint32_t n); void ReserveCopy (uint32_t n); + uint32_t DoPrint (struct PacketHistory::SmallItem *item, uint8_t const*buffer, + Buffer data, uint32_t offset, const PacketPrinter &printer, + std::ostream &os) const; + uint32_t GetTotalSize (void) const; static struct PacketHistory::Data *Create (uint32_t size); static void Recycle (struct PacketHistory::Data *data); @@ -131,26 +135,26 @@ template void PacketHistory::AddHeader (T const &header, uint32_t size) { - AddHeader (PacketPrinter::GetUid (), header, size); + AddHeader (PacketPrinter::GetHeaderUid (), header, size); } template void PacketHistory::RemoveHeader (T const &header, uint32_t size) { - RemoveHeader (PacketPrinter::GetUid (), header, size); + RemoveHeader (PacketPrinter::GetHeaderUid (), header, size); } template void PacketHistory::AddTrailer (T const &trailer, uint32_t size) { - AddTrailer (PacketPrinter::GetUid (), trailer, size); + AddTrailer (PacketPrinter::GetTrailerUid (), trailer, size); } template void PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) { - RemoveTrailer (PacketPrinter::GetUid (), trailer, size); + RemoveTrailer (PacketPrinter::GetTrailerUid (), trailer, size); } }; // namespace ns3 diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index ed04c4761..1d3a94592 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -87,12 +87,12 @@ PacketPrinter::PrintChunk (uint32_t chunkUid, { if (i->m_chunkUid == chunkUid) { - DoPrintCallback cb = (*registeredChunks)[chunkUid-1].first; + DoPrintCallback cb = (*registeredChunks)[chunkUid/2-1].printCallback; cb (i->m_printer, start, os, packetUid, size); return; } } - DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].second; + DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].getNameCallback; std::string name = cb (); struct PacketPrinter::FragmentInformation info; info.start = 0; @@ -109,7 +109,7 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid, { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); NS_ASSERT (chunkUid >= 1); - DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].second; + DoGetNameCallback cb = (*registeredChunks)[chunkUid/2-1].getNameCallback; std::string name = cb (); struct PacketPrinter::FragmentInformation info; info.start = fragmentStart; @@ -186,5 +186,23 @@ PacketPrinter::DoAddPrinter (uint32_t uid, m_printerList.push_back (p); } +bool +PacketPrinter::IsTrailer (uint32_t uid) +{ + RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); + NS_ASSERT (uid >= 1 && uid/2 < registeredChunks->size ()); + bool isHeader = (*registeredChunks)[uid/2-1].isHeader; + return !isHeader; +} +bool +PacketPrinter::IsHeader (uint32_t uid) +{ + RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); + NS_ASSERT (uid >= 1 && uid/2 < registeredChunks->size ()); + bool isHeader = (*registeredChunks)[uid/2-1].isHeader; + return isHeader; +} + + } // namespace ns3 diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index fbea25d26..416bcc7de 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -85,8 +85,15 @@ public: * \param fragmentPrinter printer for a fragment of the specified chunk */ template - void AddPrinter (Callback printer, - ChunkFragmentPrinter fragmentPrinter); + void AddHeaderPrinter (Callback printer, + ChunkFragmentPrinter fragmentPrinter); + /** + * \param printer printer for the specified chunk + * \param fragmentPrinter printer for a fragment of the specified chunk + */ + template + void AddTrailerPrinter (Callback printer, + ChunkFragmentPrinter fragmentPrinter); /** * \param printer printer for a chunk for which no callback was specified explicitely */ @@ -95,6 +102,9 @@ public: private: friend class PacketHistory; friend class ::ItemList; + typedef void (*DoPrintCallback) (Ptr, Buffer::Iterator, std::ostream &, + uint32_t, uint32_t); + typedef std::string (*DoGetNameCallback) (void); struct Printer { uint32_t m_chunkUid; @@ -102,11 +112,14 @@ private: Callback m_fragmentPrinter; }; - typedef void (*DoPrintCallback) (Ptr, Buffer::Iterator, std::ostream &, - uint32_t, uint32_t); - typedef std::string (*DoGetNameCallback) (void); + struct RegisteredChunk + { + DoPrintCallback printCallback; + DoGetNameCallback getNameCallback; + bool isHeader; + }; typedef std::vector PrinterList; - typedef std::vector > RegisteredChunks; + typedef std::vector RegisteredChunks; static PacketPrinter GetDefault (void); @@ -138,10 +151,14 @@ private: template static std::string DoGetName (void); template - static uint32_t GetUid (void); + static uint32_t GetTrailerUid (void); template - static uint32_t AllocateUid (void); + static uint32_t GetHeaderUid (void); + template + static uint32_t AllocateUid (bool isHeader); static RegisteredChunks *GetRegisteredChunks (void); + static bool IsTrailer (uint32_t uid); + static bool IsHeader (uint32_t uid); void PrintChunk (uint32_t uid, @@ -179,7 +196,7 @@ namespace ns3 { template void -PacketPrinter::AddPrinter (Callback printer, +PacketPrinter::AddHeaderPrinter (Callback printer, Callback fragmentPrinter) { - static uint32_t uid = PacketPrinter::GetUid (); + static uint32_t uid = PacketPrinter::GetHeaderUid (); + DoAddPrinter (uid, printer.GetImpl (), fragmentPrinter); +} + +template +void +PacketPrinter::AddTrailerPrinter (Callback printer, + Callback fragmentPrinter) +{ + static uint32_t uid = PacketPrinter::GetTrailerUid (); DoAddPrinter (uid, printer.GetImpl (), fragmentPrinter); } @@ -216,20 +247,31 @@ PacketPrinter::DoGetName (void) template uint32_t -PacketPrinter::GetUid (void) +PacketPrinter::GetHeaderUid (void) { - static uint32_t uid = PacketPrinter::AllocateUid (); + static uint32_t uid = PacketPrinter::AllocateUid (true); + return uid; +} + +template +uint32_t +PacketPrinter::GetTrailerUid (void) +{ + static uint32_t uid = PacketPrinter::AllocateUid (false); return uid; } template uint32_t -PacketPrinter::AllocateUid (void) +PacketPrinter::AllocateUid (bool isHeader) { RegisteredChunks *chunks = PacketPrinter::GetRegisteredChunks (); - chunks->push_back (std::make_pair(&PacketPrinter::DoPrint, - &PacketPrinter::DoGetName)); - uint32_t uid = chunks->size (); + RegisteredChunk chunk; + chunk.printCallback = &PacketPrinter::DoPrint; + chunk.getNameCallback = &PacketPrinter::DoGetName; + chunk.isHeader = isHeader; + chunks->push_back (chunk); + uint32_t uid = chunks->size () * 2; PacketPrinter::PeekDefault ()->DoAddPrinter (uid, MakeCallback (&PacketPrinter::DoDefaultPrint).GetImpl (), MakeCallback (&PacketPrinter::DoDefaultPrintFragment)); From d5e147d400aafce96ddd568026918222b6400914 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 15:59:07 +0200 Subject: [PATCH 048/116] deal with packet with zero headers correctly --- src/common/packet-history.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 60ab5efcf..bea6be0f5 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -548,11 +548,16 @@ PacketHistory::IsFF16 (uint16_t index) bool PacketHistory::CanAdd (bool atStart) { - if (atStart && m_begin != 0xffff) + if (m_begin == 0xffff) + { + NS_ASSERT (m_end == 0xffff); + return true; + } + if (atStart) { return IsFF16 (m_begin+2); } - else if (!atStart && m_end != 0xffff) + else if (!atStart) { return IsFF16 (m_end); } From bd1dcf3f9778b672927c107be0c8e8b1d1426b00 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 16:33:45 +0200 Subject: [PATCH 049/116] fix field ordering. --- src/common/packet-history.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index bea6be0f5..b69485c82 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -603,8 +603,8 @@ PacketHistory::AddSmall (bool atStart, Append16 (next, &buffer); Append16 (prev, &buffer); if (TryToAppend (typeUid, &buffer, end) && - TryToAppend (chunkUid, &buffer, end) && - TryToAppend (size, &buffer, end)) + TryToAppend (size, &buffer, end) && + TryToAppend (chunkUid, &buffer, end)) { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); @@ -616,10 +616,20 @@ PacketHistory::AddSmall (bool atStart, } else if (atStart) { + NS_ASSERT (m_begin != 0xffff); + // overwrite the prev field of the previous head of the list. + uint8_t *previousHead = &m_data->m_data[m_begin] + 2; + Append16 (m_used, &previousHead); + // update the head of list to the new node. m_begin = m_used; } else { + NS_ASSERT (m_end != 0xffff); + // overwrite the next field of the previous tail of the list. + uint8_t *previousTail = &m_data->m_data[m_end]; + Append16 (m_used, &previousTail); + // update the tail of the list to the new node. m_end = m_used; } NS_ASSERT (m_end != 0xffff); @@ -631,8 +641,8 @@ PacketHistory::AddSmall (bool atStart, } uint32_t n = GetUleb128Size (typeUid); - n += GetUleb128Size (chunkUid); n += GetUleb128Size (size); + n += GetUleb128Size (chunkUid); n += 2 + 2; ReserveCopy (n); goto append; @@ -793,7 +803,7 @@ PacketHistory::AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) { return; } - AddSmall (true, uid, size); + AddSmall (false, uid, size); } void PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) From ebfe75384cc5b6302ec2165facc78b3fd4023e20 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 16:36:53 +0200 Subject: [PATCH 050/116] rename begin to head and end to tail --- src/common/packet-history.cc | 86 ++++++++++++++++++------------------ src/common/packet-history.h | 4 +- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index b69485c82..cf849dc93 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -331,8 +331,8 @@ PacketHistory::Enable (void) PacketHistory::PacketHistory (uint32_t uid, uint32_t size) : m_data (0), - m_begin (0xffff), - m_end (0xffff), + m_head (0xffff), + m_tail (0xffff), m_used (0), m_packetUid (uid) { @@ -343,8 +343,8 @@ PacketHistory::PacketHistory (uint32_t uid, uint32_t size) } PacketHistory::PacketHistory (PacketHistory const &o) : m_data (o.m_data), - m_begin (o.m_begin), - m_end (o.m_end), + m_head (o.m_head), + m_tail (o.m_tail), m_used (o.m_used), m_packetUid (o.m_packetUid) { @@ -370,8 +370,8 @@ PacketHistory::operator = (PacketHistory const& o) } } m_data = o.m_data; - m_begin = o.m_begin; - m_end = o.m_end; + m_head = o.m_head; + m_tail = o.m_tail; m_used = o.m_used; m_packetUid = o.m_packetUid; if (m_data != 0) @@ -548,18 +548,18 @@ PacketHistory::IsFF16 (uint16_t index) bool PacketHistory::CanAdd (bool atStart) { - if (m_begin == 0xffff) + if (m_head == 0xffff) { - NS_ASSERT (m_end == 0xffff); + NS_ASSERT (m_tail == 0xffff); return true; } if (atStart) { - return IsFF16 (m_begin+2); + return IsFF16 (m_head+2); } else if (!atStart) { - return IsFF16 (m_end); + return IsFF16 (m_tail); } else { @@ -591,13 +591,13 @@ PacketHistory::AddSmall (bool atStart, uint16_t next, prev; if (atStart) { - next = m_begin; + next = m_head; prev = 0xffff; } else { next = 0xffff; - prev = m_end; + prev = m_tail; } Append16 (next, &buffer); @@ -608,32 +608,32 @@ PacketHistory::AddSmall (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); - if (m_begin == 0xffff) + if (m_head == 0xffff) { - NS_ASSERT (m_end == 0xffff); - m_begin = m_used; - m_end = m_used; + NS_ASSERT (m_tail == 0xffff); + m_head = m_used; + m_tail = m_used; } else if (atStart) { - NS_ASSERT (m_begin != 0xffff); + NS_ASSERT (m_head != 0xffff); // overwrite the prev field of the previous head of the list. - uint8_t *previousHead = &m_data->m_data[m_begin] + 2; + uint8_t *previousHead = &m_data->m_data[m_head] + 2; Append16 (m_used, &previousHead); // update the head of list to the new node. - m_begin = m_used; + m_head = m_used; } else { - NS_ASSERT (m_end != 0xffff); + NS_ASSERT (m_tail != 0xffff); // overwrite the next field of the previous tail of the list. - uint8_t *previousTail = &m_data->m_data[m_end]; + uint8_t *previousTail = &m_data->m_data[m_tail]; Append16 (m_used, &previousTail); // update the tail of the list to the new node. - m_end = m_used; + m_tail = m_used; } - NS_ASSERT (m_end != 0xffff); - NS_ASSERT (m_begin != 0xffff); + NS_ASSERT (m_tail != 0xffff); + NS_ASSERT (m_head != 0xffff); m_used += written; m_data->m_dirtyEnd = m_used; return; @@ -770,7 +770,7 @@ PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) NS_FATAL_ERROR ("Removing header from empty packet."); } struct PacketHistory::SmallItem item; - const uint8_t *buffer = &m_data->m_data[m_begin]; + const uint8_t *buffer = &m_data->m_data[m_head]; ReadSmall (&item, &buffer); NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); if ((item.typeUid & 0xfffffffd) != uid || @@ -790,10 +790,10 @@ PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) NS_FATAL_ERROR ("Removing incomplete header."); } } - m_begin = item.next; - if (m_begin > m_end) + m_head = item.next; + if (m_head > m_tail) { - m_used = m_begin; + m_used = m_head; } } void @@ -817,7 +817,7 @@ PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size NS_FATAL_ERROR ("Removing trailer from empty packet."); } struct PacketHistory::SmallItem item; - const uint8_t *buffer = &m_data->m_data[m_end]; + const uint8_t *buffer = &m_data->m_data[m_tail]; ReadSmall (&item, &buffer); NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); if ((item.typeUid & 0xfffffffd) != uid || @@ -837,10 +837,10 @@ PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size NS_FATAL_ERROR ("Removing incomplete trailer."); } } - m_end = item.prev; - if (m_end > m_begin) + m_tail = item.prev; + if (m_tail > m_head) { - m_used = m_end; + m_used = m_tail; } } void @@ -872,7 +872,7 @@ PacketHistory::RemoveAtStart (uint32_t start) NS_FATAL_ERROR ("Removing header from empty packet."); } struct PacketHistory::SmallItem item; - uint8_t *buffer = &m_data->m_data[m_begin]; + uint8_t *buffer = &m_data->m_data[m_head]; bool ok = ReadSmall (&item, &buffer); NS_ASSERT (ok); if ((item.typeUid & 0xfffffffd) != uid || @@ -990,8 +990,8 @@ uint32_t PacketHistory::GetTotalSize (void) const { uint32_t totalSize = 0; - uint16_t current = m_begin; - uint16_t end = m_end; + uint16_t current = m_head; + uint16_t end = m_tail; while (current != 0xffff) { const uint8_t *buffer = &m_data->m_data[current]; @@ -1035,9 +1035,9 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe NS_ASSERT (GetTotalSize () == data.GetSize ()); if (printer.m_forward) { - uint32_t end = m_end; - uint32_t begin = m_begin; - uint32_t current = begin; + uint32_t tail = m_tail; + uint32_t head = m_head; + uint32_t current = head; uint32_t offset = 0; while (current != 0xffff) { @@ -1046,7 +1046,7 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os); offset += realSize; current = item.next; - if (current == end) + if (current == tail) { break; } @@ -1054,9 +1054,9 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe } else { - uint32_t end = m_begin; - uint32_t begin = m_end; - uint32_t current = begin; + uint32_t head = m_head; + uint32_t tail = m_tail; + uint32_t current = head; uint32_t offset = 0; while (current != 0xffff) { @@ -1065,7 +1065,7 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os); offset -= realSize; current = item.prev; - if (current == end) + if (current == tail) { break; } diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 579522a6e..c22cb5961 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -121,8 +121,8 @@ private: static uint16_t m_chunkUid; struct Data *m_data; - uint16_t m_begin; - uint16_t m_end; + uint16_t m_head; + uint16_t m_tail; uint16_t m_used; uint32_t m_packetUid; }; From c3ff0ad5848f0ecd1c79092f8f96a04eb6382546 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 16:40:05 +0200 Subject: [PATCH 051/116] fix the list iteration logic --- src/common/packet-history.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index cf849dc93..7d250f361 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -991,7 +991,7 @@ PacketHistory::GetTotalSize (void) const { uint32_t totalSize = 0; uint16_t current = m_head; - uint16_t end = m_tail; + uint16_t tail = m_tail; while (current != 0xffff) { const uint8_t *buffer = &m_data->m_data[current]; @@ -1012,11 +1012,11 @@ PacketHistory::GetTotalSize (void) const fragmentEnd = item.size; } totalSize += fragmentEnd - fragmentStart; - current = item.next; - if (current == end) + if (current == tail) { break; } + current = item.next; } return totalSize; } @@ -1045,11 +1045,11 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe struct PacketHistory::SmallItem item; uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os); offset += realSize; - current = item.next; if (current == tail) { break; } + current = item.next; } } else @@ -1064,11 +1064,11 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe struct PacketHistory::SmallItem item; uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os); offset -= realSize; - current = item.prev; if (current == tail) { break; } + current = item.prev; } } } From 3634046dc76159a765594425c513546cbcab6845 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 17:35:22 +0200 Subject: [PATCH 052/116] fix a bunch of buggy asserts --- src/common/packet-history.cc | 10 +++++----- src/common/packet-printer.cc | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 7d250f361..5fd1d2600 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -772,7 +772,7 @@ PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) struct PacketHistory::SmallItem item; const uint8_t *buffer = &m_data->m_data[m_head]; ReadSmall (&item, &buffer); - NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); if ((item.typeUid & 0xfffffffd) != uid || item.size != size) { @@ -783,7 +783,7 @@ PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) // this is a "big" item struct PacketHistory::ExtraItem extraItem; ReadExtra (&extraItem, &buffer); - NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); if (extraItem.fragmentStart != 0 || extraItem.fragmentEnd != size) { @@ -819,7 +819,7 @@ PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size struct PacketHistory::SmallItem item; const uint8_t *buffer = &m_data->m_data[m_tail]; ReadSmall (&item, &buffer); - NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); if ((item.typeUid & 0xfffffffd) != uid || item.size != size) { @@ -830,7 +830,7 @@ PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size // this is a "big" item struct PacketHistory::ExtraItem extraItem; ReadExtra (&extraItem, &buffer); - NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); if (extraItem.fragmentStart != 0 || extraItem.fragmentEnd != size) { @@ -953,7 +953,7 @@ PacketHistory::DoPrint (struct PacketHistory::SmallItem *item, uint8_t const*buf fragmentEnd = item->size; packetUid = m_packetUid; } - NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]); + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); if (uid == 0) { // payload. diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 1d3a94592..97c5a28f2 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -82,7 +82,7 @@ PacketPrinter::PrintChunk (uint32_t chunkUid, uint32_t size) const { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); - NS_ASSERT (chunkUid >= 1); + NS_ASSERT (chunkUid >= 1 && chunkUid/2 <= registeredChunks->size ()); for (PrinterList::const_iterator i = m_printerList.begin (); i != m_printerList.end (); i++) { if (i->m_chunkUid == chunkUid) @@ -92,7 +92,7 @@ PacketPrinter::PrintChunk (uint32_t chunkUid, return; } } - DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].getNameCallback; + DoGetNameCallback cb = (*registeredChunks)[chunkUid/2-1].getNameCallback; std::string name = cb (); struct PacketPrinter::FragmentInformation info; info.start = 0; @@ -108,7 +108,7 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid, uint32_t fragmentEnd) const { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); - NS_ASSERT (chunkUid >= 1); + NS_ASSERT (chunkUid >= 1 && chunkUid/2 <= registeredChunks->size ()); DoGetNameCallback cb = (*registeredChunks)[chunkUid/2-1].getNameCallback; std::string name = cb (); struct PacketPrinter::FragmentInformation info; @@ -190,7 +190,7 @@ bool PacketPrinter::IsTrailer (uint32_t uid) { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); - NS_ASSERT (uid >= 1 && uid/2 < registeredChunks->size ()); + NS_ASSERT (uid >= 1 && uid/2 <= registeredChunks->size ()); bool isHeader = (*registeredChunks)[uid/2-1].isHeader; return !isHeader; } @@ -198,7 +198,7 @@ bool PacketPrinter::IsHeader (uint32_t uid) { RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks (); - NS_ASSERT (uid >= 1 && uid/2 < registeredChunks->size ()); + NS_ASSERT (uid >= 1 && uid/2 <= registeredChunks->size ()); bool isHeader = (*registeredChunks)[uid/2-1].isHeader; return isHeader; } From 969ff1267e56c5a7118c214e1f47c96428171655 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 18:28:37 +0200 Subject: [PATCH 053/116] the mask to filter out the low bit is 0xfe, not 0xfd --- src/common/packet-history.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 5fd1d2600..c8be8f6d2 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -773,7 +773,7 @@ PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) const uint8_t *buffer = &m_data->m_data[m_head]; ReadSmall (&item, &buffer); NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); - if ((item.typeUid & 0xfffffffd) != uid || + if ((item.typeUid & 0xfffffffe) != uid || item.size != size) { NS_FATAL_ERROR ("Removing unexpected header."); @@ -820,7 +820,7 @@ PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size const uint8_t *buffer = &m_data->m_data[m_tail]; ReadSmall (&item, &buffer); NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); - if ((item.typeUid & 0xfffffffd) != uid || + if ((item.typeUid & 0xfffffffe) != uid || item.size != size) { NS_FATAL_ERROR ("Removing unexpected trailer."); @@ -875,7 +875,7 @@ PacketHistory::RemoveAtStart (uint32_t start) uint8_t *buffer = &m_data->m_data[m_head]; bool ok = ReadSmall (&item, &buffer); NS_ASSERT (ok); - if ((item.typeUid & 0xfffffffd) != uid || + if ((item.typeUid & 0xfffffffe) != uid || item.size != size) { NS_FATAL_ERROR ("Removing unexpected header."); @@ -936,7 +936,7 @@ PacketHistory::DoPrint (struct PacketHistory::SmallItem *item, uint8_t const*buf { ReadSmall (item, &buffer); bool isExtra = (item->typeUid & 0x1) == 0x1; - uint32_t uid = item->typeUid & 0xfffffffd; + uint32_t uid = item->typeUid & 0xfffffffe; uint32_t fragmentStart, fragmentEnd; uint32_t packetUid; if (isExtra) From 1bbf7ce1a27f3839adbe5299e2ac1375a59776fd Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 5 Jun 2007 21:48:26 +0200 Subject: [PATCH 054/116] when doing a copy of a buffer, make sure to clear the prev and next fields --- src/common/packet-history.cc | 11 +++++++++++ src/common/packet-history.h | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index c8be8f6d2..28a5ae4d8 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -404,6 +404,17 @@ PacketHistory::ReserveCopy (uint32_t size) PacketHistory::Recycle (m_data); } m_data = newData; + if (m_head != 0xffff) + { + uint8_t *start; + NS_ASSERT (m_tail != 0xffff); + // clear the next field of the tail + start = &m_data->m_data[m_tail]; + Append16 (0xffff, &start); + // clear the prev field of the head + start = &m_data->m_data[m_head] + 2; + Append16 (0xffff, &start); + } } void PacketHistory::Reserve (uint32_t size) diff --git a/src/common/packet-history.h b/src/common/packet-history.h index c22cb5961..3653cb742 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -66,6 +66,11 @@ public: static void PrintStats (void); private: + /** + head -(next)-> tail + ^ | + \---(prev)---| + */ struct Data { uint16_t m_count; uint16_t m_size; From 6816e303eca5470c96545c048120c58de24f25eb Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 08:49:15 +0200 Subject: [PATCH 055/116] implement PacketHistory::RemoveAtStart --- src/common/packet-history.cc | 154 +++++++++++++++++++++++++++++++++-- src/common/packet-history.h | 3 + 2 files changed, 149 insertions(+), 8 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 28a5ae4d8..eac8c8377 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -659,6 +659,91 @@ PacketHistory::AddSmall (bool atStart, goto append; } +void +PacketHistory::AddBig (bool atStart, + const PacketHistory::SmallItem *item, + const PacketHistory::ExtraItem *extraItem) +{ + if (m_data == 0) + { + m_data = PacketHistory::Create (10); + memset (m_data->m_data, 0xff, 4); + } + NS_ASSERT (m_data != 0); + append: + uint8_t *start = &m_data->m_data[m_used]; + uint8_t *end = &m_data->m_data[m_data->m_size]; + if (end - start >= 13 && + CanAdd (atStart) && + (m_data->m_count == 1 || + m_used == m_data->m_dirtyEnd)) + { + uint8_t *buffer = start; + uint16_t next, prev; + if (atStart) + { + next = m_head; + prev = 0xffff; + } + else + { + next = 0xffff; + prev = m_tail; + } + + Append16 (next, &buffer); + Append16 (prev, &buffer); + if (TryToAppend (item->typeUid, &buffer, end) && + TryToAppend (item->size, &buffer, end) && + TryToAppend (item->chunkUid, &buffer, end) && + TryToAppend (extraItem->fragmentStart, &buffer, end) && + TryToAppend (extraItem->fragmentEnd, &buffer, end) && + TryToAppend (extraItem->packetUid, &buffer, end)) + { + uintptr_t written = buffer - start; + NS_ASSERT (written <= 0xffff); + if (m_head == 0xffff) + { + NS_ASSERT (m_tail == 0xffff); + m_head = m_used; + m_tail = m_used; + } + else if (atStart) + { + NS_ASSERT (m_head != 0xffff); + // overwrite the prev field of the previous head of the list. + uint8_t *previousHead = &m_data->m_data[m_head] + 2; + Append16 (m_used, &previousHead); + // update the head of list to the new node. + m_head = m_used; + } + else + { + NS_ASSERT (m_tail != 0xffff); + // overwrite the next field of the previous tail of the list. + uint8_t *previousTail = &m_data->m_data[m_tail]; + Append16 (m_used, &previousTail); + // update the tail of the list to the new node. + m_tail = m_used; + } + NS_ASSERT (m_tail != 0xffff); + NS_ASSERT (m_head != 0xffff); + m_used += written; + m_data->m_dirtyEnd = m_used; + return; + } + } + + uint32_t n = GetUleb128Size (item->typeUid); + n += GetUleb128Size (item->size); + n += GetUleb128Size (item->chunkUid); + n += 2 + 2; + ReserveCopy (n); + goto append; + +} + + void PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const { @@ -877,15 +962,60 @@ PacketHistory::RemoveAtStart (uint32_t start) { return; } -#if 0 if (m_data == 0) { - NS_FATAL_ERROR ("Removing header from empty packet."); + NS_FATAL_ERROR ("Removing data from start of empty packet."); } + + uint32_t leftToRemove = start; + uint16_t current = m_head; + uint16_t tail = m_tail; + while (current != 0xffff) + { + const uint8_t *buffer = &m_data->m_data[current]; + struct PacketHistory::SmallItem item; + ReadSmall (&item, &buffer); + bool isExtra = (item.typeUid & 0x1) == 0x1; + PacketHistory::ExtraItem extraItem; + if (isExtra) + { + ReadExtra (&extraItem, &buffer); + } + else + { + extraItem.fragmentStart = 0; + extraItem.fragmentEnd = item.size; + extraItem.packetUid = m_packetUid; + } + uint32_t itemRealSize = extraItem.fragmentEnd - extraItem.fragmentStart; + if (itemRealSize <= leftToRemove) + { + // remove from list. + m_head = item.next; + leftToRemove -= itemRealSize; + } + else + { + // fragment the list item. + PacketHistory fragment (m_packetUid, 0); + extraItem.fragmentStart += leftToRemove; + leftToRemove = 0; + fragment.AddBig (false, &item, &extraItem); + NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart && + extraItem.fragmentStart <= extraItem.fragmentEnd); + } + if (current == tail) + { + break; + } + current = item.next; + } + NS_ASSERT (leftToRemove == 0); +#if 0 struct PacketHistory::SmallItem item; - uint8_t *buffer = &m_data->m_data[m_head]; - bool ok = ReadSmall (&item, &buffer); - NS_ASSERT (ok); + const uint8_t *buffer = &m_data->m_data[m_head]; + ReadSmall (&item, &buffer); + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); if ((item.typeUid & 0xfffffffe) != uid || item.size != size) { @@ -895,14 +1025,19 @@ PacketHistory::RemoveAtStart (uint32_t start) { // this is a "big" item struct PacketHistory::ExtraItem extraItem; - ok = ReadExtra (&extraItem, &buffer); - NS_ASSERT (ok); + ReadExtra (&extraItem, &buffer); + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); if (extraItem.fragmentStart != 0 || extraItem.fragmentEnd != size) { NS_FATAL_ERROR ("Removing incomplete header."); } } + m_head = item.next; + if (m_head > m_tail) + { + m_used = m_head; + } uint32_t leftToRemove = start; while (!m_itemList.empty () && leftToRemove > 0) @@ -1545,7 +1680,10 @@ PacketHistoryTest::RunTests (void) p1.RemoveAtStart (3); CHECK_HISTORY (p1, 4, 2, 1, 10, 4); - p1.RemoveAtStart (2); + p1.RemoveAtStart (1); + CHECK_HISTORY (p1, 4, + 1, 1, 10, 4); + p1.RemoveAtStart (1); CHECK_HISTORY (p1, 3, 1, 10, 4); p1.RemoveAtEnd (4); diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 3653cb742..f66eaf604 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -100,6 +100,9 @@ private: void AddSmall (bool atStart, uint32_t typeUid, uint32_t size); + void AddBig (bool atStart, + const PacketHistory::SmallItem *item, + const PacketHistory::ExtraItem *extraItem); uint32_t GetUleb128Size (uint32_t value) const; uint32_t ReadUleb128 (const uint8_t **pBuffer) const; void Append16 (uint16_t value, uint8_t **pBuffer); From aabed928b1f07f607f4c2f0e8ed16b03d305e766 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 08:54:11 +0200 Subject: [PATCH 056/116] make sure that we set the low bit for typeUid when writing a 'big' item --- src/common/packet-history.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index eac8c8377..7e720893a 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -693,7 +693,7 @@ PacketHistory::AddBig (bool atStart, Append16 (next, &buffer); Append16 (prev, &buffer); - if (TryToAppend (item->typeUid, &buffer, end) && + if (TryToAppend (item->typeUid+1, &buffer, end) && TryToAppend (item->size, &buffer, end) && TryToAppend (item->chunkUid, &buffer, end) && TryToAppend (extraItem->fragmentStart, &buffer, end) && @@ -734,7 +734,7 @@ PacketHistory::AddBig (bool atStart, } } - uint32_t n = GetUleb128Size (item->typeUid); + uint32_t n = GetUleb128Size (item->typeUid+1); n += GetUleb128Size (item->size); n += GetUleb128Size (item->chunkUid); n += 2 + 2; From 3e511d14572af8c52f823b12816d8c355e88e760 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 09:13:21 +0200 Subject: [PATCH 057/116] rewrite PacketHistory::RemoveAtstart --- src/common/packet-history.cc | 53 +++++++++++++++++++++++++----------- src/common/packet-history.h | 4 +++ 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 7e720893a..264109cad 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -758,6 +758,27 @@ PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t * item->chunkUid = ReadUleb128 (pBuffer); } +void +PacketHistory::ReadItems (uint16_t current, + struct PacketHistory::SmallItem *item, + struct PacketHistory::ExtraItem *extraItem) const +{ + const uint8_t *buffer = &m_data->m_data[current]; + ReadSmall (item, &buffer); + bool isExtra = (item->typeUid & 0x1) == 0x1; + if (isExtra) + { + ReadExtra (extraItem, &buffer); + } + else + { + extraItem->fragmentStart = 0; + extraItem->fragmentEnd = item->size; + extraItem->packetUid = m_packetUid; + } +} + + void PacketHistory::ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const { @@ -970,23 +991,11 @@ PacketHistory::RemoveAtStart (uint32_t start) uint32_t leftToRemove = start; uint16_t current = m_head; uint16_t tail = m_tail; - while (current != 0xffff) + while (current != 0xffff && leftToRemove > 0) { - const uint8_t *buffer = &m_data->m_data[current]; struct PacketHistory::SmallItem item; - ReadSmall (&item, &buffer); - bool isExtra = (item.typeUid & 0x1) == 0x1; PacketHistory::ExtraItem extraItem; - if (isExtra) - { - ReadExtra (&extraItem, &buffer); - } - else - { - extraItem.fragmentStart = 0; - extraItem.fragmentEnd = item.size; - extraItem.packetUid = m_packetUid; - } + ReadItems (current, &item, &extraItem); uint32_t itemRealSize = extraItem.fragmentEnd - extraItem.fragmentStart; if (itemRealSize <= leftToRemove) { @@ -1001,9 +1010,21 @@ PacketHistory::RemoveAtStart (uint32_t start) extraItem.fragmentStart += leftToRemove; leftToRemove = 0; fragment.AddBig (false, &item, &extraItem); - NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart && - extraItem.fragmentStart <= extraItem.fragmentEnd); + current = item.next; + while (current != 0xffff) + { + ReadItems (current, &item, &extraItem); + fragment.AddBig (false, &item, &extraItem); + if (current == tail) + { + break; + } + current = item.next; + } + *this = fragment; } + NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart && + extraItem.fragmentStart <= extraItem.fragmentEnd); if (current == tail) { break; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index f66eaf604..dc4f8d881 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -117,6 +117,10 @@ private: Buffer data, uint32_t offset, const PacketPrinter &printer, std::ostream &os) const; uint32_t GetTotalSize (void) const; + void ReadItems (uint16_t current, + struct PacketHistory::SmallItem *item, + struct PacketHistory::ExtraItem *extraItem) const; + static struct PacketHistory::Data *Create (uint32_t size); static void Recycle (struct PacketHistory::Data *data); From e829515b02792d8d54329f9497389098eb0af34b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 09:23:47 +0200 Subject: [PATCH 058/116] fix fragment printing --- src/common/packet-history.cc | 50 ++++++++++++------------------------ src/common/packet-history.h | 2 +- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 264109cad..26decfcf0 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -776,6 +776,7 @@ PacketHistory::ReadItems (uint16_t current, extraItem->fragmentEnd = item->size; extraItem->packetUid = m_packetUid; } + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); } @@ -1097,60 +1098,43 @@ PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const } uint32_t -PacketHistory::DoPrint (struct PacketHistory::SmallItem *item, uint8_t const*buffer, +PacketHistory::DoPrint (struct PacketHistory::SmallItem *item, uint32_t current, Buffer data, uint32_t offset, const PacketPrinter &printer, std::ostream &os) const { - ReadSmall (item, &buffer); - bool isExtra = (item->typeUid & 0x1) == 0x1; + PacketHistory::ExtraItem extraItem; + ReadItems (current, item, &extraItem); uint32_t uid = item->typeUid & 0xfffffffe; - uint32_t fragmentStart, fragmentEnd; - uint32_t packetUid; - if (isExtra) - { - PacketHistory::ExtraItem extraItem; - ReadExtra (&extraItem, &buffer); - fragmentStart = extraItem.fragmentStart; - fragmentEnd = extraItem.fragmentEnd; - packetUid = extraItem.packetUid; - } - else - { - fragmentStart = 0; - fragmentEnd = item->size; - packetUid = m_packetUid; - } - NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); if (uid == 0) { // payload. - printer.PrintPayload (os, packetUid, item->size, - fragmentStart, - fragmentEnd); + printer.PrintPayload (os, extraItem.packetUid, item->size, + extraItem.fragmentStart, + extraItem.fragmentEnd); } - else if (fragmentStart != 0 && - fragmentEnd != item->size) + else if (extraItem.fragmentStart != 0 || + extraItem.fragmentEnd != item->size) { - printer.PrintChunkFragment (uid, os, packetUid, item->size, - fragmentStart, fragmentEnd); + printer.PrintChunkFragment (uid, os, extraItem.packetUid, item->size, + extraItem.fragmentStart, extraItem.fragmentEnd); } else if (PacketPrinter::IsHeader (uid)) { ns3::Buffer::Iterator j = data.Begin (); j.Next (offset); - printer.PrintChunk (uid, j, os, packetUid, item->size); + printer.PrintChunk (uid, j, os, extraItem.packetUid, item->size); } else if (PacketPrinter::IsTrailer (uid)) { ns3::Buffer::Iterator j = data.End (); j.Prev (data.GetSize () - (offset + item->size)); - printer.PrintChunk (uid, j, os, packetUid, item->size); + printer.PrintChunk (uid, j, os, extraItem.packetUid, item->size); } else { NS_ASSERT (false); } - return fragmentEnd - fragmentStart; + return extraItem.fragmentEnd - extraItem.fragmentStart; } uint32_t @@ -1208,9 +1192,8 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe uint32_t offset = 0; while (current != 0xffff) { - uint8_t *buffer = &m_data->m_data[current]; struct PacketHistory::SmallItem item; - uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os); + uint32_t realSize = DoPrint (&item, current, data, offset, printer, os); offset += realSize; if (current == tail) { @@ -1227,9 +1210,8 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe uint32_t offset = 0; while (current != 0xffff) { - uint8_t *buffer = &m_data->m_data[current]; struct PacketHistory::SmallItem item; - uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os); + uint32_t realSize = DoPrint (&item, current, data, offset, printer, os); offset -= realSize; if (current == tail) { diff --git a/src/common/packet-history.h b/src/common/packet-history.h index dc4f8d881..e129d0d2a 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -113,7 +113,7 @@ private: void ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const; void Reserve (uint32_t n); void ReserveCopy (uint32_t n); - uint32_t DoPrint (struct PacketHistory::SmallItem *item, uint8_t const*buffer, + uint32_t DoPrint (struct PacketHistory::SmallItem *item, uint32_t current, Buffer data, uint32_t offset, const PacketPrinter &printer, std::ostream &os) const; uint32_t GetTotalSize (void) const; From cbac246ffbcb5c06d0472c753b20a900c2a50b94 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 09:43:54 +0200 Subject: [PATCH 059/116] fix simple bugs in RemoveAtEnd --- src/common/packet-history.cc | 106 ++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 26decfcf0..2b65f0991 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -673,7 +673,7 @@ PacketHistory::AddBig (bool atStart, append: uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; - if (end - start >= 13 && + if (end - start >= 10 && CanAdd (atStart) && (m_data->m_count == 1 || m_used == m_data->m_dirtyEnd)) @@ -737,6 +737,9 @@ PacketHistory::AddBig (bool atStart, uint32_t n = GetUleb128Size (item->typeUid+1); n += GetUleb128Size (item->size); n += GetUleb128Size (item->chunkUid); + n += GetUleb128Size (extraItem->fragmentStart); + n += GetUleb128Size (extraItem->fragmentEnd); + n += GetUleb128Size (extraItem->packetUid); n += 2 + 2; ReserveCopy (n); goto append; @@ -991,7 +994,6 @@ PacketHistory::RemoveAtStart (uint32_t start) uint32_t leftToRemove = start; uint16_t current = m_head; - uint16_t tail = m_tail; while (current != 0xffff && leftToRemove > 0) { struct PacketHistory::SmallItem item; @@ -1016,7 +1018,7 @@ PacketHistory::RemoveAtStart (uint32_t start) { ReadItems (current, &item, &extraItem); fragment.AddBig (false, &item, &extraItem); - if (current == tail) + if (current == m_tail) { break; } @@ -1026,61 +1028,13 @@ PacketHistory::RemoveAtStart (uint32_t start) } NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart && extraItem.fragmentStart <= extraItem.fragmentEnd); - if (current == tail) + if (current == m_tail) { break; } current = item.next; } NS_ASSERT (leftToRemove == 0); -#if 0 - struct PacketHistory::SmallItem item; - const uint8_t *buffer = &m_data->m_data[m_head]; - ReadSmall (&item, &buffer); - NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); - if ((item.typeUid & 0xfffffffe) != uid || - item.size != size) - { - NS_FATAL_ERROR ("Removing unexpected header."); - } - else if (item.typeUid != uid) - { - // this is a "big" item - struct PacketHistory::ExtraItem extraItem; - ReadExtra (&extraItem, &buffer); - NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); - if (extraItem.fragmentStart != 0 || - extraItem.fragmentEnd != size) - { - NS_FATAL_ERROR ("Removing incomplete header."); - } - } - m_head = item.next; - if (m_head > m_tail) - { - m_used = m_head; - } - - uint32_t leftToRemove = start; - while (!m_itemList.empty () && leftToRemove > 0) - { - struct Item &item = m_itemList.front (); - uint32_t itemRealSize = item.m_fragmentEnd - item.m_fragmentStart; - if (itemRealSize <= leftToRemove) - { - m_itemList.pop_front (); - leftToRemove -= itemRealSize; - } - else - { - item.m_fragmentStart += leftToRemove; - leftToRemove = 0; - NS_ASSERT (item.m_size >= item.m_fragmentEnd - item.m_fragmentStart && - item.m_fragmentStart <= item.m_fragmentEnd); - } - } - NS_ASSERT (leftToRemove == 0); -#endif } void PacketHistory::RemoveAtEnd (uint32_t end) @@ -1089,6 +1043,54 @@ PacketHistory::RemoveAtEnd (uint32_t end) { return; } + if (m_data == 0) + { + NS_FATAL_ERROR ("Removing data from start of empty packet."); + } + + uint32_t leftToRemove = end; + uint16_t current = m_tail; + while (current != 0xffff && leftToRemove > 0) + { + struct PacketHistory::SmallItem item; + PacketHistory::ExtraItem extraItem; + ReadItems (current, &item, &extraItem); + uint32_t itemRealSize = extraItem.fragmentEnd - extraItem.fragmentStart; + if (itemRealSize <= leftToRemove) + { + // remove from list. + m_tail = item.prev; + leftToRemove -= itemRealSize; + } + else + { + // fragment the list item. + PacketHistory fragment (m_packetUid, 0); + extraItem.fragmentStart += leftToRemove; + leftToRemove = 0; + fragment.AddBig (true, &item, &extraItem); + current = item.prev; + while (current != 0xffff) + { + ReadItems (current, &item, &extraItem); + fragment.AddBig (false, &item, &extraItem); + if (current == m_head) + { + break; + } + current = item.prev; + } + *this = fragment; + } + NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart && + extraItem.fragmentStart <= extraItem.fragmentEnd); + if (current == m_head) + { + break; + } + current = item.prev; + } + NS_ASSERT (leftToRemove == 0); } void From 113e6255ea62554fca8179611916099ea7ce4b3f Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 09:45:23 +0200 Subject: [PATCH 060/116] simplify GetTotalSize --- src/common/packet-history.cc | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 2b65f0991..7e25466e4 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1147,24 +1147,10 @@ PacketHistory::GetTotalSize (void) const uint16_t tail = m_tail; while (current != 0xffff) { - const uint8_t *buffer = &m_data->m_data[current]; struct PacketHistory::SmallItem item; - ReadSmall (&item, &buffer); - bool isExtra = (item.typeUid & 0x1) == 0x1; - uint32_t fragmentStart, fragmentEnd; - if (isExtra) - { - PacketHistory::ExtraItem extraItem; - ReadExtra (&extraItem, &buffer); - fragmentStart = extraItem.fragmentStart; - fragmentEnd = extraItem.fragmentEnd; - } - else - { - fragmentStart = 0; - fragmentEnd = item.size; - } - totalSize += fragmentEnd - fragmentStart; + PacketHistory::ExtraItem extraItem; + ReadItems (current, &item, &extraItem); + totalSize += extraItem.fragmentEnd - extraItem.fragmentStart; if (current == tail) { break; From 8c03ce9e0c2cb91d42b07ddeeb7abc4751e116fd Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 09:55:01 +0200 Subject: [PATCH 061/116] remove data from end of trailer, not start of header --- src/common/packet-history.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 7e25466e4..dd7ffda19 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1066,7 +1066,8 @@ PacketHistory::RemoveAtEnd (uint32_t end) { // fragment the list item. PacketHistory fragment (m_packetUid, 0); - extraItem.fragmentStart += leftToRemove; + NS_ASSERT (extraItem.fragmentEnd > leftToRemove); + extraItem.fragmentEnd -= leftToRemove; leftToRemove = 0; fragment.AddBig (true, &item, &extraItem); current = item.prev; From 5698e745c9b9e91b37296be41899bc2bc34732d8 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 10:04:02 +0200 Subject: [PATCH 062/116] fix a few bugs in ::RemoveAtEnd --- src/common/packet-history.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index dd7ffda19..5e039f8ef 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -670,6 +670,7 @@ PacketHistory::AddBig (bool atStart, memset (m_data->m_data, 0xff, 4); } NS_ASSERT (m_data != 0); + uint32_t typeUid = ((item->typeUid & 0x1) == 0x1)?item->typeUid:item->typeUid+1; append: uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; @@ -693,7 +694,7 @@ PacketHistory::AddBig (bool atStart, Append16 (next, &buffer); Append16 (prev, &buffer); - if (TryToAppend (item->typeUid+1, &buffer, end) && + if (TryToAppend (typeUid, &buffer, end) && TryToAppend (item->size, &buffer, end) && TryToAppend (item->chunkUid, &buffer, end) && TryToAppend (extraItem->fragmentStart, &buffer, end) && @@ -734,7 +735,7 @@ PacketHistory::AddBig (bool atStart, } } - uint32_t n = GetUleb128Size (item->typeUid+1); + uint32_t n = GetUleb128Size (typeUid); n += GetUleb128Size (item->size); n += GetUleb128Size (item->chunkUid); n += GetUleb128Size (extraItem->fragmentStart); @@ -1074,7 +1075,7 @@ PacketHistory::RemoveAtEnd (uint32_t end) while (current != 0xffff) { ReadItems (current, &item, &extraItem); - fragment.AddBig (false, &item, &extraItem); + fragment.AddBig (true, &item, &extraItem); if (current == m_head) { break; From 929ea4dab0183cdac9248e87d60b205547d59dea Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 11:01:59 +0200 Subject: [PATCH 063/116] share some code, implement AddAtEnd --- src/common/packet-history.cc | 158 ++++++++++++++++++++--------------- src/common/packet-history.h | 11 +-- 2 files changed, 98 insertions(+), 71 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 5e039f8ef..2fdccb81e 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -338,7 +338,8 @@ PacketHistory::PacketHistory (uint32_t uid, uint32_t size) { if (size > 0) { - AddSmall (true, 0, size); + uint16_t written = AddSmall (true, 0, size); + Update (true, written); } } PacketHistory::PacketHistory (PacketHistory const &o) @@ -579,6 +580,39 @@ PacketHistory::CanAdd (bool atStart) } void +PacketHistory::Update (bool atStart, uint16_t written) +{ + if (m_head == 0xffff) + { + NS_ASSERT (m_tail == 0xffff); + m_head = m_used; + m_tail = m_used; + } + else if (atStart) + { + NS_ASSERT (m_head != 0xffff); + // overwrite the prev field of the previous head of the list. + uint8_t *previousHead = &m_data->m_data[m_head] + 2; + Append16 (m_used, &previousHead); + // update the head of list to the new node. + m_head = m_used; + } + else + { + NS_ASSERT (m_tail != 0xffff); + // overwrite the next field of the previous tail of the list. + uint8_t *previousTail = &m_data->m_data[m_tail]; + Append16 (m_used, &previousTail); + // update the tail of the list to the new node. + m_tail = m_used; + } + NS_ASSERT (m_tail != 0xffff); + NS_ASSERT (m_head != 0xffff); + m_used += written; + m_data->m_dirtyEnd = m_used; +} + +uint16_t PacketHistory::AddSmall (bool atStart, uint32_t typeUid, uint32_t size) { @@ -619,35 +653,7 @@ PacketHistory::AddSmall (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); - if (m_head == 0xffff) - { - NS_ASSERT (m_tail == 0xffff); - m_head = m_used; - m_tail = m_used; - } - else if (atStart) - { - NS_ASSERT (m_head != 0xffff); - // overwrite the prev field of the previous head of the list. - uint8_t *previousHead = &m_data->m_data[m_head] + 2; - Append16 (m_used, &previousHead); - // update the head of list to the new node. - m_head = m_used; - } - else - { - NS_ASSERT (m_tail != 0xffff); - // overwrite the next field of the previous tail of the list. - uint8_t *previousTail = &m_data->m_data[m_tail]; - Append16 (m_used, &previousTail); - // update the tail of the list to the new node. - m_tail = m_used; - } - NS_ASSERT (m_tail != 0xffff); - NS_ASSERT (m_head != 0xffff); - m_used += written; - m_data->m_dirtyEnd = m_used; - return; + return written; } } @@ -659,7 +665,7 @@ PacketHistory::AddSmall (bool atStart, goto append; } -void +uint16_t PacketHistory::AddBig (bool atStart, const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem) @@ -703,35 +709,7 @@ PacketHistory::AddBig (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); - if (m_head == 0xffff) - { - NS_ASSERT (m_tail == 0xffff); - m_head = m_used; - m_tail = m_used; - } - else if (atStart) - { - NS_ASSERT (m_head != 0xffff); - // overwrite the prev field of the previous head of the list. - uint8_t *previousHead = &m_data->m_data[m_head] + 2; - Append16 (m_used, &previousHead); - // update the head of list to the new node. - m_head = m_used; - } - else - { - NS_ASSERT (m_tail != 0xffff); - // overwrite the next field of the previous tail of the list. - uint8_t *previousTail = &m_data->m_data[m_tail]; - Append16 (m_used, &previousTail); - // update the tail of the list to the new node. - m_tail = m_used; - } - NS_ASSERT (m_tail != 0xffff); - NS_ASSERT (m_head != 0xffff); - m_used += written; - m_data->m_dirtyEnd = m_used; - return; + return written; } } @@ -878,7 +856,8 @@ PacketHistory::AddHeader (uint32_t uid, Chunk const & header, uint32_t size) { return; } - AddSmall (true, uid, size); + uint16_t written = AddSmall (true, uid, size); + Update (true, written); } void PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) @@ -925,7 +904,8 @@ PacketHistory::AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) { return; } - AddSmall (false, uid, size); + uint16_t written = AddSmall (false, uid, size); + Update (false, written); } void PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) @@ -972,6 +952,48 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { return; } + if (m_data == 0 || m_tail == 0xffff) + { + *this = o; + return; + } + NS_ASSERT (m_head != 0xffff && m_tail != 0xffff); + + uint16_t lastTail = m_tail; + struct PacketHistory::SmallItem lastItem; + PacketHistory::ExtraItem lastExtraItem; + ReadItems (m_tail, &lastItem, &lastExtraItem); + + uint16_t current = o.m_head; + while (current != 0xffff) + { + struct PacketHistory::SmallItem item; + PacketHistory::ExtraItem extraItem; + o.ReadItems (current, &item, &extraItem); + if (extraItem.packetUid == lastExtraItem.packetUid && + item.typeUid == lastItem.typeUid && + item.chunkUid == lastItem.chunkUid && + item.size == lastItem.size && + extraItem.fragmentStart == lastExtraItem.fragmentEnd) + { + // add at tail + lastExtraItem.fragmentEnd = extraItem.fragmentEnd; + NS_ASSERT (m_tail == lastTail); + uint16_t written = AddBig (false, &lastItem, &lastExtraItem); + m_used += written; + m_data->m_dirtyEnd = m_used; + } + else + { + uint16_t written = AddBig (false, &item, &extraItem); + Update (false, written); + } + current = item.next; + if (current == o.m_tail) + { + break; + } + } } void PacketHistory::AddPaddingAtEnd (uint32_t end) @@ -1013,12 +1035,14 @@ PacketHistory::RemoveAtStart (uint32_t start) PacketHistory fragment (m_packetUid, 0); extraItem.fragmentStart += leftToRemove; leftToRemove = 0; - fragment.AddBig (false, &item, &extraItem); + uint16_t written = fragment.AddBig (false, &item, &extraItem); + fragment.Update (false, written); current = item.next; while (current != 0xffff) { ReadItems (current, &item, &extraItem); - fragment.AddBig (false, &item, &extraItem); + written = fragment.AddBig (false, &item, &extraItem); + fragment.Update (false, written); if (current == m_tail) { break; @@ -1070,12 +1094,14 @@ PacketHistory::RemoveAtEnd (uint32_t end) NS_ASSERT (extraItem.fragmentEnd > leftToRemove); extraItem.fragmentEnd -= leftToRemove; leftToRemove = 0; - fragment.AddBig (true, &item, &extraItem); + uint16_t written = fragment.AddBig (true, &item, &extraItem); + fragment.Update (true, written); current = item.prev; while (current != 0xffff) { ReadItems (current, &item, &extraItem); - fragment.AddBig (true, &item, &extraItem); + uint16_t written = fragment.AddBig (true, &item, &extraItem); + fragment.Update (true, written); if (current == m_head) { break; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index e129d0d2a..6f6542302 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -98,11 +98,12 @@ private: void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); - void AddSmall (bool atStart, - uint32_t typeUid, uint32_t size); - void AddBig (bool atStart, - const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem); + uint16_t AddSmall (bool atStart, + uint32_t typeUid, uint32_t size); + uint16_t AddBig (bool atStart, + const PacketHistory::SmallItem *item, + const PacketHistory::ExtraItem *extraItem); + void Update (bool atStart, uint16_t written); uint32_t GetUleb128Size (uint32_t value) const; uint32_t ReadUleb128 (const uint8_t **pBuffer) const; void Append16 (uint16_t value, uint8_t **pBuffer); From 2caaf900379d907c2770751a05f1ad71914316ce Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 11:30:17 +0200 Subject: [PATCH 064/116] simplify calls to AddBig and AddSmall --- src/common/packet-history.cc | 45 ++++++++++++++++++------------------ src/common/packet-history.h | 12 ++++++---- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 2fdccb81e..84074f3d3 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -338,8 +338,7 @@ PacketHistory::PacketHistory (uint32_t uid, uint32_t size) { if (size > 0) { - uint16_t written = AddSmall (true, 0, size); - Update (true, written); + AddSmall (true, 0, size); } } PacketHistory::PacketHistory (PacketHistory const &o) @@ -612,7 +611,7 @@ PacketHistory::Update (bool atStart, uint16_t written) m_data->m_dirtyEnd = m_used; } -uint16_t +void PacketHistory::AddSmall (bool atStart, uint32_t typeUid, uint32_t size) { @@ -653,7 +652,8 @@ PacketHistory::AddSmall (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); - return written; + Update (atStart, written); + return; } } @@ -665,7 +665,7 @@ PacketHistory::AddSmall (bool atStart, goto append; } -uint16_t +void PacketHistory::AddBig (bool atStart, const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem) @@ -709,7 +709,8 @@ PacketHistory::AddBig (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); - return written; + Update (atStart, written); + return; } } @@ -722,10 +723,17 @@ PacketHistory::AddBig (bool atStart, n += 2 + 2; ReserveCopy (n); goto append; +} + +void +PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, + const PacketHistory::ExtraItem *extraItem) +{ } + void PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const { @@ -856,8 +864,7 @@ PacketHistory::AddHeader (uint32_t uid, Chunk const & header, uint32_t size) { return; } - uint16_t written = AddSmall (true, uid, size); - Update (true, written); + AddSmall (true, uid, size); } void PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) @@ -904,8 +911,7 @@ PacketHistory::AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) { return; } - uint16_t written = AddSmall (false, uid, size); - Update (false, written); + AddSmall (false, uid, size); } void PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) @@ -979,14 +985,11 @@ PacketHistory::AddAtEnd (PacketHistory const&o) // add at tail lastExtraItem.fragmentEnd = extraItem.fragmentEnd; NS_ASSERT (m_tail == lastTail); - uint16_t written = AddBig (false, &lastItem, &lastExtraItem); - m_used += written; - m_data->m_dirtyEnd = m_used; + ReplaceTail (&lastItem, &lastExtraItem); } else { - uint16_t written = AddBig (false, &item, &extraItem); - Update (false, written); + AddBig (false, &item, &extraItem); } current = item.next; if (current == o.m_tail) @@ -1035,14 +1038,12 @@ PacketHistory::RemoveAtStart (uint32_t start) PacketHistory fragment (m_packetUid, 0); extraItem.fragmentStart += leftToRemove; leftToRemove = 0; - uint16_t written = fragment.AddBig (false, &item, &extraItem); - fragment.Update (false, written); + fragment.AddBig (false, &item, &extraItem); current = item.next; while (current != 0xffff) { ReadItems (current, &item, &extraItem); - written = fragment.AddBig (false, &item, &extraItem); - fragment.Update (false, written); + fragment.AddBig (false, &item, &extraItem); if (current == m_tail) { break; @@ -1094,14 +1095,12 @@ PacketHistory::RemoveAtEnd (uint32_t end) NS_ASSERT (extraItem.fragmentEnd > leftToRemove); extraItem.fragmentEnd -= leftToRemove; leftToRemove = 0; - uint16_t written = fragment.AddBig (true, &item, &extraItem); - fragment.Update (true, written); + fragment.AddBig (true, &item, &extraItem); current = item.prev; while (current != 0xffff) { ReadItems (current, &item, &extraItem); - uint16_t written = fragment.AddBig (true, &item, &extraItem); - fragment.Update (true, written); + fragment.AddBig (true, &item, &extraItem); if (current == m_head) { break; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 6f6542302..d5aafa2d5 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -98,11 +98,13 @@ private: void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); - uint16_t AddSmall (bool atStart, - uint32_t typeUid, uint32_t size); - uint16_t AddBig (bool atStart, - const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem); + void AddSmall (bool atStart, + uint32_t typeUid, uint32_t size); + void AddBig (bool atStart, + const PacketHistory::SmallItem *item, + const PacketHistory::ExtraItem *extraItem); + void ReplaceTail (const PacketHistory::SmallItem *item, + const PacketHistory::ExtraItem *extraItem); void Update (bool atStart, uint16_t written); uint32_t GetUleb128Size (uint32_t value) const; uint32_t ReadUleb128 (const uint8_t **pBuffer) const; From b0a30b32bbff96bcab97262bd55ec37475e20fb6 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 12:39:33 +0200 Subject: [PATCH 065/116] implement ReplaceTail --- src/common/packet-history.cc | 54 ++++++++++++++++++++++++++++++++---- src/common/packet-history.h | 9 +++--- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 84074f3d3..b9f6fa8fe 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -727,9 +727,44 @@ PacketHistory::AddBig (bool atStart, void PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem) + const PacketHistory::ExtraItem *extraItem, + uint32_t available) { + NS_ASSERT (m_data != 0); + if (available >= 10 && + (m_data->m_count == 1 || + m_used == m_data->m_dirtyEnd)) + { + uint8_t *buffer = &m_data->m_data[m_tail]; + uint8_t *end = buffer + available; + Append16 (item->next, &buffer); + Append16 (item->prev, &buffer); + if (TryToAppend (item->typeUid, &buffer, end) && + TryToAppend (item->size, &buffer, end) && + TryToAppend (item->chunkUid, &buffer, end) && + TryToAppend (extraItem->fragmentStart, &buffer, end) && + TryToAppend (extraItem->fragmentEnd, &buffer, end) && + TryToAppend (extraItem->packetUid, &buffer, end)) + { + return; + } + } + + // create a copy of the packet. + PacketHistory h (m_packetUid, 0); + uint16_t current = m_head; + while (current != 0xffff && current != m_tail) + { + struct PacketHistory::SmallItem tmpItem; + PacketHistory::ExtraItem tmpExtraItem; + ReadItems (current, &tmpItem, &tmpExtraItem); + h.AddBig (false, &tmpItem, &tmpExtraItem); + } + // append new tail. + h.AddBig (false, item, extraItem); + + *this = h; } @@ -748,7 +783,7 @@ PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t * item->chunkUid = ReadUleb128 (pBuffer); } -void +uint32_t PacketHistory::ReadItems (uint16_t current, struct PacketHistory::SmallItem *item, struct PacketHistory::ExtraItem *extraItem) const @@ -767,6 +802,7 @@ PacketHistory::ReadItems (uint16_t current, extraItem->packetUid = m_packetUid; } NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); + return buffer - &m_data->m_data[current]; } @@ -968,7 +1004,12 @@ PacketHistory::AddAtEnd (PacketHistory const&o) uint16_t lastTail = m_tail; struct PacketHistory::SmallItem lastItem; PacketHistory::ExtraItem lastExtraItem; - ReadItems (m_tail, &lastItem, &lastExtraItem); + uint32_t lastTailSize = ReadItems (m_tail, &lastItem, &lastExtraItem); + if (m_tail + lastTailSize == m_used && + m_used == m_data->m_dirtyEnd) + { + lastTailSize = m_data->m_size; + } uint16_t current = o.m_head; while (current != 0xffff) @@ -982,13 +1023,14 @@ PacketHistory::AddAtEnd (PacketHistory const&o) item.size == lastItem.size && extraItem.fragmentStart == lastExtraItem.fragmentEnd) { - // add at tail + // replace previous tail. lastExtraItem.fragmentEnd = extraItem.fragmentEnd; NS_ASSERT (m_tail == lastTail); - ReplaceTail (&lastItem, &lastExtraItem); + ReplaceTail (&lastItem, &lastExtraItem, lastTailSize); } else { + // append the extra items. AddBig (false, &item, &extraItem); } current = item.next; @@ -996,7 +1038,7 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { break; } - } + } } void PacketHistory::AddPaddingAtEnd (uint32_t end) diff --git a/src/common/packet-history.h b/src/common/packet-history.h index d5aafa2d5..e7b5b4d12 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -104,7 +104,8 @@ private: const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem); void ReplaceTail (const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem); + const PacketHistory::ExtraItem *extraItem, + uint32_t available); void Update (bool atStart, uint16_t written); uint32_t GetUleb128Size (uint32_t value) const; uint32_t ReadUleb128 (const uint8_t **pBuffer) const; @@ -120,9 +121,9 @@ private: Buffer data, uint32_t offset, const PacketPrinter &printer, std::ostream &os) const; uint32_t GetTotalSize (void) const; - void ReadItems (uint16_t current, - struct PacketHistory::SmallItem *item, - struct PacketHistory::ExtraItem *extraItem) const; + uint32_t ReadItems (uint16_t current, + struct PacketHistory::SmallItem *item, + struct PacketHistory::ExtraItem *extraItem) const; static struct PacketHistory::Data *Create (uint32_t size); From eb6eea0f72230aea01ec0c5bb277e6f5f96bb967 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 13:02:00 +0200 Subject: [PATCH 066/116] make all tests pass --- src/common/packet-history.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index b9f6fa8fe..dccd315fe 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -732,8 +732,7 @@ PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, { NS_ASSERT (m_data != 0); if (available >= 10 && - (m_data->m_count == 1 || - m_used == m_data->m_dirtyEnd)) + m_data->m_count == 1) { uint8_t *buffer = &m_data->m_data[m_tail]; uint8_t *end = buffer + available; @@ -747,6 +746,8 @@ PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, TryToAppend (extraItem->fragmentEnd, &buffer, end) && TryToAppend (extraItem->packetUid, &buffer, end)) { + m_used = buffer - &m_data->m_data[0]; + m_data->m_dirtyEnd = m_used; return; } } @@ -1008,7 +1009,7 @@ PacketHistory::AddAtEnd (PacketHistory const&o) if (m_tail + lastTailSize == m_used && m_used == m_data->m_dirtyEnd) { - lastTailSize = m_data->m_size; + lastTailSize = m_data->m_size - m_tail; } uint16_t current = o.m_head; @@ -1033,11 +1034,11 @@ PacketHistory::AddAtEnd (PacketHistory const&o) // append the extra items. AddBig (false, &item, &extraItem); } - current = item.next; if (current == o.m_tail) { break; } + current = item.next; } } void From 07489e7e9c00389ba0a6738effd29f26a86af56e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 13:51:15 +0200 Subject: [PATCH 067/116] a few micro-optimizations --- src/common/packet-history.cc | 65 +++++++++++++++++++++++++----------- src/common/packet-history.h | 13 ++++---- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index dccd315fe..21ca8a1f0 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -410,10 +410,10 @@ PacketHistory::ReserveCopy (uint32_t size) NS_ASSERT (m_tail != 0xffff); // clear the next field of the tail start = &m_data->m_data[m_tail]; - Append16 (0xffff, &start); + Append16 (0xffff, start); // clear the prev field of the head start = &m_data->m_data[m_head] + 2; - Append16 (0xffff, &start); + Append16 (0xffff, start); } } void @@ -496,13 +496,32 @@ PacketHistory::ReadUleb128 (const uint8_t **pBuffer) const } void -PacketHistory::Append16 (uint16_t value, uint8_t **pBuffer) +PacketHistory::Append16 (uint16_t value, uint8_t *buffer) { - uint8_t *buffer = *pBuffer; buffer[0] = value & 0xff; value >>= 8; buffer[1] = value; - *pBuffer = buffer + 2; +} +bool +PacketHistory::TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end) +{ + uint8_t *start = *pBuffer; + if (value < 0x80 && start < end) + { + start[0] = value; + *pBuffer = start + 1; + return true; + } + if (value < 0x4000 && start + 1 < end) + { + uint8_t byte = value & (~0x80); + start[0] = 0x80 | byte; + value >>= 7; + start[1] = value; + *pBuffer = start + 2; + return true; + } + return false; } bool PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) @@ -551,13 +570,13 @@ PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) } bool -PacketHistory::IsFF16 (uint16_t index) +PacketHistory::IsFF16 (uint16_t index) const { return m_data->m_data[index] == 0xff && m_data->m_data[index+1] == 0xff; } bool -PacketHistory::CanAdd (bool atStart) +PacketHistory::CanAdd (bool atStart) const { if (m_head == 0xffff) { @@ -592,7 +611,7 @@ PacketHistory::Update (bool atStart, uint16_t written) NS_ASSERT (m_head != 0xffff); // overwrite the prev field of the previous head of the list. uint8_t *previousHead = &m_data->m_data[m_head] + 2; - Append16 (m_used, &previousHead); + Append16 (m_used, previousHead); // update the head of list to the new node. m_head = m_used; } @@ -601,7 +620,7 @@ PacketHistory::Update (bool atStart, uint16_t written) NS_ASSERT (m_tail != 0xffff); // overwrite the next field of the previous tail of the list. uint8_t *previousTail = &m_data->m_data[m_tail]; - Append16 (m_used, &previousTail); + Append16 (m_used, previousTail); // update the tail of the list to the new node. m_tail = m_used; } @@ -644,19 +663,22 @@ PacketHistory::AddSmall (bool atStart, prev = m_tail; } - Append16 (next, &buffer); - Append16 (prev, &buffer); - if (TryToAppend (typeUid, &buffer, end) && - TryToAppend (size, &buffer, end) && + Append16 (next, buffer); + buffer += 2; + Append16 (prev, buffer); + buffer += 2; + if (TryToAppendFast (typeUid, &buffer, end) && + TryToAppendFast (size, &buffer, end) && TryToAppend (chunkUid, &buffer, end)) { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); Update (atStart, written); + g_one++; return; } } - + g_two++; uint32_t n = GetUleb128Size (typeUid); n += GetUleb128Size (size); n += GetUleb128Size (chunkUid); @@ -698,8 +720,10 @@ PacketHistory::AddBig (bool atStart, prev = m_tail; } - Append16 (next, &buffer); - Append16 (prev, &buffer); + Append16 (next, buffer); + buffer += 2; + Append16 (prev, buffer); + buffer += 2; if (TryToAppend (typeUid, &buffer, end) && TryToAppend (item->size, &buffer, end) && TryToAppend (item->chunkUid, &buffer, end) && @@ -737,8 +761,10 @@ PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, uint8_t *buffer = &m_data->m_data[m_tail]; uint8_t *end = buffer + available; - Append16 (item->next, &buffer); - Append16 (item->prev, &buffer); + Append16 (item->next, buffer); + buffer += 2; + Append16 (item->prev, buffer); + buffer += 2; if (TryToAppend (item->typeUid, &buffer, end) && TryToAppend (item->size, &buffer, end) && TryToAppend (item->chunkUid, &buffer, end) && @@ -1002,7 +1028,8 @@ PacketHistory::AddAtEnd (PacketHistory const&o) } NS_ASSERT (m_head != 0xffff && m_tail != 0xffff); - uint16_t lastTail = m_tail; + uint16_t lastTail; + lastTail = m_tail; struct PacketHistory::SmallItem lastItem; PacketHistory::ExtraItem lastExtraItem; uint32_t lastTailSize = ReadItems (m_tail, &lastItem, &lastExtraItem); diff --git a/src/common/packet-history.h b/src/common/packet-history.h index e7b5b4d12..e5a99bc1e 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -106,13 +106,14 @@ private: void ReplaceTail (const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem, uint32_t available); - void Update (bool atStart, uint16_t written); + inline void Update (bool atStart, uint16_t written); uint32_t GetUleb128Size (uint32_t value) const; - uint32_t ReadUleb128 (const uint8_t **pBuffer) const; - void Append16 (uint16_t value, uint8_t **pBuffer); - bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); - bool IsFF16 (uint16_t index); - bool CanAdd (bool atStart); + inline uint32_t ReadUleb128 (const uint8_t **pBuffer) const; + inline void Append16 (uint16_t value, uint8_t *buffer); + inline bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); + inline bool TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end); + inline bool IsFF16 (uint16_t index) const; + inline bool CanAdd (bool atStart) const; void ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const; void ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const; void Reserve (uint32_t n); From f348fc4fbc2d6094b24b42b27a10c9ecbda3643f Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 13:56:42 +0200 Subject: [PATCH 068/116] remove useless CanAdd --- src/common/packet-history.cc | 36 ++++-------------------------------- src/common/packet-history.h | 2 -- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 21ca8a1f0..a95c59013 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -569,34 +569,6 @@ PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) return false; } -bool -PacketHistory::IsFF16 (uint16_t index) const -{ - return m_data->m_data[index] == 0xff && m_data->m_data[index+1] == 0xff; -} - -bool -PacketHistory::CanAdd (bool atStart) const -{ - if (m_head == 0xffff) - { - NS_ASSERT (m_tail == 0xffff); - return true; - } - if (atStart) - { - return IsFF16 (m_head+2); - } - else if (!atStart) - { - return IsFF16 (m_tail); - } - else - { - return false; - } -} - void PacketHistory::Update (bool atStart, uint16_t written) { @@ -646,8 +618,8 @@ PacketHistory::AddSmall (bool atStart, uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; if (end - start >= 7 && - CanAdd (atStart) && - (m_data->m_count == 1 || + (m_head == 0xffff || + m_data->m_count == 1 || m_used == m_data->m_dirtyEnd)) { uint8_t *buffer = start; @@ -703,8 +675,8 @@ PacketHistory::AddBig (bool atStart, uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; if (end - start >= 10 && - CanAdd (atStart) && - (m_data->m_count == 1 || + (m_head == 0xffff || + m_data->m_count == 1 || m_used == m_data->m_dirtyEnd)) { uint8_t *buffer = start; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index e5a99bc1e..ada462a29 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -112,8 +112,6 @@ private: inline void Append16 (uint16_t value, uint8_t *buffer); inline bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); inline bool TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end); - inline bool IsFF16 (uint16_t index) const; - inline bool CanAdd (bool atStart) const; void ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const; void ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const; void Reserve (uint32_t n); From 4ed6463d22dffa1adf451e6352c3aa3c42da9277 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 14:11:22 +0200 Subject: [PATCH 069/116] remove Update call from within AddSmall and AddBig --- src/common/packet-history.cc | 40 +++++++++++++++++++++--------------- src/common/packet-history.h | 10 ++++----- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index a95c59013..63712a7d5 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -338,7 +338,8 @@ PacketHistory::PacketHistory (uint32_t uid, uint32_t size) { if (size > 0) { - AddSmall (true, 0, size); + uint16_t written = AddSmall (true, 0, size); + Update (true, written); } } PacketHistory::PacketHistory (PacketHistory const &o) @@ -602,7 +603,7 @@ PacketHistory::Update (bool atStart, uint16_t written) m_data->m_dirtyEnd = m_used; } -void +uint16_t PacketHistory::AddSmall (bool atStart, uint32_t typeUid, uint32_t size) { @@ -645,9 +646,8 @@ PacketHistory::AddSmall (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); - Update (atStart, written); g_one++; - return; + return written; } } g_two++; @@ -659,7 +659,7 @@ PacketHistory::AddSmall (bool atStart, goto append; } -void +uint16_t PacketHistory::AddBig (bool atStart, const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem) @@ -705,8 +705,7 @@ PacketHistory::AddBig (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); - Update (atStart, written); - return; + return written; } } @@ -758,10 +757,12 @@ PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, struct PacketHistory::SmallItem tmpItem; PacketHistory::ExtraItem tmpExtraItem; ReadItems (current, &tmpItem, &tmpExtraItem); - h.AddBig (false, &tmpItem, &tmpExtraItem); + uint16_t written = h.AddBig (false, &tmpItem, &tmpExtraItem); + h.Update (false, written); } // append new tail. - h.AddBig (false, item, extraItem); + uint16_t written = h.AddBig (false, item, extraItem); + h.Update (false, written); *this = h; } @@ -899,7 +900,8 @@ PacketHistory::AddHeader (uint32_t uid, Chunk const & header, uint32_t size) { return; } - AddSmall (true, uid, size); + uint16_t written = AddSmall (true, uid, size); + Update (true, written); } void PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) @@ -946,7 +948,8 @@ PacketHistory::AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) { return; } - AddSmall (false, uid, size); + uint16_t written = AddSmall (false, uid, size); + Update (false, written); } void PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) @@ -1031,7 +1034,8 @@ PacketHistory::AddAtEnd (PacketHistory const&o) else { // append the extra items. - AddBig (false, &item, &extraItem); + uint16_t written = AddBig (false, &item, &extraItem); + Update (false, written); } if (current == o.m_tail) { @@ -1080,12 +1084,14 @@ PacketHistory::RemoveAtStart (uint32_t start) PacketHistory fragment (m_packetUid, 0); extraItem.fragmentStart += leftToRemove; leftToRemove = 0; - fragment.AddBig (false, &item, &extraItem); + uint16_t written = fragment.AddBig (false, &item, &extraItem); + Update (false, written); current = item.next; while (current != 0xffff) { ReadItems (current, &item, &extraItem); - fragment.AddBig (false, &item, &extraItem); + written = fragment.AddBig (false, &item, &extraItem); + Update (false, written); if (current == m_tail) { break; @@ -1137,12 +1143,14 @@ PacketHistory::RemoveAtEnd (uint32_t end) NS_ASSERT (extraItem.fragmentEnd > leftToRemove); extraItem.fragmentEnd -= leftToRemove; leftToRemove = 0; - fragment.AddBig (true, &item, &extraItem); + uint16_t written = fragment.AddBig (true, &item, &extraItem); + Update (true, written); current = item.prev; while (current != 0xffff) { ReadItems (current, &item, &extraItem); - fragment.AddBig (true, &item, &extraItem); + written = fragment.AddBig (true, &item, &extraItem); + Update (true, written); if (current == m_head) { break; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index ada462a29..1d853742e 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -98,11 +98,11 @@ private: void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); - void AddSmall (bool atStart, - uint32_t typeUid, uint32_t size); - void AddBig (bool atStart, - const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem); + uint16_t AddSmall (bool atStart, + uint32_t typeUid, uint32_t size); + uint16_t AddBig (bool atStart, + const PacketHistory::SmallItem *item, + const PacketHistory::ExtraItem *extraItem); void ReplaceTail (const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem, uint32_t available); From e5b63ce34dc2fafff39240306566808a0c291ad5 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 14:14:22 +0200 Subject: [PATCH 070/116] add counters --- src/common/packet-history.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 63712a7d5..3b91cf817 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -705,10 +705,12 @@ PacketHistory::AddBig (bool atStart, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); + g_one++; return written; } } - + + g_two++; uint32_t n = GetUleb128Size (typeUid); n += GetUleb128Size (item->size); n += GetUleb128Size (item->chunkUid); From 02763bf7cbd6f269bb8293f6fc978ec34d8a70b0 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 14:19:21 +0200 Subject: [PATCH 071/116] fix bug introduced in commit 767 --- src/common/packet-history.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 3b91cf817..786dccf4f 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -1087,13 +1087,13 @@ PacketHistory::RemoveAtStart (uint32_t start) extraItem.fragmentStart += leftToRemove; leftToRemove = 0; uint16_t written = fragment.AddBig (false, &item, &extraItem); - Update (false, written); + fragment.Update (false, written); current = item.next; while (current != 0xffff) { ReadItems (current, &item, &extraItem); written = fragment.AddBig (false, &item, &extraItem); - Update (false, written); + fragment.Update (false, written); if (current == m_tail) { break; @@ -1146,13 +1146,13 @@ PacketHistory::RemoveAtEnd (uint32_t end) extraItem.fragmentEnd -= leftToRemove; leftToRemove = 0; uint16_t written = fragment.AddBig (true, &item, &extraItem); - Update (true, written); + fragment.Update (true, written); current = item.prev; while (current != 0xffff) { ReadItems (current, &item, &extraItem); written = fragment.AddBig (true, &item, &extraItem); - Update (true, written); + fragment.Update (true, written); if (current == m_head) { break; From 1608934b89bacc33945d09e36860ba12c7c588f0 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 14:32:17 +0200 Subject: [PATCH 072/116] simplify a bit the small item logic --- src/common/packet-history.cc | 61 ++++++++++++++++++------------------ src/common/packet-history.h | 19 ++++++----- 2 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 786dccf4f..91293466f 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -338,8 +338,7 @@ PacketHistory::PacketHistory (uint32_t uid, uint32_t size) { if (size > 0) { - uint16_t written = AddSmall (true, 0, size); - Update (true, written); + DoAddHeader (0, size); } } PacketHistory::PacketHistory (PacketHistory const &o) @@ -604,8 +603,7 @@ PacketHistory::Update (bool atStart, uint16_t written) } uint16_t -PacketHistory::AddSmall (bool atStart, - uint32_t typeUid, uint32_t size) +PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) { if (m_data == 0) { @@ -613,8 +611,6 @@ PacketHistory::AddSmall (bool atStart, memset (m_data->m_data, 0xff, 4); } NS_ASSERT (m_data != 0); - uint16_t chunkUid = m_chunkUid; - m_chunkUid++; append: uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; @@ -624,25 +620,14 @@ PacketHistory::AddSmall (bool atStart, m_used == m_data->m_dirtyEnd)) { uint8_t *buffer = start; - uint16_t next, prev; - if (atStart) - { - next = m_head; - prev = 0xffff; - } - else - { - next = 0xffff; - prev = m_tail; - } - Append16 (next, buffer); + Append16 (item->next, buffer); buffer += 2; - Append16 (prev, buffer); + Append16 (item->prev, buffer); buffer += 2; - if (TryToAppendFast (typeUid, &buffer, end) && - TryToAppendFast (size, &buffer, end) && - TryToAppend (chunkUid, &buffer, end)) + if (TryToAppendFast (item->typeUid, &buffer, end) && + TryToAppendFast (item->size, &buffer, end) && + TryToAppend (item->chunkUid, &buffer, end)) { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); @@ -651,9 +636,9 @@ PacketHistory::AddSmall (bool atStart, } } g_two++; - uint32_t n = GetUleb128Size (typeUid); - n += GetUleb128Size (size); - n += GetUleb128Size (chunkUid); + uint32_t n = GetUleb128Size (item->typeUid); + n += GetUleb128Size (item->size); + n += GetUleb128Size (item->chunkUid); n += 2 + 2; ReserveCopy (n); goto append; @@ -896,17 +881,24 @@ PacketHistory::CreateFragment (uint32_t start, uint32_t end) const } void -PacketHistory::AddHeader (uint32_t uid, Chunk const & header, uint32_t size) +PacketHistory::DoAddHeader (uint32_t uid, uint32_t size) { if (!m_enable) { return; } - uint16_t written = AddSmall (true, uid, size); + struct PacketHistory::SmallItem item; + item.next = m_head; + item.prev = 0xffff; + item.typeUid = uid; + item.size = size; + item.chunkUid = m_chunkUid; + m_chunkUid++; + uint16_t written = AddSmall (&item); Update (true, written); } void -PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) +PacketHistory::DoRemoveHeader (uint32_t uid, uint32_t size) { if (!m_enable) { @@ -944,17 +936,24 @@ PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size) } } void -PacketHistory::AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) +PacketHistory::DoAddTrailer (uint32_t uid, uint32_t size) { if (!m_enable) { return; } - uint16_t written = AddSmall (false, uid, size); + struct PacketHistory::SmallItem item; + item.next = 0xffff; + item.prev = m_tail; + item.typeUid = uid; + item.size = size; + item.chunkUid = m_chunkUid; + m_chunkUid++; + uint16_t written = AddSmall (&item); Update (false, written); } void -PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size) +PacketHistory::DoRemoveTrailer (uint32_t uid, uint32_t size) { if (!m_enable) { diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 1d853742e..3b446dd9a 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -93,13 +93,12 @@ private: typedef std::vector DataFreeList; PacketHistory (); - void AddHeader (uint32_t uid, Chunk const & header, uint32_t size); - void RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size); - void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); - void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); + void DoAddHeader (uint32_t uid, uint32_t size); + void DoRemoveHeader (uint32_t uid, uint32_t size); + void DoAddTrailer (uint32_t uid, uint32_t size); + void DoRemoveTrailer (uint32_t uid, uint32_t size); - uint16_t AddSmall (bool atStart, - uint32_t typeUid, uint32_t size); + uint16_t AddSmall (const PacketHistory::SmallItem *item); uint16_t AddBig (bool atStart, const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem); @@ -150,26 +149,26 @@ template void PacketHistory::AddHeader (T const &header, uint32_t size) { - AddHeader (PacketPrinter::GetHeaderUid (), header, size); + DoAddHeader (PacketPrinter::GetHeaderUid (), size); } template void PacketHistory::RemoveHeader (T const &header, uint32_t size) { - RemoveHeader (PacketPrinter::GetHeaderUid (), header, size); + DoRemoveHeader (PacketPrinter::GetHeaderUid (), size); } template void PacketHistory::AddTrailer (T const &trailer, uint32_t size) { - AddTrailer (PacketPrinter::GetTrailerUid (), trailer, size); + DoAddTrailer (PacketPrinter::GetTrailerUid (), size); } template void PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) { - RemoveTrailer (PacketPrinter::GetTrailerUid (), trailer, size); + DoRemoveTrailer (PacketPrinter::GetTrailerUid (), size); } }; // namespace ns3 From 8e0ccbb45a0d81c518119f5c298981eb74c9b960 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 14:38:52 +0200 Subject: [PATCH 073/116] Update -> UpdateHead + UpdateTail --- src/common/packet-history.cc | 54 +++++++++++++++++++++++------------- src/common/packet-history.h | 3 +- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 91293466f..3cf072187 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -570,7 +570,7 @@ PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) } void -PacketHistory::Update (bool atStart, uint16_t written) +PacketHistory::UpdateTail (uint16_t written) { if (m_head == 0xffff) { @@ -578,15 +578,6 @@ PacketHistory::Update (bool atStart, uint16_t written) m_head = m_used; m_tail = m_used; } - else if (atStart) - { - NS_ASSERT (m_head != 0xffff); - // overwrite the prev field of the previous head of the list. - uint8_t *previousHead = &m_data->m_data[m_head] + 2; - Append16 (m_used, previousHead); - // update the head of list to the new node. - m_head = m_used; - } else { NS_ASSERT (m_tail != 0xffff); @@ -602,6 +593,31 @@ PacketHistory::Update (bool atStart, uint16_t written) m_data->m_dirtyEnd = m_used; } + +void +PacketHistory::UpdateHead (uint16_t written) +{ + if (m_head == 0xffff) + { + NS_ASSERT (m_tail == 0xffff); + m_head = m_used; + m_tail = m_used; + } + else + { + NS_ASSERT (m_head != 0xffff); + // overwrite the prev field of the previous head of the list. + uint8_t *previousHead = &m_data->m_data[m_head + 2]; + Append16 (m_used, previousHead); + // update the head of list to the new node. + m_head = m_used; + } + NS_ASSERT (m_tail != 0xffff); + NS_ASSERT (m_head != 0xffff); + m_used += written; + m_data->m_dirtyEnd = m_used; +} + uint16_t PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) { @@ -745,11 +761,11 @@ PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, PacketHistory::ExtraItem tmpExtraItem; ReadItems (current, &tmpItem, &tmpExtraItem); uint16_t written = h.AddBig (false, &tmpItem, &tmpExtraItem); - h.Update (false, written); + h.UpdateTail (written); } // append new tail. uint16_t written = h.AddBig (false, item, extraItem); - h.Update (false, written); + h.UpdateTail (written); *this = h; } @@ -895,7 +911,7 @@ PacketHistory::DoAddHeader (uint32_t uid, uint32_t size) item.chunkUid = m_chunkUid; m_chunkUid++; uint16_t written = AddSmall (&item); - Update (true, written); + UpdateHead (written); } void PacketHistory::DoRemoveHeader (uint32_t uid, uint32_t size) @@ -950,7 +966,7 @@ PacketHistory::DoAddTrailer (uint32_t uid, uint32_t size) item.chunkUid = m_chunkUid; m_chunkUid++; uint16_t written = AddSmall (&item); - Update (false, written); + UpdateTail (written); } void PacketHistory::DoRemoveTrailer (uint32_t uid, uint32_t size) @@ -1036,7 +1052,7 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { // append the extra items. uint16_t written = AddBig (false, &item, &extraItem); - Update (false, written); + UpdateTail (written); } if (current == o.m_tail) { @@ -1086,13 +1102,13 @@ PacketHistory::RemoveAtStart (uint32_t start) extraItem.fragmentStart += leftToRemove; leftToRemove = 0; uint16_t written = fragment.AddBig (false, &item, &extraItem); - fragment.Update (false, written); + fragment.UpdateTail (written); current = item.next; while (current != 0xffff) { ReadItems (current, &item, &extraItem); written = fragment.AddBig (false, &item, &extraItem); - fragment.Update (false, written); + fragment.UpdateTail (written); if (current == m_tail) { break; @@ -1145,13 +1161,13 @@ PacketHistory::RemoveAtEnd (uint32_t end) extraItem.fragmentEnd -= leftToRemove; leftToRemove = 0; uint16_t written = fragment.AddBig (true, &item, &extraItem); - fragment.Update (true, written); + fragment.UpdateHead (written); current = item.prev; while (current != 0xffff) { ReadItems (current, &item, &extraItem); written = fragment.AddBig (true, &item, &extraItem); - fragment.Update (true, written); + fragment.UpdateHead (written); if (current == m_head) { break; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 3b446dd9a..722008729 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -105,7 +105,8 @@ private: void ReplaceTail (const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem, uint32_t available); - inline void Update (bool atStart, uint16_t written); + inline void UpdateHead (uint16_t written); + inline void UpdateTail (uint16_t written); uint32_t GetUleb128Size (uint32_t value) const; inline uint32_t ReadUleb128 (const uint8_t **pBuffer) const; inline void Append16 (uint16_t value, uint8_t *buffer); From a0901958a890ffd573296cf1e9c42b577f64fd9d Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 6 Jun 2007 14:40:48 +0200 Subject: [PATCH 074/116] make some methods inline --- src/common/packet-history.cc | 63 ------------------------------- src/common/packet-history.h | 72 ++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 67 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 3cf072187..233d60b2e 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -329,69 +329,6 @@ PacketHistory::Enable (void) m_enable = true; } -PacketHistory::PacketHistory (uint32_t uid, uint32_t size) - : m_data (0), - m_head (0xffff), - m_tail (0xffff), - m_used (0), - m_packetUid (uid) -{ - if (size > 0) - { - DoAddHeader (0, size); - } -} -PacketHistory::PacketHistory (PacketHistory const &o) - : m_data (o.m_data), - m_head (o.m_head), - m_tail (o.m_tail), - m_used (o.m_used), - m_packetUid (o.m_packetUid) -{ - if (m_data != 0) - { - m_data->m_count++; - } -} -PacketHistory & -PacketHistory::operator = (PacketHistory const& o) -{ - if (m_data == o.m_data) - { - // self assignment - return *this; - } - if (m_data != 0) - { - m_data->m_count--; - if (m_data->m_count == 0) - { - PacketHistory::Recycle (m_data); - } - } - m_data = o.m_data; - m_head = o.m_head; - m_tail = o.m_tail; - m_used = o.m_used; - m_packetUid = o.m_packetUid; - if (m_data != 0) - { - m_data->m_count++; - } - return *this; -} -PacketHistory::~PacketHistory () -{ - if (m_data != 0) - { - m_data->m_count--; - if (m_data->m_count == 0) - { - PacketHistory::Recycle (m_data); - } - } -} - void PacketHistory::ReserveCopy (uint32_t size) { diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 722008729..f13658c79 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -39,10 +39,10 @@ class PacketHistory { public: static void Enable (void); - PacketHistory (uint32_t uid, uint32_t size); - PacketHistory (PacketHistory const &o); - PacketHistory &operator = (PacketHistory const& o); - ~PacketHistory (); + inline PacketHistory (uint32_t uid, uint32_t size); + inline PacketHistory (PacketHistory const &o); + inline PacketHistory &operator = (PacketHistory const& o); + inline ~PacketHistory (); template void AddHeader (T const &header, uint32_t size); @@ -172,6 +172,70 @@ PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) DoRemoveTrailer (PacketPrinter::GetTrailerUid (), size); } + +PacketHistory::PacketHistory (uint32_t uid, uint32_t size) + : m_data (0), + m_head (0xffff), + m_tail (0xffff), + m_used (0), + m_packetUid (uid) +{ + if (size > 0) + { + DoAddHeader (0, size); + } +} +PacketHistory::PacketHistory (PacketHistory const &o) + : m_data (o.m_data), + m_head (o.m_head), + m_tail (o.m_tail), + m_used (o.m_used), + m_packetUid (o.m_packetUid) +{ + if (m_data != 0) + { + m_data->m_count++; + } +} +PacketHistory & +PacketHistory::operator = (PacketHistory const& o) +{ + if (m_data == o.m_data) + { + // self assignment + return *this; + } + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } + m_data = o.m_data; + m_head = o.m_head; + m_tail = o.m_tail; + m_used = o.m_used; + m_packetUid = o.m_packetUid; + if (m_data != 0) + { + m_data->m_count++; + } + return *this; +} +PacketHistory::~PacketHistory () +{ + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } +} + }; // namespace ns3 From 8a3e4b7b142ce55f856ec7f668b917fb341df193 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 07:32:10 +0200 Subject: [PATCH 075/116] ReadItems does not depend on ReadSmall & ReadExtra --- src/common/packet-history.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 233d60b2e..f68513c15 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -729,11 +729,21 @@ PacketHistory::ReadItems (uint16_t current, struct PacketHistory::ExtraItem *extraItem) const { const uint8_t *buffer = &m_data->m_data[current]; - ReadSmall (item, &buffer); + item->next = buffer[0]; + item->next |= (buffer[1]) << 8; + item->prev = buffer[2]; + item->prev |= (buffer[3]) << 8; + buffer += 4; + item->typeUid = ReadUleb128 (&buffer); + item->size = ReadUleb128 (&buffer); + item->chunkUid = ReadUleb128 (&buffer); + bool isExtra = (item->typeUid & 0x1) == 0x1; if (isExtra) { - ReadExtra (extraItem, &buffer); + extraItem->fragmentStart = ReadUleb128 (&buffer); + extraItem->fragmentEnd = ReadUleb128 (&buffer); + extraItem->packetUid = ReadUleb128 (&buffer); } else { From e77c21195553358f9aea6e8c786f10eeec526475 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 07:39:47 +0200 Subject: [PATCH 076/116] remove ReadSmall and ReadExtra --- src/common/packet-history.cc | 64 +++++++----------------------------- src/common/packet-history.h | 2 -- 2 files changed, 12 insertions(+), 54 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index f68513c15..b8228eda5 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -707,22 +707,6 @@ PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, *this = h; } - - -void -PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const -{ - const uint8_t *buffer = *pBuffer; - item->next = buffer[0]; - item->next |= (buffer[1]) << 8; - item->prev = buffer[2]; - item->prev |= (buffer[3]) << 8; - *pBuffer = *pBuffer + 4; - item->typeUid = ReadUleb128 (pBuffer); - item->size = ReadUleb128 (pBuffer); - item->chunkUid = ReadUleb128 (pBuffer); -} - uint32_t PacketHistory::ReadItems (uint16_t current, struct PacketHistory::SmallItem *item, @@ -755,16 +739,6 @@ PacketHistory::ReadItems (uint16_t current, return buffer - &m_data->m_data[current]; } - -void -PacketHistory::ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const -{ - item->fragmentStart = ReadUleb128 (pBuffer); - item->fragmentEnd = ReadUleb128 (pBuffer); - item->packetUid = ReadUleb128 (pBuffer); -} - - struct PacketHistory::Data * PacketHistory::Create (uint32_t size) { @@ -872,25 +846,18 @@ PacketHistory::DoRemoveHeader (uint32_t uid, uint32_t size) NS_FATAL_ERROR ("Removing header from empty packet."); } struct PacketHistory::SmallItem item; - const uint8_t *buffer = &m_data->m_data[m_head]; - ReadSmall (&item, &buffer); - NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); + struct PacketHistory::ExtraItem extraItem; + ReadItems (m_head, &item, &extraItem); if ((item.typeUid & 0xfffffffe) != uid || item.size != size) { NS_FATAL_ERROR ("Removing unexpected header."); } - else if (item.typeUid != uid) + else if (item.typeUid != uid && + (extraItem.fragmentStart != 0 || + extraItem.fragmentEnd != size)) { - // this is a "big" item - struct PacketHistory::ExtraItem extraItem; - ReadExtra (&extraItem, &buffer); - NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); - if (extraItem.fragmentStart != 0 || - extraItem.fragmentEnd != size) - { - NS_FATAL_ERROR ("Removing incomplete header."); - } + NS_FATAL_ERROR ("Removing incomplete header."); } m_head = item.next; if (m_head > m_tail) @@ -927,25 +894,18 @@ PacketHistory::DoRemoveTrailer (uint32_t uid, uint32_t size) NS_FATAL_ERROR ("Removing trailer from empty packet."); } struct PacketHistory::SmallItem item; - const uint8_t *buffer = &m_data->m_data[m_tail]; - ReadSmall (&item, &buffer); - NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); + struct PacketHistory::ExtraItem extraItem; + ReadItems (m_tail, &item, &extraItem); if ((item.typeUid & 0xfffffffe) != uid || item.size != size) { NS_FATAL_ERROR ("Removing unexpected trailer."); } - else if (item.typeUid != uid) + else if (item.typeUid != uid && + (extraItem.fragmentStart != 0 || + extraItem.fragmentEnd != size)) { - // this is a "big" item - struct PacketHistory::ExtraItem extraItem; - ReadExtra (&extraItem, &buffer); - NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); - if (extraItem.fragmentStart != 0 || - extraItem.fragmentEnd != size) - { - NS_FATAL_ERROR ("Removing incomplete trailer."); - } + NS_FATAL_ERROR ("Removing incomplete trailer."); } m_tail = item.prev; if (m_tail > m_head) diff --git a/src/common/packet-history.h b/src/common/packet-history.h index f13658c79..4daf46baf 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -112,8 +112,6 @@ private: inline void Append16 (uint16_t value, uint8_t *buffer); inline bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); inline bool TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end); - void ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const; - void ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const; void Reserve (uint32_t n); void ReserveCopy (uint32_t n); uint32_t DoPrint (struct PacketHistory::SmallItem *item, uint32_t current, From a6382422df3885a4346e99e85b5c06c40e5ad86c Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 08:13:19 +0200 Subject: [PATCH 077/116] remove atStart arg to AddBig --- src/common/packet-history.cc | 38 ++++++++++++++++-------------------- src/common/packet-history.h | 6 +++--- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index b8228eda5..283c1e433 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -562,6 +562,7 @@ PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) { m_data = PacketHistory::Create (10); memset (m_data->m_data, 0xff, 4); + NS_ASSERT (m_head == 0xffff && m_tail == 0xffff); } NS_ASSERT (m_data != 0); append: @@ -598,7 +599,7 @@ PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) } uint16_t -PacketHistory::AddBig (bool atStart, +PacketHistory::AddBig (uint32_t next, uint32_t prev, const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem) { @@ -606,6 +607,7 @@ PacketHistory::AddBig (bool atStart, { m_data = PacketHistory::Create (10); memset (m_data->m_data, 0xff, 4); + NS_ASSERT (m_head == 0xffff && m_tail == 0xffff); } NS_ASSERT (m_data != 0); uint32_t typeUid = ((item->typeUid & 0x1) == 0x1)?item->typeUid:item->typeUid+1; @@ -618,17 +620,6 @@ PacketHistory::AddBig (bool atStart, m_used == m_data->m_dirtyEnd)) { uint8_t *buffer = start; - uint16_t next, prev; - if (atStart) - { - next = m_head; - prev = 0xffff; - } - else - { - next = 0xffff; - prev = m_tail; - } Append16 (next, buffer); buffer += 2; @@ -661,8 +652,8 @@ PacketHistory::AddBig (bool atStart, } void -PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem, +PacketHistory::ReplaceTail (PacketHistory::SmallItem *item, + PacketHistory::ExtraItem *extraItem, uint32_t available) { NS_ASSERT (m_data != 0); @@ -697,11 +688,12 @@ PacketHistory::ReplaceTail (const PacketHistory::SmallItem *item, struct PacketHistory::SmallItem tmpItem; PacketHistory::ExtraItem tmpExtraItem; ReadItems (current, &tmpItem, &tmpExtraItem); - uint16_t written = h.AddBig (false, &tmpItem, &tmpExtraItem); + uint16_t written = h.AddBig (0xffff, h.m_tail, + &tmpItem, &tmpExtraItem); h.UpdateTail (written); } // append new tail. - uint16_t written = h.AddBig (false, item, extraItem); + uint16_t written = h.AddBig (0xffff, h.m_tail, item, extraItem); h.UpdateTail (written); *this = h; @@ -958,7 +950,7 @@ PacketHistory::AddAtEnd (PacketHistory const&o) else { // append the extra items. - uint16_t written = AddBig (false, &item, &extraItem); + uint16_t written = AddBig (0xffff, m_tail, &item, &extraItem); UpdateTail (written); } if (current == o.m_tail) @@ -1008,13 +1000,15 @@ PacketHistory::RemoveAtStart (uint32_t start) PacketHistory fragment (m_packetUid, 0); extraItem.fragmentStart += leftToRemove; leftToRemove = 0; - uint16_t written = fragment.AddBig (false, &item, &extraItem); + uint16_t written = fragment.AddBig (0xffff, fragment.m_tail, + &item, &extraItem); fragment.UpdateTail (written); current = item.next; while (current != 0xffff) { ReadItems (current, &item, &extraItem); - written = fragment.AddBig (false, &item, &extraItem); + written = fragment.AddBig (0xffff, fragment.m_tail, + &item, &extraItem); fragment.UpdateTail (written); if (current == m_tail) { @@ -1067,13 +1061,15 @@ PacketHistory::RemoveAtEnd (uint32_t end) NS_ASSERT (extraItem.fragmentEnd > leftToRemove); extraItem.fragmentEnd -= leftToRemove; leftToRemove = 0; - uint16_t written = fragment.AddBig (true, &item, &extraItem); + uint16_t written = fragment.AddBig (fragment.m_head, 0xffff, + &item, &extraItem); fragment.UpdateHead (written); current = item.prev; while (current != 0xffff) { ReadItems (current, &item, &extraItem); - written = fragment.AddBig (true, &item, &extraItem); + written = fragment.AddBig (fragment.m_head, 0xffff, + &item, &extraItem); fragment.UpdateHead (written); if (current == m_head) { diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 4daf46baf..5fdb90eed 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -99,11 +99,11 @@ private: void DoRemoveTrailer (uint32_t uid, uint32_t size); uint16_t AddSmall (const PacketHistory::SmallItem *item); - uint16_t AddBig (bool atStart, + uint16_t AddBig (uint32_t head, uint32_t tail, const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem); - void ReplaceTail (const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem, + void ReplaceTail (PacketHistory::SmallItem *item, + PacketHistory::ExtraItem *extraItem, uint32_t available); inline void UpdateHead (uint16_t written); inline void UpdateTail (uint16_t written); From 4b95d67beaee8f89c067a60e576380136f27a8d2 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 09:18:04 +0200 Subject: [PATCH 078/116] optimize a bit AddHeader --- src/common/packet-history.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 5fdb90eed..93e2d8099 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -98,7 +98,7 @@ private: void DoAddTrailer (uint32_t uid, uint32_t size); void DoRemoveTrailer (uint32_t uid, uint32_t size); - uint16_t AddSmall (const PacketHistory::SmallItem *item); + inline uint16_t AddSmall (const PacketHistory::SmallItem *item); uint16_t AddBig (uint32_t head, uint32_t tail, const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem); @@ -108,7 +108,7 @@ private: inline void UpdateHead (uint16_t written); inline void UpdateTail (uint16_t written); uint32_t GetUleb128Size (uint32_t value) const; - inline uint32_t ReadUleb128 (const uint8_t **pBuffer) const; + uint32_t ReadUleb128 (const uint8_t **pBuffer) const; inline void Append16 (uint16_t value, uint8_t *buffer); inline bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); inline bool TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end); From 49abdbd0092134ab984bddac65a2d6bc4b5f07fd Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 09:38:51 +0200 Subject: [PATCH 079/116] fix Append and optimize GetUleb128Size --- src/common/packet-history.cc | 59 ++++++++++++++++++++++++------------ src/common/packet-history.h | 2 +- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 283c1e433..16dd5c7d0 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -310,17 +310,6 @@ PacketHistory::PrintStats (void) g_three = 0; g_four = 0; g_five = 0; -#if 0 - PacketHistory h (0, 0); - for (uint32_t i = 0; i < 0xffffff; i++) - { - if (h.GetUleb128Size (i) == 4) - { - std::cout << i << std::endl; - break; - } - } -#endif } void @@ -375,13 +364,23 @@ PacketHistory::Reserve (uint32_t size) uint32_t PacketHistory::GetUleb128Size (uint32_t value) const { - uint32_t n = 0; - uint32_t tmp = value; - do { - tmp >>= 7; - n++; - } while (tmp != 0); - return n; + if (value < 0x80) + { + return 1; + } + if (value < 0x4000) + { + return 2; + } + if (value < 0x200000) + { + return 3; + } + if (value < 0x10000000) + { + return 4; + } + return 5; } uint32_t PacketHistory::ReadUleb128 (const uint8_t **pBuffer) const @@ -484,25 +483,47 @@ PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) uint8_t byte = value & (~0x80); start[0] = 0x80 | byte; value >>= 7; + byte = value & (~0x80); start[1] = 0x80 | byte; value >>= 7; + byte = value & (~0x80); start[2] = value; *pBuffer = start + 3; return true; } - if (start + 3 < end) + if (value < 0x10000000 && start + 3 < end) { uint8_t byte = value & (~0x80); start[0] = 0x80 | byte; value >>= 7; + byte = value & (~0x80); start[1] = 0x80 | byte; value >>= 7; + byte = value & (~0x80); start[2] = 0x80 | byte; value >>= 7; start[3] = value; *pBuffer = start + 4; return true; } + if (start + 4 < end) + { + uint8_t byte = value & (~0x80); + start[0] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + start[1] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + start[2] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + start[3] = 0x80 | byte; + value >>= 7; + start[4] = value; + *pBuffer = start + 5; + return true; + } return false; } diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 93e2d8099..2db574aed 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -107,7 +107,7 @@ private: uint32_t available); inline void UpdateHead (uint16_t written); inline void UpdateTail (uint16_t written); - uint32_t GetUleb128Size (uint32_t value) const; + inline uint32_t GetUleb128Size (uint32_t value) const; uint32_t ReadUleb128 (const uint8_t **pBuffer) const; inline void Append16 (uint16_t value, uint8_t *buffer); inline bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); From 8361cbab71bdab02f1e1cc9f277f36ab2b37cbd3 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 10:38:48 +0200 Subject: [PATCH 080/116] try alternative implementation of AddSmall --- src/common/packet-history.cc | 105 +++++++++++++++++++++++++++++++++-- src/common/packet-history.h | 6 +- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 16dd5c7d0..1e4fd5ddc 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -299,8 +299,8 @@ PacketHistory::PrintStats (void) { std::cout << "allocs="< Date: Thu, 7 Jun 2007 11:00:49 +0200 Subject: [PATCH 082/116] unconditionally set m_data --- src/common/packet-history.cc | 38 ++++-------------------------------- src/common/packet-history.h | 36 ++++++++++++++-------------------- 2 files changed, 19 insertions(+), 55 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 1e4fd5ddc..0571fd690 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -645,12 +645,6 @@ PacketHistory::UpdateHead (uint16_t written) uint16_t PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) { - if (m_data == 0) - { - m_data = PacketHistory::Create (10); - memset (m_data->m_data, 0xff, 4); - NS_ASSERT (m_head == 0xffff && m_tail == 0xffff); - } NS_ASSERT (m_data != 0); #if 1 append: @@ -721,12 +715,6 @@ PacketHistory::AddBig (uint32_t next, uint32_t prev, const PacketHistory::SmallItem *item, const PacketHistory::ExtraItem *extraItem) { - if (m_data == 0) - { - m_data = PacketHistory::Create (10); - memset (m_data->m_data, 0xff, 4); - NS_ASSERT (m_head == 0xffff && m_tail == 0xffff); - } NS_ASSERT (m_data != 0); uint32_t typeUid = ((item->typeUid & 0x1) == 0x1)?item->typeUid:item->typeUid+1; append: @@ -951,10 +939,6 @@ PacketHistory::DoRemoveHeader (uint32_t uid, uint32_t size) { return; } - if (m_data == 0) - { - NS_FATAL_ERROR ("Removing header from empty packet."); - } struct PacketHistory::SmallItem item; struct PacketHistory::ExtraItem extraItem; ReadItems (m_head, &item, &extraItem); @@ -999,10 +983,6 @@ PacketHistory::DoRemoveTrailer (uint32_t uid, uint32_t size) { return; } - if (m_data == 0) - { - NS_FATAL_ERROR ("Removing trailer from empty packet."); - } struct PacketHistory::SmallItem item; struct PacketHistory::ExtraItem extraItem; ReadItems (m_tail, &item, &extraItem); @@ -1030,7 +1010,7 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { return; } - if (m_data == 0 || m_tail == 0xffff) + if (m_tail == 0xffff) { *this = o; return; @@ -1093,11 +1073,7 @@ PacketHistory::RemoveAtStart (uint32_t start) { return; } - if (m_data == 0) - { - NS_FATAL_ERROR ("Removing data from start of empty packet."); - } - + NS_ASSERT (m_data != 0); uint32_t leftToRemove = start; uint16_t current = m_head; while (current != 0xffff && leftToRemove > 0) @@ -1153,10 +1129,7 @@ PacketHistory::RemoveAtEnd (uint32_t end) { return; } - if (m_data == 0) - { - NS_FATAL_ERROR ("Removing data from start of empty packet."); - } + NS_ASSERT (m_data != 0); uint32_t leftToRemove = end; uint16_t current = m_tail; @@ -1282,10 +1255,7 @@ PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printe { return; } - if (m_data == 0) - { - return; - } + NS_ASSERT (m_data != 0); NS_ASSERT (GetTotalSize () == data.GetSize ()); if (printer.m_forward) { diff --git a/src/common/packet-history.h b/src/common/packet-history.h index d2d354ef8..7f82f410f 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -24,6 +24,7 @@ #include #include #include "ns3/callback.h" +#include "ns3/assert.h" #include "packet-printer.h" namespace { @@ -174,12 +175,13 @@ PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) PacketHistory::PacketHistory (uint32_t uid, uint32_t size) - : m_data (0), + : m_data (m_data = PacketHistory::Create (10)), m_head (0xffff), m_tail (0xffff), m_used (0), m_packetUid (uid) { + memset (m_data->m_data, 0xff, 4); if (size > 0) { DoAddHeader (0, size); @@ -192,10 +194,8 @@ PacketHistory::PacketHistory (PacketHistory const &o) m_used (o.m_used), m_packetUid (o.m_packetUid) { - if (m_data != 0) - { - m_data->m_count++; - } + NS_ASSERT (m_data != 0); + m_data->m_count++; } PacketHistory & PacketHistory::operator = (PacketHistory const& o) @@ -205,34 +205,28 @@ PacketHistory::operator = (PacketHistory const& o) // self assignment return *this; } - if (m_data != 0) + NS_ASSERT (m_data != 0); + m_data->m_count--; + if (m_data->m_count == 0) { - m_data->m_count--; - if (m_data->m_count == 0) - { - PacketHistory::Recycle (m_data); - } + PacketHistory::Recycle (m_data); } m_data = o.m_data; m_head = o.m_head; m_tail = o.m_tail; m_used = o.m_used; m_packetUid = o.m_packetUid; - if (m_data != 0) - { - m_data->m_count++; - } + NS_ASSERT (m_data != 0); + m_data->m_count++; return *this; } PacketHistory::~PacketHistory () { - if (m_data != 0) + NS_ASSERT (m_data != 0); + m_data->m_count--; + if (m_data->m_count == 0) { - m_data->m_count--; - if (m_data->m_count == 0) - { - PacketHistory::Recycle (m_data); - } + PacketHistory::Recycle (m_data); } } From 40e654dd222747d1d69d5b067c5bd49630f07d4b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 11:21:21 +0200 Subject: [PATCH 083/116] store chunkUid and packetUid as fixed-size fields --- src/common/packet-history.cc | 65 +++++++++++++++++++++++++++--------- src/common/packet-history.h | 2 ++ 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 0571fd690..6a9bad059 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -461,6 +461,34 @@ PacketHistory::TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end) return false; } bool +PacketHistory::TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end) +{ + uint8_t *start = *pBuffer; + if (start + 1 < end) + { + start[0] = value & 0xff; + start[1] = value >> 8; + *pBuffer = start + 2; + return true; + } + return false; +} +bool +PacketHistory::TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end) +{ + uint8_t *start = *pBuffer; + if (start + 3 < end) + { + start[0] = value & 0xff; + start[1] = (value >> 8) & 0xff; + start[2] = (value >> 16) & 0xff; + start[3] = (value >> 24) & 0xff; + *pBuffer = start + 4; + return true; + } + return false; +} +bool PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) { uint8_t *start = *pBuffer; @@ -650,7 +678,7 @@ PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) append: uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; - if (end - start >= 7 && + if (end - start >= 8 && (m_head == 0xffff || m_data->m_count == 1 || m_used == m_data->m_dirtyEnd)) @@ -663,7 +691,7 @@ PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) buffer += 2; if (TryToAppendFast (item->typeUid, &buffer, end) && TryToAppendFast (item->size, &buffer, end) && - TryToAppend (item->chunkUid, &buffer, end)) + TryToAppend16 (item->chunkUid, &buffer, end)) { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); @@ -674,15 +702,14 @@ PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) g_two++; uint32_t n = GetUleb128Size (item->typeUid); n += GetUleb128Size (item->size); - n += GetUleb128Size (item->chunkUid); + n += 2; n += 2 + 2; Reserve (n); goto append; #else uint32_t typeUidSize = GetUleb128Size (item->typeUid); uint32_t sizeSize = GetUleb128Size (item->size); - uint32_t chunkUidSize = GetUleb128Size (item->chunkUid); - uint32_t n = typeUidSize + sizeSize + chunkUidSize + 2 + 2; + uint32_t n = typeUidSize + sizeSize + 2 + 2 + 2; restart: if (m_used + n <= m_data->m_size && (m_head == 0xffff || @@ -698,7 +725,7 @@ PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) buffer += typeUidSize; AppendValue (item->size, buffer); buffer += sizeSize; - AppendValue (item->chunkUid, buffer); + Append16 (item->chunkUid, buffer); } else { @@ -720,7 +747,7 @@ PacketHistory::AddBig (uint32_t next, uint32_t prev, append: uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; - if (end - start >= 10 && + if (end - start >= 14 && (m_head == 0xffff || m_data->m_count == 1 || m_used == m_data->m_dirtyEnd)) @@ -733,10 +760,10 @@ PacketHistory::AddBig (uint32_t next, uint32_t prev, buffer += 2; if (TryToAppend (typeUid, &buffer, end) && TryToAppend (item->size, &buffer, end) && - TryToAppend (item->chunkUid, &buffer, end) && + TryToAppend16 (item->chunkUid, &buffer, end) && TryToAppend (extraItem->fragmentStart, &buffer, end) && TryToAppend (extraItem->fragmentEnd, &buffer, end) && - TryToAppend (extraItem->packetUid, &buffer, end)) + TryToAppend32 (extraItem->packetUid, &buffer, end)) { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); @@ -748,10 +775,10 @@ PacketHistory::AddBig (uint32_t next, uint32_t prev, g_two++; uint32_t n = GetUleb128Size (typeUid); n += GetUleb128Size (item->size); - n += GetUleb128Size (item->chunkUid); + n += 2; n += GetUleb128Size (extraItem->fragmentStart); n += GetUleb128Size (extraItem->fragmentEnd); - n += GetUleb128Size (extraItem->packetUid); + n += 4; n += 2 + 2; ReserveCopy (n); goto append; @@ -763,7 +790,7 @@ PacketHistory::ReplaceTail (PacketHistory::SmallItem *item, uint32_t available) { NS_ASSERT (m_data != 0); - if (available >= 10 && + if (available >= 14 && m_data->m_count == 1) { uint8_t *buffer = &m_data->m_data[m_tail]; @@ -775,10 +802,10 @@ PacketHistory::ReplaceTail (PacketHistory::SmallItem *item, buffer += 2; if (TryToAppend (item->typeUid, &buffer, end) && TryToAppend (item->size, &buffer, end) && - TryToAppend (item->chunkUid, &buffer, end) && + TryToAppend16 (item->chunkUid, &buffer, end) && TryToAppend (extraItem->fragmentStart, &buffer, end) && TryToAppend (extraItem->fragmentEnd, &buffer, end) && - TryToAppend (extraItem->packetUid, &buffer, end)) + TryToAppend32 (extraItem->packetUid, &buffer, end)) { m_used = buffer - &m_data->m_data[0]; m_data->m_dirtyEnd = m_used; @@ -818,14 +845,20 @@ PacketHistory::ReadItems (uint16_t current, buffer += 4; item->typeUid = ReadUleb128 (&buffer); item->size = ReadUleb128 (&buffer); - item->chunkUid = ReadUleb128 (&buffer); + item->chunkUid = buffer[0]; + item->chunkUid |= (buffer[1]) << 8; + buffer += 2; bool isExtra = (item->typeUid & 0x1) == 0x1; if (isExtra) { extraItem->fragmentStart = ReadUleb128 (&buffer); extraItem->fragmentEnd = ReadUleb128 (&buffer); - extraItem->packetUid = ReadUleb128 (&buffer); + extraItem->packetUid = buffer[0]; + extraItem->packetUid |= buffer[1] << 8; + extraItem->packetUid |= buffer[2] << 16; + extraItem->packetUid |= buffer[3] << 24; + buffer += 4; } else { diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 7f82f410f..d90d5131a 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -113,6 +113,8 @@ private: inline void Append16 (uint16_t value, uint8_t *buffer); inline bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end); inline bool TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end); + inline bool TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end); + inline bool TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end); void AppendValue (uint32_t value, uint8_t *buffer); void AppendValueExtra (uint32_t value, uint8_t *buffer); inline void Reserve (uint32_t n); From fb3786c1377c77649ff05329f00d6cc1d919b9ce Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 11:38:06 +0200 Subject: [PATCH 084/116] remove dead code --- src/common/packet-history.cc | 381 ----------------------------------- src/common/packet-history.h | 4 - utils/bench-packets.cc | 3 - 3 files changed, 388 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 6a9bad059..36dd29a6a 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -29,288 +29,12 @@ NS_DEBUG_COMPONENT_DEFINE ("PacketHistory"); -#define USE_ULEB 1 - -namespace { - -class ItemList -{ -public: - void InitPayload (uint32_t packetUid, uint32_t size); - void AddHeader (uint32_t type, uint32_t size); - void AddTrailer (uint32_t type, uint32_t size); - - void RemHeader (uint32_t type, uint32_t size); - void RemTrailer (uint32_t type, uint32_t size); - - void RemAtStart (uint32_t toRemove); - void RemAtEnd (uint32_t toRemove); - - void AddAtEnd (ItemList const *other); - - void Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter &printer) const; - -private: - enum Type { - PAYLOAD, - HEADER, - TRAILER, - }; - struct Item - { - enum ItemList::Type m_type; - uint32_t m_size; - uint32_t m_chunkType; - uint32_t m_fragmentStart; - uint32_t m_fragmentEnd; - uint32_t m_packetUid; - uint32_t m_chunkUid; - }; - std::list m_itemList; - uint32_t m_packetUid; - uint32_t m_chunkUid; -}; - - -void -ItemList::InitPayload (uint32_t packetUid, uint32_t size) -{ - NS_ASSERT (m_itemList.empty ()); - m_packetUid = packetUid; - m_chunkUid = 1; - if (size > 0) - { - struct Item item; - item.m_type = ItemList::PAYLOAD; - item.m_chunkType = 0; - item.m_size = size; - item.m_fragmentStart = 0; - item.m_fragmentEnd = item.m_size; - item.m_packetUid = m_packetUid; - item.m_chunkUid = m_chunkUid; - m_itemList.push_back (item); - } -} - -void -ItemList::AddHeader (uint32_t type, uint32_t size) -{ - struct Item item; - item.m_type = ItemList::HEADER; - item.m_chunkType = type; - item.m_size = size; - item.m_fragmentStart = 0; - item.m_fragmentEnd = size; - item.m_packetUid = m_packetUid; - item.m_chunkUid = m_chunkUid; - m_itemList.push_front (item); - m_chunkUid++; -} - -void -ItemList::AddTrailer (uint32_t type, uint32_t size) -{ - struct Item item; - item.m_type = ItemList::TRAILER; - item.m_chunkType = type; - item.m_size = size; - item.m_fragmentStart = 0; - item.m_fragmentEnd = size; - item.m_packetUid = m_packetUid; - item.m_chunkUid = m_chunkUid; - m_itemList.push_back (item); - m_chunkUid++; -} - -void -ItemList::RemHeader (uint32_t type, uint32_t size) -{ - struct Item item = m_itemList.front (); - if (item.m_type != ItemList::HEADER || - item.m_size != size || - item.m_chunkType != type) - { - NS_FATAL_ERROR ("Removing Unexpected header"); - } - else if (item.m_fragmentStart != 0 || - item.m_fragmentEnd != item.m_size) - { - NS_FATAL_ERROR ("Removing non-complete header"); - } - m_itemList.pop_front (); -} -void -ItemList::RemTrailer (uint32_t type, uint32_t size) -{ - struct Item item = m_itemList.back (); - if (item.m_type != ItemList::TRAILER || - item.m_size != size || - item.m_chunkType != type) - { - NS_FATAL_ERROR ("Removing Unexpected trailer"); - } - else if (item.m_fragmentStart != 0 || - item.m_fragmentEnd != item.m_size) - { - NS_FATAL_ERROR ("Removing non-complete trailer"); - } - m_itemList.pop_back (); -} - -void -ItemList::RemAtStart (uint32_t toRemove) -{ - uint32_t leftToRemove = toRemove; - while (!m_itemList.empty () && leftToRemove > 0) - { - struct Item &item = m_itemList.front (); - uint32_t itemRealSize = item.m_fragmentEnd - item.m_fragmentStart; - if (itemRealSize <= leftToRemove) - { - m_itemList.pop_front (); - leftToRemove -= itemRealSize; - } - else - { - item.m_fragmentStart += leftToRemove; - leftToRemove = 0; - NS_ASSERT (item.m_size >= item.m_fragmentEnd - item.m_fragmentStart && - item.m_fragmentStart <= item.m_fragmentEnd); - } - } - NS_ASSERT (leftToRemove == 0); -} -void -ItemList::RemAtEnd (uint32_t toRemove) -{ - uint32_t leftToRemove = toRemove; - while (!m_itemList.empty () && leftToRemove > 0) - { - struct Item &item = m_itemList.back (); - uint32_t itemRealSize = item.m_fragmentEnd - item.m_fragmentStart; - if (itemRealSize <= leftToRemove) - { - m_itemList.pop_back (); - leftToRemove -= itemRealSize; - } - else - { - item.m_fragmentEnd -= leftToRemove; - leftToRemove = 0; - } - NS_ASSERT (item.m_size >= item.m_fragmentEnd - item.m_fragmentStart && - item.m_fragmentStart <= item.m_fragmentEnd && - item.m_fragmentEnd <= item.m_size); - } - NS_ASSERT (leftToRemove == 0); -} - -void -ItemList::AddAtEnd (ItemList const *other) -{ - ItemList::Item &last = m_itemList.back (); - for (std::list::const_iterator i = other->m_itemList.begin (); - i != other->m_itemList.end (); i++) - { - const ItemList::Item &item = *i; - if (item.m_packetUid == last.m_packetUid && - item.m_type == last.m_type && - item.m_chunkType == last.m_chunkType && - item.m_size == last.m_size && - last.m_fragmentEnd != last.m_size && - item.m_fragmentStart == last.m_fragmentEnd && - item.m_chunkUid == last.m_chunkUid) - { - last.m_fragmentEnd = item.m_fragmentEnd; - } - else - { - m_itemList.push_back (item); - } - } -} - -void -ItemList::Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter &printer) const -{ - uint32_t totalSize = 0; - for (std::list::const_iterator i = m_itemList.begin (); - i != m_itemList.end (); i++) - { - ItemList::Item item = *i; - totalSize += item.m_fragmentEnd - item.m_fragmentStart; - } - NS_ASSERT (totalSize == buffer.GetSize ()); - uint32_t offset = 0; - for (std::list::const_iterator i = m_itemList.begin (); - i != m_itemList.end (); i++) - { - ItemList::Item item = *i; - if (item.m_type == ItemList::PAYLOAD) - { - printer.PrintPayload (os, item.m_packetUid, item.m_size, item.m_fragmentStart, item.m_fragmentEnd); - } - else if (item.m_fragmentStart != 0 || - item.m_fragmentEnd != item.m_size) - { - printer.PrintChunkFragment (item.m_chunkType, os, item.m_packetUid, item.m_size, - item.m_fragmentStart, item.m_fragmentEnd); - } - else if (item.m_type == ItemList::HEADER) - { - ns3::Buffer::Iterator j = buffer.Begin (); - j.Next (offset); - printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size); - } - else if (item.m_type == ItemList::TRAILER) - { - ns3::Buffer::Iterator j = buffer.End (); - j.Prev (totalSize - (offset + item.m_size)); - printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size); - } - else - { - NS_ASSERT (false); - } - offset += item.m_fragmentEnd - item.m_fragmentStart; - } -} - -} // anonymous namespace - namespace ns3 { bool PacketHistory::m_enable = false; uint32_t PacketHistory::m_maxSize = 0; uint16_t PacketHistory::m_chunkUid = 0; PacketHistory::DataFreeList PacketHistory::m_freeList; -uint32_t g_nAllocs = 0; -uint32_t g_nDeAllocs = 0; -uint32_t g_nRecycle = 0; -uint32_t g_nCreate = 0; - uint32_t g_one = 0; - uint32_t g_two = 0; - uint32_t g_three = 0; - uint32_t g_four = 0; - uint32_t g_five = 0; - -void -PacketHistory::PrintStats (void) -{ - std::cout << "allocs="< Date: Thu, 7 Jun 2007 12:17:25 +0200 Subject: [PATCH 085/116] rename History::Enable to Packet::EnableMetadata --- src/common/packet.cc | 6 ++++++ src/common/packet.h | 2 ++ utils/bench-packets.cc | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/common/packet.cc b/src/common/packet.cc index 4796d86e6..f27136fd9 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -141,4 +141,10 @@ Packet::Print (std::ostream &os, const PacketPrinter &printer) const m_history.Print (os, m_buffer, printer); } +void +Packet::EnableMetadata (void) +{ + PacketHistory::Enable (); +} + }; // namespace ns3 diff --git a/src/common/packet.h b/src/common/packet.h index db4d8cb74..921e3f968 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -257,6 +257,8 @@ public: void Print (std::ostream &os) const; void Print (std::ostream &os, const PacketPrinter &printer) const; + + static void EnableMetadata (void); private: Packet (Buffer buffer, Tags tags, PacketHistory history, uint32_t uid); Buffer m_buffer; diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index 2e3e0e490..e3c66011c 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -179,9 +179,9 @@ int main (int argc, char *argv[]) char const *nAscii = argv[0] + strlen ("--n="); n = atoi (nAscii); } - if (strncmp ("--enable-history", argv[0], strlen ("--enable-history")) == 0) + if (strncmp ("--enable-history", argv[0], strlen ("--enable-metadata")) == 0) { - PacketHistory::Enable (); + Packet::EnableMetadata (); } argc--; argv++; From 8435bfc4febe19bc5a79f0fbd7b30eede73d17ee Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 12:25:40 +0200 Subject: [PATCH 086/116] add back optimization option --- src/common/packet-history.cc | 101 +++++++++++++++++++++++++++++++++++ src/common/packet-history.h | 9 ++-- utils/bench-packets.cc | 2 +- 3 files changed, 107 insertions(+), 5 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 36dd29a6a..f845fd678 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -35,6 +35,7 @@ bool PacketHistory::m_enable = false; uint32_t PacketHistory::m_maxSize = 0; uint16_t PacketHistory::m_chunkUid = 0; PacketHistory::DataFreeList PacketHistory::m_freeList; +bool g_optOne = false; void PacketHistory::Enable (void) @@ -42,6 +43,12 @@ PacketHistory::Enable (void) m_enable = true; } +void +PacketHistory::SetOptOne (bool optOne) +{ + g_optOne = optOne; +} + void PacketHistory::ReserveCopy (uint32_t size) { @@ -278,6 +285,71 @@ PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) return false; } +void +PacketHistory::AppendValueExtra (uint32_t value, uint8_t *buffer) +{ + if (value < 0x200000) + { + uint8_t byte = value & (~0x80); + buffer[0] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + buffer[1] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + buffer[2] = value; + return; + } + if (value < 0x10000000) + { + uint8_t byte = value & (~0x80); + buffer[0] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + buffer[1] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + buffer[2] = 0x80 | byte; + value >>= 7; + buffer[3] = value; + return; + } + { + uint8_t byte = value & (~0x80); + buffer[0] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + buffer[1] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + buffer[2] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + buffer[3] = 0x80 | byte; + value >>= 7; + buffer[4] = value; + } +} + +void +PacketHistory::AppendValue (uint32_t value, uint8_t *buffer) +{ + if (value < 0x80) + { + buffer[0] = value; + return; + } + if (value < 0x4000) + { + uint8_t byte = value & (~0x80); + buffer[0] = 0x80 | byte; + value >>= 7; + buffer[1] = value; + return; + } + AppendValueExtra (value, buffer); +} + void PacketHistory::UpdateTail (uint16_t written) { @@ -331,6 +403,35 @@ uint16_t PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) { NS_ASSERT (m_data != 0); + if (g_optOne) + { + uint32_t typeUidSize = GetUleb128Size (item->typeUid); + uint32_t sizeSize = GetUleb128Size (item->size); + uint32_t n = typeUidSize + sizeSize + 2 + 2 + 2; + restart: + if (m_used + n <= m_data->m_size && + (m_head == 0xffff || + m_data->m_count == 1 || + m_used == m_data->m_dirtyEnd)) + { + uint8_t *buffer = &m_data->m_data[m_used]; + Append16 (item->next, buffer); + buffer += 2; + Append16 (item->prev, buffer); + buffer += 2; + AppendValue (item->typeUid, buffer); + buffer += typeUidSize; + AppendValue (item->size, buffer); + buffer += sizeSize; + Append16 (item->chunkUid, buffer); + } + else + { + ReserveCopy (n); + goto restart; + } + return n; + } append: uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 084893bfb..a0424c8f6 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -27,10 +27,6 @@ #include "ns3/assert.h" #include "packet-printer.h" -namespace { -class ItemList; -} - namespace ns3 { class Chunk; @@ -39,6 +35,7 @@ class Buffer; class PacketHistory { public: static void Enable (void); + static void SetOptOne (bool optOne); inline PacketHistory (uint32_t uid, uint32_t size); inline PacketHistory (PacketHistory const &o); @@ -64,6 +61,8 @@ public: void PrintDefault (std::ostream &os, Buffer buffer) const; void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const; + static void PrintStats (void); + private: /** head -(next)-> tail @@ -113,6 +112,8 @@ private: inline bool TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end); inline bool TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end); inline bool TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end); + void AppendValue (uint32_t value, uint8_t *buffer); + void AppendValueExtra (uint32_t value, uint8_t *buffer); inline void Reserve (uint32_t n); void ReserveCopy (uint32_t n); uint32_t DoPrint (struct PacketHistory::SmallItem *item, uint32_t current, diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index e3c66011c..c18444536 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -179,7 +179,7 @@ int main (int argc, char *argv[]) char const *nAscii = argv[0] + strlen ("--n="); n = atoi (nAscii); } - if (strncmp ("--enable-history", argv[0], strlen ("--enable-metadata")) == 0) + if (strncmp ("--enable-metadata", argv[0], strlen ("--enable-metadata")) == 0) { Packet::EnableMetadata (); } From 12476595ad84ad32195cfde3ba196a34a2187b0d Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 12:29:27 +0200 Subject: [PATCH 087/116] improve dox doc --- src/common/packet-printer.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 416bcc7de..26dcf1aa7 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -34,6 +34,12 @@ namespace ns3 { class Chunk; +/** + * \brief hold a list of print callbacks for packet headers and trailers + * + * Users can register in instances of this class print callbacks + * which are used by Packet::Print to print the content of a packet. + */ class PacketPrinter { public: @@ -83,6 +89,10 @@ public: /** * \param printer printer for the specified chunk * \param fragmentPrinter printer for a fragment of the specified chunk + * + * If the user has not specified a callback for a specific header present + * in a packet, the "default" callback is invoked. If no such callback + * was specified, nothing happens. */ template void AddHeaderPrinter (Callback printer, @@ -90,6 +100,10 @@ public: /** * \param printer printer for the specified chunk * \param fragmentPrinter printer for a fragment of the specified chunk + * + * If the user has not specified a callback for a specific trailer present + * in a packet, the "default" callback is invoked. If no such callback + * was specified, nothing happens. */ template void AddTrailerPrinter (Callback printer, From 2b3882fb1ae464dc9cac03dc5fbcf3a74529a88f Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 12:29:38 +0200 Subject: [PATCH 088/116] make the code match the dox doc --- src/common/packet-printer.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 97c5a28f2..9d0627635 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -97,7 +97,10 @@ PacketPrinter::PrintChunk (uint32_t chunkUid, struct PacketPrinter::FragmentInformation info; info.start = 0; info.end = size; - m_defaultPrinter (os, packetUid, size, name, info); + if (!m_defaultPrinter.IsNull ()) + { + m_defaultPrinter (os, packetUid, size, name, info); + } } void PacketPrinter::PrintChunkFragment (uint32_t chunkUid, @@ -122,7 +125,10 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid, return; } } - m_defaultPrinter (os, packetUid, size, name, info); + if (!m_defaultPrinter.IsNull ()) + { + m_defaultPrinter (os, packetUid, size, name, info); + } } void PacketPrinter::PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size, From c6f42b1cff846a3b14ee19a97481d842d968c753 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 12:30:52 +0200 Subject: [PATCH 089/116] constify Callback::IsNull --- src/core/callback.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/callback.h b/src/core/callback.h index 64e92ccd8..a6c89a7a1 100644 --- a/src/core/callback.h +++ b/src/core/callback.h @@ -280,7 +280,7 @@ public: : m_impl (impl) {} - bool IsNull (void) { + bool IsNull (void) const { return (PeekImpl () == 0)?true:false; } void Nullify (void) { From 1ba5c012813c93e9f677f60bd8f5feb3d4c6f2a8 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 12:42:44 +0200 Subject: [PATCH 090/116] more dox --- src/common/packet.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/common/packet.h b/src/common/packet.h index 921e3f968..184ac6756 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -255,9 +255,44 @@ public: */ uint32_t GetUid (void) const; + /** + * \param os output stream in which the data should be printed. + * + * Iterate over the headers and trailers present in this packet, + * from the first header to the last trailer and invoke, for + * each of them, the user-provided method Header::DoPrint or + * Trailer::DoPrint methods. + */ void Print (std::ostream &os) const; + /** + * \param os output stream in which the data should be printed. + * \param printer the output formatter to use to print + * the content of this packet. + * + * Iterate over the headers and trailers present in this packet, + * either in the "forward" (first header to last trailer) or in + * the "backward" (last trailer to first header) direction, as + * specified by the PacketPrinter::PrintForward or the + * PacketPrinter::PrintBackward methods. For each header, trailer, + * or fragment of a header or a trailer, invoke the user-specified + * print callback stored in the specified PacketPrinter. + */ void Print (std::ostream &os, const PacketPrinter &printer) const; + /** + * By default, packets do not keep around enough metadata to + * perform the operations requested by the Print methods. If you + * want to be able to invoke any of the two ::Print methods, + * you need to invoke this method at least once during the + * simulation setup and before any packet is created. + * + * The packet metadata is also used to perform extensive + * sanity checks at runtime when performing operations on a + * Packet. For example, this metadata is used to verify that + * when you remove a header from a packet, this same header + * was actually present at the front of the packet. These + * errors will be detected and will abort the program. + */ static void EnableMetadata (void); private: Packet (Buffer buffer, Tags tags, PacketHistory history, uint32_t uid); From 6e2d89844307e2f04c5482a376681747f447cf90 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 12:44:44 +0200 Subject: [PATCH 091/116] add an option to control the history implementation --- utils/bench-packets.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index c18444536..64f0a44df 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -188,10 +188,14 @@ int main (int argc, char *argv[]) } - + PacketHistory::SetOptOne (false); runBench (&benchPtrA, n, "a"); runBench (&benchPtrB, n, "b"); runBench (&benchPtrC, n, "c"); + PacketHistory::SetOptOne (true); + runBench (&benchPtrA, n, "a-opt"); + runBench (&benchPtrB, n, "b-opt"); + runBench (&benchPtrC, n, "c-opt"); return 0; } From b61417101f10101e98a3cabcea8eebb240be3393 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 12:48:52 +0200 Subject: [PATCH 092/116] rename packet-history.h to packet-metadata.h --- SConstruct | 4 ++-- src/common/{packet-history.cc => packet-metadata.cc} | 2 +- src/common/{packet-history.h => packet-metadata.h} | 0 src/common/packet.h | 2 +- utils/bench-packets.cc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename src/common/{packet-history.cc => packet-metadata.cc} (99%) rename src/common/{packet-history.h => packet-metadata.h} (100%) diff --git a/SConstruct b/SConstruct index 4cf009bf1..fba95508f 100644 --- a/SConstruct +++ b/SConstruct @@ -189,7 +189,7 @@ common.add_sources([ 'header.cc', 'trailer.cc', 'packet-printer.cc', - 'packet-history.cc', + 'packet-metadata.cc', 'packet.cc', 'tags.cc', 'pcap-writer.cc', @@ -212,7 +212,7 @@ common.add_inst_headers([ 'tags.h', 'packet.h', 'packet-printer.h', - 'packet-history.h', + 'packet-metadata.h', 'uv-trace-source.h', 'sv-trace-source.h', 'fv-trace-source.h', diff --git a/src/common/packet-history.cc b/src/common/packet-metadata.cc similarity index 99% rename from src/common/packet-history.cc rename to src/common/packet-metadata.cc index f845fd678..3b7d2eaab 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-metadata.cc @@ -23,7 +23,7 @@ #include "ns3/assert.h" #include "ns3/fatal-error.h" #include "ns3/debug.h" -#include "packet-history.h" +#include "packet-metadata.h" #include "chunk.h" #include "buffer.h" diff --git a/src/common/packet-history.h b/src/common/packet-metadata.h similarity index 100% rename from src/common/packet-history.h rename to src/common/packet-metadata.h diff --git a/src/common/packet.h b/src/common/packet.h index 184ac6756..fa7bea8ff 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -26,7 +26,7 @@ #include "header.h" #include "trailer.h" #include "tags.h" -#include "packet-history.h" +#include "packet-metadata.h" #include "ns3/callback.h" #include "ns3/assert.h" diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index 64f0a44df..4b8ba7adf 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -20,7 +20,7 @@ */ #include "ns3/system-wall-clock-ms.h" #include "ns3/packet.h" -#include "ns3/packet-history.h" +#include "ns3/packet-metadata.h" #include #include From b7ded4e595283859eb83f1d16143928c9196d418 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 12:51:57 +0200 Subject: [PATCH 093/116] PacketHistory -> PacketMetadata --- src/common/packet-metadata.cc | 216 +++++++++++++++++----------------- src/common/packet-metadata.h | 70 +++++------ src/common/packet-printer.h | 3 +- src/common/packet.cc | 6 +- src/common/packet.h | 4 +- utils/bench-packets.cc | 4 +- 6 files changed, 151 insertions(+), 152 deletions(-) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 3b7d2eaab..3e179ebfa 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -27,38 +27,38 @@ #include "chunk.h" #include "buffer.h" -NS_DEBUG_COMPONENT_DEFINE ("PacketHistory"); +NS_DEBUG_COMPONENT_DEFINE ("PacketMetadata"); namespace ns3 { -bool PacketHistory::m_enable = false; -uint32_t PacketHistory::m_maxSize = 0; -uint16_t PacketHistory::m_chunkUid = 0; -PacketHistory::DataFreeList PacketHistory::m_freeList; +bool PacketMetadata::m_enable = false; +uint32_t PacketMetadata::m_maxSize = 0; +uint16_t PacketMetadata::m_chunkUid = 0; +PacketMetadata::DataFreeList PacketMetadata::m_freeList; bool g_optOne = false; void -PacketHistory::Enable (void) +PacketMetadata::Enable (void) { m_enable = true; } void -PacketHistory::SetOptOne (bool optOne) +PacketMetadata::SetOptOne (bool optOne) { g_optOne = optOne; } void -PacketHistory::ReserveCopy (uint32_t size) +PacketMetadata::ReserveCopy (uint32_t size) { - struct PacketHistory::Data *newData = PacketHistory::Create (m_used + size); + struct PacketMetadata::Data *newData = PacketMetadata::Create (m_used + size); memcpy (newData->m_data, m_data->m_data, m_used); newData->m_dirtyEnd = m_used; m_data->m_count--; if (m_data->m_count == 0) { - PacketHistory::Recycle (m_data); + PacketMetadata::Recycle (m_data); } m_data = newData; if (m_head != 0xffff) @@ -74,7 +74,7 @@ PacketHistory::ReserveCopy (uint32_t size) } } void -PacketHistory::Reserve (uint32_t size) +PacketMetadata::Reserve (uint32_t size) { NS_ASSERT (m_data != 0); if (m_data->m_size >= m_used + size && @@ -92,7 +92,7 @@ PacketHistory::Reserve (uint32_t size) } uint32_t -PacketHistory::GetUleb128Size (uint32_t value) const +PacketMetadata::GetUleb128Size (uint32_t value) const { if (value < 0x80) { @@ -113,7 +113,7 @@ PacketHistory::GetUleb128Size (uint32_t value) const return 5; } uint32_t -PacketHistory::ReadUleb128 (const uint8_t **pBuffer) const +PacketMetadata::ReadUleb128 (const uint8_t **pBuffer) const { const uint8_t *buffer = *pBuffer; uint32_t result = 0; @@ -162,14 +162,14 @@ PacketHistory::ReadUleb128 (const uint8_t **pBuffer) const } void -PacketHistory::Append16 (uint16_t value, uint8_t *buffer) +PacketMetadata::Append16 (uint16_t value, uint8_t *buffer) { buffer[0] = value & 0xff; value >>= 8; buffer[1] = value; } bool -PacketHistory::TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end) +PacketMetadata::TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end) { uint8_t *start = *pBuffer; if (value < 0x80 && start < end) @@ -190,7 +190,7 @@ PacketHistory::TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end) return false; } bool -PacketHistory::TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end) +PacketMetadata::TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end) { uint8_t *start = *pBuffer; if (start + 1 < end) @@ -203,7 +203,7 @@ PacketHistory::TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end) return false; } bool -PacketHistory::TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end) +PacketMetadata::TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end) { uint8_t *start = *pBuffer; if (start + 3 < end) @@ -218,7 +218,7 @@ PacketHistory::TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end) return false; } bool -PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) +PacketMetadata::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) { uint8_t *start = *pBuffer; if (value < 0x80 && start < end) @@ -286,7 +286,7 @@ PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end) } void -PacketHistory::AppendValueExtra (uint32_t value, uint8_t *buffer) +PacketMetadata::AppendValueExtra (uint32_t value, uint8_t *buffer) { if (value < 0x200000) { @@ -332,7 +332,7 @@ PacketHistory::AppendValueExtra (uint32_t value, uint8_t *buffer) } void -PacketHistory::AppendValue (uint32_t value, uint8_t *buffer) +PacketMetadata::AppendValue (uint32_t value, uint8_t *buffer) { if (value < 0x80) { @@ -351,7 +351,7 @@ PacketHistory::AppendValue (uint32_t value, uint8_t *buffer) } void -PacketHistory::UpdateTail (uint16_t written) +PacketMetadata::UpdateTail (uint16_t written) { if (m_head == 0xffff) { @@ -376,7 +376,7 @@ PacketHistory::UpdateTail (uint16_t written) void -PacketHistory::UpdateHead (uint16_t written) +PacketMetadata::UpdateHead (uint16_t written) { if (m_head == 0xffff) { @@ -400,7 +400,7 @@ PacketHistory::UpdateHead (uint16_t written) } uint16_t -PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) +PacketMetadata::AddSmall (const struct PacketMetadata::SmallItem *item) { NS_ASSERT (m_data != 0); if (g_optOne) @@ -464,9 +464,9 @@ PacketHistory::AddSmall (const struct PacketHistory::SmallItem *item) } uint16_t -PacketHistory::AddBig (uint32_t next, uint32_t prev, - const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem) +PacketMetadata::AddBig (uint32_t next, uint32_t prev, + const PacketMetadata::SmallItem *item, + const PacketMetadata::ExtraItem *extraItem) { NS_ASSERT (m_data != 0); uint32_t typeUid = ((item->typeUid & 0x1) == 0x1)?item->typeUid:item->typeUid+1; @@ -509,8 +509,8 @@ PacketHistory::AddBig (uint32_t next, uint32_t prev, } void -PacketHistory::ReplaceTail (PacketHistory::SmallItem *item, - PacketHistory::ExtraItem *extraItem, +PacketMetadata::ReplaceTail (PacketMetadata::SmallItem *item, + PacketMetadata::ExtraItem *extraItem, uint32_t available) { NS_ASSERT (m_data != 0); @@ -538,12 +538,12 @@ PacketHistory::ReplaceTail (PacketHistory::SmallItem *item, } // create a copy of the packet. - PacketHistory h (m_packetUid, 0); + PacketMetadata h (m_packetUid, 0); uint16_t current = m_head; while (current != 0xffff && current != m_tail) { - struct PacketHistory::SmallItem tmpItem; - PacketHistory::ExtraItem tmpExtraItem; + struct PacketMetadata::SmallItem tmpItem; + PacketMetadata::ExtraItem tmpExtraItem; ReadItems (current, &tmpItem, &tmpExtraItem); uint16_t written = h.AddBig (0xffff, h.m_tail, &tmpItem, &tmpExtraItem); @@ -557,9 +557,9 @@ PacketHistory::ReplaceTail (PacketHistory::SmallItem *item, } uint32_t -PacketHistory::ReadItems (uint16_t current, - struct PacketHistory::SmallItem *item, - struct PacketHistory::ExtraItem *extraItem) const +PacketMetadata::ReadItems (uint16_t current, + struct PacketMetadata::SmallItem *item, + struct PacketMetadata::ExtraItem *extraItem) const { const uint8_t *buffer = &m_data->m_data[current]; item->next = buffer[0]; @@ -594,8 +594,8 @@ PacketHistory::ReadItems (uint16_t current, return buffer - &m_data->m_data[current]; } -struct PacketHistory::Data * -PacketHistory::Create (uint32_t size) +struct PacketMetadata::Data * +PacketMetadata::Create (uint32_t size) { NS_DEBUG ("create size="< void -PacketHistoryTest::RegisterHeader (void) +PacketMetadataTest::RegisterHeader (void) { static bool registered = false; if (!registered) { - m_printer.AddHeaderPrinter (MakeCallback (&PacketHistoryTest::PrintHeader, this), - MakeCallback (&PacketHistoryTest::PrintFragment, this)); + m_printer.AddHeaderPrinter (MakeCallback (&PacketMetadataTest::PrintHeader, this), + MakeCallback (&PacketMetadataTest::PrintFragment, this)); registered = true; } } template void -PacketHistoryTest::RegisterTrailer (void) +PacketMetadataTest::RegisterTrailer (void) { static bool registered = false; if (!registered) { - m_printer.AddTrailerPrinter (MakeCallback (&PacketHistoryTest::PrintTrailer, this), - MakeCallback (&PacketHistoryTest::PrintFragment, this)); + m_printer.AddTrailerPrinter (MakeCallback (&PacketMetadataTest::PrintTrailer, this), + MakeCallback (&PacketMetadataTest::PrintFragment, this)); registered = true; } } @@ -1275,7 +1275,7 @@ PacketHistoryTest::RegisterTrailer (void) template void -PacketHistoryTest::PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, +PacketMetadataTest::PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryHeader *header) { if (!header->IsOk ()) @@ -1287,7 +1287,7 @@ PacketHistoryTest::PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t s template void -PacketHistoryTest::PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, +PacketMetadataTest::PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryTrailer *trailer) { if (!trailer->IsOk ()) @@ -1297,21 +1297,21 @@ PacketHistoryTest::PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t m_prints.push_back (N); } void -PacketHistoryTest::PrintFragment (std::ostream &os,uint32_t packetUid, +PacketMetadataTest::PrintFragment (std::ostream &os,uint32_t packetUid, uint32_t size,std::string & name, struct PacketPrinter::FragmentInformation info) { m_prints.push_back (info.end - info.start); } void -PacketHistoryTest::PrintDefault (std::ostream& os,uint32_t packetUid, +PacketMetadataTest::PrintDefault (std::ostream& os,uint32_t packetUid, uint32_t size,std::string& name, struct PacketPrinter::FragmentInformation info) { NS_ASSERT (false); } void -PacketHistoryTest::PrintPayload (std::ostream &os,uint32_t packetUid, +PacketMetadataTest::PrintPayload (std::ostream &os,uint32_t packetUid, uint32_t size, struct PacketPrinter::FragmentInformation info) { @@ -1320,13 +1320,13 @@ PacketHistoryTest::PrintPayload (std::ostream &os,uint32_t packetUid, void -PacketHistoryTest::CleanupPrints (void) +PacketMetadataTest::CleanupPrints (void) { m_prints.clear (); } bool -PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ...) +PacketMetadataTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ...) { m_headerError = false; m_trailerError = false; @@ -1335,13 +1335,13 @@ PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ... va_start (ap, n); if (m_headerError) { - std::cout << "PacketHistory header error. file=" << file + std::cout << "PacketMetadata header error. file=" << file << ", line=" << line << std::endl; return false; } if (m_trailerError) { - std::cout << "PacketHistory trailer error. file=" << file + std::cout << "PacketMetadata trailer error. file=" << file << ", line=" << line << std::endl; return false; } @@ -1362,7 +1362,7 @@ PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ... va_end (ap); return true; error: - std::cout << "PacketHistory error. file="<< file + std::cout << "PacketMetadata error. file="<< file << ", line=" << line << ", got:\""; for (std::list::iterator i = m_prints.begin (); i != m_prints.end (); i++) @@ -1416,11 +1416,11 @@ PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ... } bool -PacketHistoryTest::RunTests (void) +PacketMetadataTest::RunTests (void) { bool ok = true; - PacketHistory::Enable (); + PacketMetadata::Enable (); Packet p = Packet (0); Packet p1 = Packet (0); @@ -1626,6 +1626,6 @@ PacketHistoryTest::RunTests (void) return ok; } -static PacketHistoryTest g_packetHistoryTest; +static PacketMetadataTest g_packetHistoryTest; }//namespace ns3 diff --git a/src/common/packet-metadata.h b/src/common/packet-metadata.h index a0424c8f6..098775934 100644 --- a/src/common/packet-metadata.h +++ b/src/common/packet-metadata.h @@ -18,8 +18,8 @@ * * Author: Mathieu Lacage */ -#ifndef PACKET_HISTORY_H -#define PACKET_HISTORY_H +#ifndef PACKET_METADATA_H +#define PACKET_METADATA_H #include #include @@ -32,15 +32,15 @@ namespace ns3 { class Chunk; class Buffer; -class PacketHistory { +class PacketMetadata { public: static void Enable (void); static void SetOptOne (bool optOne); - inline PacketHistory (uint32_t uid, uint32_t size); - inline PacketHistory (PacketHistory const &o); - inline PacketHistory &operator = (PacketHistory const& o); - inline ~PacketHistory (); + inline PacketMetadata (uint32_t uid, uint32_t size); + inline PacketMetadata (PacketMetadata const &o); + inline PacketMetadata &operator = (PacketMetadata const& o); + inline ~PacketMetadata (); template void AddHeader (T const &header, uint32_t size); @@ -52,8 +52,8 @@ public: template void RemoveTrailer (T const &trailer, uint32_t size); - PacketHistory CreateFragment (uint32_t start, uint32_t end) const; - void AddAtEnd (PacketHistory const&o); + PacketMetadata CreateFragment (uint32_t start, uint32_t end) const; + void AddAtEnd (PacketMetadata const&o); void AddPaddingAtEnd (uint32_t end); void RemoveAtStart (uint32_t start); void RemoveAtEnd (uint32_t end); @@ -90,18 +90,18 @@ private: typedef std::vector DataFreeList; - PacketHistory (); + PacketMetadata (); void DoAddHeader (uint32_t uid, uint32_t size); void DoRemoveHeader (uint32_t uid, uint32_t size); void DoAddTrailer (uint32_t uid, uint32_t size); void DoRemoveTrailer (uint32_t uid, uint32_t size); - inline uint16_t AddSmall (const PacketHistory::SmallItem *item); + inline uint16_t AddSmall (const PacketMetadata::SmallItem *item); uint16_t AddBig (uint32_t head, uint32_t tail, - const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem); - void ReplaceTail (PacketHistory::SmallItem *item, - PacketHistory::ExtraItem *extraItem, + const PacketMetadata::SmallItem *item, + const PacketMetadata::ExtraItem *extraItem); + void ReplaceTail (PacketMetadata::SmallItem *item, + PacketMetadata::ExtraItem *extraItem, uint32_t available); inline void UpdateHead (uint16_t written); inline void UpdateTail (uint16_t written); @@ -116,19 +116,19 @@ private: void AppendValueExtra (uint32_t value, uint8_t *buffer); inline void Reserve (uint32_t n); void ReserveCopy (uint32_t n); - uint32_t DoPrint (struct PacketHistory::SmallItem *item, uint32_t current, + uint32_t DoPrint (struct PacketMetadata::SmallItem *item, uint32_t current, Buffer data, uint32_t offset, const PacketPrinter &printer, std::ostream &os) const; uint32_t GetTotalSize (void) const; uint32_t ReadItems (uint16_t current, - struct PacketHistory::SmallItem *item, - struct PacketHistory::ExtraItem *extraItem) const; + struct PacketMetadata::SmallItem *item, + struct PacketMetadata::ExtraItem *extraItem) const; - static struct PacketHistory::Data *Create (uint32_t size); - static void Recycle (struct PacketHistory::Data *data); - static struct PacketHistory::Data *Allocate (uint32_t n); - static void Deallocate (struct PacketHistory::Data *data); + static struct PacketMetadata::Data *Create (uint32_t size); + static void Recycle (struct PacketMetadata::Data *data); + static struct PacketMetadata::Data *Allocate (uint32_t n); + static void Deallocate (struct PacketMetadata::Data *data); static DataFreeList m_freeList; static bool m_enable; @@ -148,33 +148,33 @@ namespace ns3 { template void -PacketHistory::AddHeader (T const &header, uint32_t size) +PacketMetadata::AddHeader (T const &header, uint32_t size) { DoAddHeader (PacketPrinter::GetHeaderUid (), size); } template void -PacketHistory::RemoveHeader (T const &header, uint32_t size) +PacketMetadata::RemoveHeader (T const &header, uint32_t size) { DoRemoveHeader (PacketPrinter::GetHeaderUid (), size); } template void -PacketHistory::AddTrailer (T const &trailer, uint32_t size) +PacketMetadata::AddTrailer (T const &trailer, uint32_t size) { DoAddTrailer (PacketPrinter::GetTrailerUid (), size); } template void -PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) +PacketMetadata::RemoveTrailer (T const &trailer, uint32_t size) { DoRemoveTrailer (PacketPrinter::GetTrailerUid (), size); } -PacketHistory::PacketHistory (uint32_t uid, uint32_t size) - : m_data (m_data = PacketHistory::Create (10)), +PacketMetadata::PacketMetadata (uint32_t uid, uint32_t size) + : m_data (m_data = PacketMetadata::Create (10)), m_head (0xffff), m_tail (0xffff), m_used (0), @@ -186,7 +186,7 @@ PacketHistory::PacketHistory (uint32_t uid, uint32_t size) DoAddHeader (0, size); } } -PacketHistory::PacketHistory (PacketHistory const &o) +PacketMetadata::PacketMetadata (PacketMetadata const &o) : m_data (o.m_data), m_head (o.m_head), m_tail (o.m_tail), @@ -196,8 +196,8 @@ PacketHistory::PacketHistory (PacketHistory const &o) NS_ASSERT (m_data != 0); m_data->m_count++; } -PacketHistory & -PacketHistory::operator = (PacketHistory const& o) +PacketMetadata & +PacketMetadata::operator = (PacketMetadata const& o) { if (m_data == o.m_data) { @@ -208,7 +208,7 @@ PacketHistory::operator = (PacketHistory const& o) m_data->m_count--; if (m_data->m_count == 0) { - PacketHistory::Recycle (m_data); + PacketMetadata::Recycle (m_data); } m_data = o.m_data; m_head = o.m_head; @@ -219,17 +219,17 @@ PacketHistory::operator = (PacketHistory const& o) m_data->m_count++; return *this; } -PacketHistory::~PacketHistory () +PacketMetadata::~PacketMetadata () { NS_ASSERT (m_data != 0); m_data->m_count--; if (m_data->m_count == 0) { - PacketHistory::Recycle (m_data); + PacketMetadata::Recycle (m_data); } } }; // namespace ns3 -#endif /* PACKET_HISTORY_H */ +#endif /* PACKET_METADATA_H */ diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 26dcf1aa7..0b5e41633 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -114,8 +114,7 @@ public: void AddDefaultPrinter (DefaultPrinter printer); private: - friend class PacketHistory; - friend class ::ItemList; + friend class PacketMetadata; typedef void (*DoPrintCallback) (Ptr, Buffer::Iterator, std::ostream &, uint32_t, uint32_t); typedef std::string (*DoGetNameCallback) (void); diff --git a/src/common/packet.cc b/src/common/packet.cc index f27136fd9..18c5f6c6d 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -52,7 +52,7 @@ Packet::Packet (uint8_t const*buffer, uint32_t size) i.Write (buffer, size); } -Packet::Packet (Buffer buffer, Tags tags, PacketHistory history, uint32_t uid) +Packet::Packet (Buffer buffer, Tags tags, PacketMetadata history, uint32_t uid) : m_buffer (buffer), m_tags (tags), m_history (history), @@ -65,7 +65,7 @@ Packet::CreateFragment (uint32_t start, uint32_t length) const Buffer buffer = m_buffer.CreateFragment (start, length); NS_ASSERT (m_buffer.GetSize () >= start + length); uint32_t end = m_buffer.GetSize () - (start + length); - PacketHistory history = m_history.CreateFragment (start, end); + PacketMetadata history = m_history.CreateFragment (start, end); return Packet (buffer, m_tags, history, m_uid); } @@ -144,7 +144,7 @@ Packet::Print (std::ostream &os, const PacketPrinter &printer) const void Packet::EnableMetadata (void) { - PacketHistory::Enable (); + PacketMetadata::Enable (); } }; // namespace ns3 diff --git a/src/common/packet.h b/src/common/packet.h index fa7bea8ff..fbc9f9b98 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -295,10 +295,10 @@ public: */ static void EnableMetadata (void); private: - Packet (Buffer buffer, Tags tags, PacketHistory history, uint32_t uid); + Packet (Buffer buffer, Tags tags, PacketMetadata history, uint32_t uid); Buffer m_buffer; Tags m_tags; - PacketHistory m_history; + PacketMetadata m_history; uint32_t m_uid; static uint32_t m_globalUid; }; diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index 4b8ba7adf..cf962c710 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -188,11 +188,11 @@ int main (int argc, char *argv[]) } - PacketHistory::SetOptOne (false); + PacketMetadata::SetOptOne (false); runBench (&benchPtrA, n, "a"); runBench (&benchPtrB, n, "b"); runBench (&benchPtrC, n, "c"); - PacketHistory::SetOptOne (true); + PacketMetadata::SetOptOne (true); runBench (&benchPtrA, n, "a-opt"); runBench (&benchPtrB, n, "b-opt"); runBench (&benchPtrC, n, "c-opt"); From e89ad0a86b8f5aa588c17a5de15ad0896b67af41 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 13:16:15 +0200 Subject: [PATCH 094/116] fix uleb128 reading bug --- src/common/packet-metadata.cc | 13 ++++++++----- utils/bench-packets.cc | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 3e179ebfa..a076633bd 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -127,28 +127,28 @@ PacketMetadata::ReadUleb128 (const uint8_t **pBuffer) const return result; } byte = buffer[1]; - result = (byte & (~0x80)) << 7; + result |= (byte & (~0x80)) << 7; if (!(byte & 0x80)) { *pBuffer = buffer + 2; return result; } byte = buffer[2]; - result = (byte & (~0x80)) << 14; + result |= (byte & (~0x80)) << 14; if (!(byte & 0x80)) { *pBuffer = buffer + 3; return result; } byte = buffer[3]; - result = (byte & (~0x80)) << 21; + result |= (byte & (~0x80)) << 21; if (!(byte & 0x80)) { *pBuffer = buffer + 4; return result; } byte = buffer[4]; - result = (byte & (~0x80)) << 28; + result |= (byte & (~0x80)) << 28; if (!(byte & 0x80)) { *pBuffer = buffer + 5; @@ -1619,7 +1619,10 @@ PacketMetadataTest::RunTests (void) CHECK_HISTORY (p2, 1, 1); p1.AddAtEnd (p2); CHECK_HISTORY (p1, 2, 4, 1); - + + + p = Packet (2000); + CHECK_HISTORY (p, 1, 2000); diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index cf962c710..75489e40d 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -156,6 +156,22 @@ benchPtrC (uint32_t n) } } +static void +benchPrint (uint32_t n) +{ + PacketPrinter printer; + BenchHeader<25> ipv4; + BenchHeader<8> udp; + Packet p (2000); + p.AddHeader (udp); + p.AddHeader (ipv4); + + for (uint32_t i = 0; i < n; i++) + { + p.Print (std::cerr, printer); + } +} + static void runBench (void (*bench) (uint32_t), uint32_t n, char const *name) @@ -188,6 +204,7 @@ int main (int argc, char *argv[]) } + runBench (&benchPrint, n, "print"); PacketMetadata::SetOptOne (false); runBench (&benchPtrA, n, "a"); runBench (&benchPtrB, n, "b"); From 102dcfd4bc601ad3f9bf55ce5928d60ad8cdcf05 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 7 Jun 2007 13:19:25 +0200 Subject: [PATCH 095/116] do not crash is the payload printer is null --- src/common/packet-printer.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 9d0627635..72514ef70 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -137,7 +137,10 @@ PacketPrinter::PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size struct PacketPrinter::FragmentInformation info; info.start = fragmentStart; info.end = fragmentEnd; - m_payloadPrinter (os, packetUid, size, info); + if (!m_payloadPrinter.IsNull ()) + { + m_payloadPrinter (os, packetUid, size, info); + } } void From 55f2084e86bb03f34eef5a2f623e8b8bd6d4185a Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 12 Jun 2007 13:21:06 +0200 Subject: [PATCH 096/116] avoid duplicating the packet uid --- src/common/packet-metadata.cc | 6 ++++++ src/common/packet-metadata.h | 2 ++ src/common/packet.cc | 18 +++++++----------- src/common/packet.h | 3 +-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index a076633bd..06209b732 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -1001,6 +1001,12 @@ PacketMetadata::GetTotalSize (void) const return totalSize; } +uint32_t +PacketMetadata::GetUid (void) const +{ + return m_packetUid; +} + void PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &printer) const { diff --git a/src/common/packet-metadata.h b/src/common/packet-metadata.h index 098775934..cb96ddd10 100644 --- a/src/common/packet-metadata.h +++ b/src/common/packet-metadata.h @@ -58,6 +58,8 @@ public: void RemoveAtStart (uint32_t start); void RemoveAtEnd (uint32_t end); + uint32_t GetUid (void) const; + void PrintDefault (std::ostream &os, Buffer buffer) const; void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const; diff --git a/src/common/packet.cc b/src/common/packet.cc index 18c5f6c6d..c24ac6415 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -28,23 +28,20 @@ uint32_t Packet::m_globalUid = 0; Packet::Packet () : m_buffer (), - m_history (m_globalUid, 0), - m_uid (m_globalUid) + m_history (m_globalUid, 0) { m_globalUid++; } Packet::Packet (uint32_t size) : m_buffer (size), - m_history (m_globalUid, size), - m_uid (m_globalUid) + m_history (m_globalUid, size) { m_globalUid++; } Packet::Packet (uint8_t const*buffer, uint32_t size) : m_buffer (), - m_history (m_globalUid, size), - m_uid (m_globalUid) + m_history (m_globalUid, size) { m_globalUid++; m_buffer.AddAtStart (size); @@ -52,11 +49,10 @@ Packet::Packet (uint8_t const*buffer, uint32_t size) i.Write (buffer, size); } -Packet::Packet (Buffer buffer, Tags tags, PacketMetadata history, uint32_t uid) +Packet::Packet (Buffer buffer, Tags tags, PacketMetadata history) : m_buffer (buffer), m_tags (tags), - m_history (history), - m_uid (uid) + m_history (history) {} Packet @@ -66,7 +62,7 @@ Packet::CreateFragment (uint32_t start, uint32_t length) const NS_ASSERT (m_buffer.GetSize () >= start + length); uint32_t end = m_buffer.GetSize () - (start + length); PacketMetadata history = m_history.CreateFragment (start, end); - return Packet (buffer, m_tags, history, m_uid); + return Packet (buffer, m_tags, history); } uint32_t @@ -126,7 +122,7 @@ Packet::PeekData (void) const uint32_t Packet::GetUid (void) const { - return m_uid; + return m_history.GetUid (); } void diff --git a/src/common/packet.h b/src/common/packet.h index fbc9f9b98..07a2ae383 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -295,11 +295,10 @@ public: */ static void EnableMetadata (void); private: - Packet (Buffer buffer, Tags tags, PacketMetadata history, uint32_t uid); + Packet (Buffer buffer, Tags tags, PacketMetadata history); Buffer m_buffer; Tags m_tags; PacketMetadata m_history; - uint32_t m_uid; static uint32_t m_globalUid; }; From 0d7b0e26eedcc8ab3f9bd275841823c381a3ca06 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 12 Jun 2007 22:52:56 +0200 Subject: [PATCH 097/116] history -> metadata --- src/common/packet.cc | 28 ++++++++++++++-------------- src/common/packet.h | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/common/packet.cc b/src/common/packet.cc index c24ac6415..8c03c453a 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -28,20 +28,20 @@ uint32_t Packet::m_globalUid = 0; Packet::Packet () : m_buffer (), - m_history (m_globalUid, 0) + m_metadata (m_globalUid, 0) { m_globalUid++; } Packet::Packet (uint32_t size) : m_buffer (size), - m_history (m_globalUid, size) + m_metadata (m_globalUid, size) { m_globalUid++; } Packet::Packet (uint8_t const*buffer, uint32_t size) : m_buffer (), - m_history (m_globalUid, size) + m_metadata (m_globalUid, size) { m_globalUid++; m_buffer.AddAtStart (size); @@ -49,10 +49,10 @@ Packet::Packet (uint8_t const*buffer, uint32_t size) i.Write (buffer, size); } -Packet::Packet (Buffer buffer, Tags tags, PacketMetadata history) +Packet::Packet (Buffer buffer, Tags tags, PacketMetadata metadata) : m_buffer (buffer), m_tags (tags), - m_history (history) + m_metadata (metadata) {} Packet @@ -61,8 +61,8 @@ Packet::CreateFragment (uint32_t start, uint32_t length) const Buffer buffer = m_buffer.CreateFragment (start, length); NS_ASSERT (m_buffer.GetSize () >= start + length); uint32_t end = m_buffer.GetSize () - (start + length); - PacketMetadata history = m_history.CreateFragment (start, end); - return Packet (buffer, m_tags, history); + PacketMetadata metadata = m_metadata.CreateFragment (start, end); + return Packet (buffer, m_tags, metadata); } uint32_t @@ -86,25 +86,25 @@ Packet::AddAtEnd (Packet packet) * XXX: we might need to merge the tag list of the * other packet into the current packet. */ - m_history.AddAtEnd (packet.m_history); + m_metadata.AddAtEnd (packet.m_metadata); } void Packet::AddPaddingAtEnd (uint32_t size) { m_buffer.AddAtEnd (size); - m_history.AddPaddingAtEnd (size); + m_metadata.AddPaddingAtEnd (size); } void Packet::RemoveAtEnd (uint32_t size) { m_buffer.RemoveAtEnd (size); - m_history.RemoveAtEnd (size); + m_metadata.RemoveAtEnd (size); } void Packet::RemoveAtStart (uint32_t size) { m_buffer.RemoveAtStart (size); - m_history.RemoveAtStart (size); + m_metadata.RemoveAtStart (size); } void @@ -122,19 +122,19 @@ Packet::PeekData (void) const uint32_t Packet::GetUid (void) const { - return m_history.GetUid (); + return m_metadata.GetUid (); } void Packet::Print (std::ostream &os) const { - m_history.PrintDefault (os, m_buffer); + m_metadata.PrintDefault (os, m_buffer); } void Packet::Print (std::ostream &os, const PacketPrinter &printer) const { - m_history.Print (os, m_buffer, printer); + m_metadata.Print (os, m_buffer, printer); } void diff --git a/src/common/packet.h b/src/common/packet.h index 07a2ae383..69ebdc392 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -295,10 +295,10 @@ public: */ static void EnableMetadata (void); private: - Packet (Buffer buffer, Tags tags, PacketMetadata history); + Packet (Buffer buffer, Tags tags, PacketMetadata metadata); Buffer m_buffer; Tags m_tags; - PacketMetadata m_history; + PacketMetadata m_metadata; static uint32_t m_globalUid; }; @@ -321,7 +321,7 @@ Packet::AddHeader (T const &header) uint32_t size = header.GetSize (); m_buffer.AddAtStart (size); header.Serialize (m_buffer.Begin ()); - m_history.AddHeader (header, size); + m_metadata.AddHeader (header, size); } template uint32_t @@ -331,7 +331,7 @@ Packet::RemoveHeader (T &header) "Must pass Header subclass to Packet::RemoveHeader"); uint32_t deserialized = header.Deserialize (m_buffer.Begin ()); m_buffer.RemoveAtStart (deserialized); - m_history.RemoveHeader (header, deserialized); + m_metadata.RemoveHeader (header, deserialized); return deserialized; } template @@ -344,7 +344,7 @@ Packet::AddTrailer (T const &trailer) m_buffer.AddAtEnd (size); Buffer::Iterator start = m_buffer.End (); trailer.Serialize (start); - m_history.AddTrailer (trailer, size); + m_metadata.AddTrailer (trailer, size); } template uint32_t @@ -354,7 +354,7 @@ Packet::RemoveTrailer (T &trailer) "Must pass Trailer subclass to Packet::RemoveTrailer"); uint32_t deserialized = trailer.Deserialize (m_buffer.End ()); m_buffer.RemoveAtEnd (deserialized); - m_history.RemoveTrailer (trailer, deserialized); + m_metadata.RemoveTrailer (trailer, deserialized); return deserialized; } From c2fda9ce09d1509d7b7f1e28ba2fb055fa96880b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 12 Jun 2007 23:23:31 +0200 Subject: [PATCH 098/116] do not forget payload printer for default printer --- src/common/packet-printer.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 72514ef70..27bc0a191 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -70,6 +70,8 @@ PacketPrinter * PacketPrinter::CreateStaticDefault (void) { static PacketPrinter tmp; + tmp.PrintForward (); + tmp.AddPayloadPrinter (MakeCallback (&PacketPrinter::DoDefaultPrintPayload)); return &tmp; } From 75bc2e9b0b4313e0644a0e1b5275c5233197ad10 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 12 Jun 2007 23:40:14 +0200 Subject: [PATCH 099/116] sample code for pretty printing --- SConstruct | 7 ++ samples/main-packet-printer.cc | 173 +++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 samples/main-packet-printer.cc diff --git a/SConstruct b/SConstruct index aec276e33..69a681c5d 100644 --- a/SConstruct +++ b/SConstruct @@ -397,6 +397,13 @@ sample_debug.add_dep('core') sample_debug.add_source('main-debug.cc') sample_debug.add_source('main-debug-other.cc') +sample_packet_printer = build.Ns3Module('sample-packet-printer', 'samples') +sample_packet_printer.set_executable() +ns3.add(sample_packet_printer) +sample_packet_printer.add_dep('common') +sample_packet_printer.add_source('main-packet-printer.cc') + + sample_callback = build.Ns3Module('sample-callback', 'samples') sample_callback.set_executable() ns3.add(sample_callback) diff --git a/samples/main-packet-printer.cc b/samples/main-packet-printer.cc new file mode 100644 index 000000000..bcad6f422 --- /dev/null +++ b/samples/main-packet-printer.cc @@ -0,0 +1,173 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +#include "ns3/packet.h" +#include "ns3/header.h" +#include "ns3/packet-printer.h" + +using namespace ns3; + +#define MY_HEADER(name,size) \ +class MyHeader##name : public Header \ +{ \ +public: \ + void Set (uint8_t v) \ + { \ + m_v = v; \ + } \ + uint8_t Get (void) const \ + { \ + return m_v; \ + } \ +private: \ + virtual std::string DoGetName (void) const \ + { \ + return #name; \ + } \ + virtual void PrintTo (std::ostream &os) const \ + { \ + uint32_t v = m_v; \ + os << #name << ", v=" << v; \ + } \ + virtual uint32_t GetSerializedSize (void) const \ + { \ + return size; \ + } \ + virtual void SerializeTo (Buffer::Iterator start) const \ + { \ + start.WriteU8 (m_v, size); \ + } \ + virtual uint32_t DeserializeFrom (Buffer::Iterator start) \ + { \ + NS_ASSERT (size >= 1); \ + m_v = start.ReadU8 (); \ + for (uint32_t i = 2; i < size; i++) \ + { \ + NS_ASSERT (start.ReadU8 () == m_v); \ + } \ + return size; \ + } \ + uint8_t m_v; \ +}; + +MY_HEADER(A,10); +MY_HEADER(B,100); +MY_HEADER(C,20); + +void DefaultPrint (void) +{ + Packet p (1000); + MyHeaderA a; + MyHeaderB b; + MyHeaderC c; + a.Set (1); + b.Set (3); + c.Set (2); + p.AddHeader (a); + p.AddHeader (b); + p.AddHeader (c); + + std::cout << "full packet size=" << p.GetSize () << std::endl; + p.Print (std::cout); + + + Packet p1 = p.CreateFragment (0, 2); + Packet p2 = p.CreateFragment (2, 1000); + Packet p3 = p.CreateFragment (1002, 128); + std::cout << "fragment1" << std::endl; + p1.Print (std::cout); + std::cout << "fragment2" << std::endl; + p2.Print (std::cout); + std::cout << "fragment3" << std::endl; + p3.Print (std::cout); + + Packet aggregate = p1; + aggregate.AddAtEnd (p2); + aggregate.AddAtEnd (p3); + std::cout << "aggregated" << std::endl; + aggregate.Print (std::cout); +} + +void +DoPrintDefault (std::ostream &os,uint32_t packetUid, uint32_t size, + std::string &name, struct PacketPrinter::FragmentInformation info) +{ + os << "default name="<Get (); + os << "A v=" << v; + os << " - "; +} +void +DoPrintMyHeaderAFragment (std::ostream &os, uint32_t packetUid, uint32_t size, + std::string &name, struct PacketPrinter::FragmentInformation info) +{ + os << "A fragment"; + os << " - "; +} + +void NonDefaultPrint (void) +{ + PacketPrinter printer; + printer.AddDefaultPrinter (MakeCallback (&DoPrintDefault)); + printer.AddPayloadPrinter (MakeCallback (&DoPrintPayload)); + printer.AddHeaderPrinter (MakeCallback (&DoPrintMyHeaderA), + MakeCallback (&DoPrintMyHeaderAFragment)); + Packet p (1000); + MyHeaderA a; + MyHeaderB b; + MyHeaderC c; + a.Set (1); + b.Set (3); + c.Set (2); + p.AddHeader (a); + p.AddHeader (b); + p.AddHeader (c); + + std::cout << "full packet size=" << p.GetSize () << std::endl; + p.Print (std::cout, printer); + std::cout << std::endl; + + + Packet p1 = p.CreateFragment (0, 2); + Packet p2 = p.CreateFragment (2, 1000); + Packet p3 = p.CreateFragment (1002, 128); + std::cout << "fragment1" << std::endl; + p1.Print (std::cout, printer); + std::cout << std::endl; + std::cout << "fragment2" << std::endl; + p2.Print (std::cout, printer); + std::cout << std::endl; + std::cout << "fragment3" << std::endl; + p3.Print (std::cout, printer); + std::cout << std::endl; + + Packet aggregate = p1; + aggregate.AddAtEnd (p2); + aggregate.AddAtEnd (p3); + std::cout << "aggregated" << std::endl; + aggregate.Print (std::cout, printer); + std::cout << std::endl; +} + + + +int main (int argc, char *argv[]) +{ + Packet::EnableMetadata (); + + DefaultPrint (); + + NonDefaultPrint (); + + return 0; +} From c4ab5ba8ff640970c64df2a2f5a531802219092d Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 13 Jun 2007 00:02:57 +0200 Subject: [PATCH 100/116] add separator support to PacketPrinter --- samples/main-packet-printer.cc | 13 ++++++++----- src/common/packet-metadata.cc | 4 ++++ src/common/packet-printer.cc | 11 ++++++++--- src/common/packet-printer.h | 3 ++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/samples/main-packet-printer.cc b/samples/main-packet-printer.cc index bcad6f422..aae9b54fe 100644 --- a/samples/main-packet-printer.cc +++ b/samples/main-packet-printer.cc @@ -24,7 +24,7 @@ private: \ } \ virtual void PrintTo (std::ostream &os) const \ { \ - uint32_t v = m_v; \ + uint32_t v = m_v; \ os << #name << ", v=" << v; \ } \ virtual uint32_t GetSerializedSize (void) const \ @@ -67,6 +67,7 @@ void DefaultPrint (void) std::cout << "full packet size=" << p.GetSize () << std::endl; p.Print (std::cout); + std::cout << std::endl; Packet p1 = p.CreateFragment (0, 2); @@ -74,16 +75,20 @@ void DefaultPrint (void) Packet p3 = p.CreateFragment (1002, 128); std::cout << "fragment1" << std::endl; p1.Print (std::cout); + std::cout << std::endl; std::cout << "fragment2" << std::endl; p2.Print (std::cout); + std::cout << std::endl; std::cout << "fragment3" << std::endl; p3.Print (std::cout); + std::cout << std::endl; Packet aggregate = p1; aggregate.AddAtEnd (p2); aggregate.AddAtEnd (p3); std::cout << "aggregated" << std::endl; aggregate.Print (std::cout); + std::cout << std::endl; } void @@ -91,33 +96,31 @@ DoPrintDefault (std::ostream &os,uint32_t packetUid, uint32_t size, std::string &name, struct PacketPrinter::FragmentInformation info) { os << "default name="<Get (); os << "A v=" << v; - os << " - "; } void DoPrintMyHeaderAFragment (std::ostream &os, uint32_t packetUid, uint32_t size, std::string &name, struct PacketPrinter::FragmentInformation info) { os << "A fragment"; - os << " - "; } void NonDefaultPrint (void) { PacketPrinter printer; + printer.PrintForward (); + printer.SetSeparator (" - "); printer.AddDefaultPrinter (MakeCallback (&DoPrintDefault)); printer.AddPayloadPrinter (MakeCallback (&DoPrintPayload)); printer.AddHeaderPrinter (MakeCallback (&DoPrintMyHeaderA), diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 06209b732..737cc7ac5 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -1031,6 +1031,10 @@ PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &print { break; } + if (item.next != 0xffff) + { + os << printer.m_separator; + } current = item.next; } } diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 27bc0a191..37cddbf59 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -24,7 +24,8 @@ namespace ns3 { PacketPrinter::PacketPrinter () - : m_forward (true) + : m_forward (true), + m_separator ("") {} void @@ -37,6 +38,11 @@ PacketPrinter::PrintBackward (void) { m_forward = false; } +void +PacketPrinter::SetSeparator (std::string separator) +{ + m_separator = separator; +} void PacketPrinter::AddPayloadPrinter (PayloadPrinter printer) { @@ -72,6 +78,7 @@ PacketPrinter::CreateStaticDefault (void) static PacketPrinter tmp; tmp.PrintForward (); tmp.AddPayloadPrinter (MakeCallback (&PacketPrinter::DoDefaultPrintPayload)); + tmp.SetSeparator ("\n"); return &tmp; } @@ -154,7 +161,6 @@ PacketPrinter::DoDefaultPrintPayload (std::ostream & os, os << "data "; os << "[" << info.start << ":" << info.end << "] -> " << "[0:" << size << "]"; - os << std::endl; } void @@ -177,7 +183,6 @@ PacketPrinter::DoDefaultPrintFragment (std::ostream & os, os << name << " "; os << "[" << info.start << ":" << info.end << "] -> " << "[0:" << size << "]"; - os << std::endl; } void diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 0b5e41633..9db70be9c 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -82,6 +82,7 @@ public: * Print the content of the packet backward. */ void PrintBackward (void); + void SetSeparator (std::string separator); /** * \param printer printer for payload */ @@ -201,6 +202,7 @@ private: PayloadPrinter m_payloadPrinter; DefaultPrinter m_defaultPrinter; bool m_forward; + std::string m_separator; }; } // namespace ns3 @@ -296,7 +298,6 @@ void PacketPrinter::DoDefaultPrint (std::ostream &os, uint32_t packetUid, uint32_t size, const T *chunk) { chunk->Print (os); - os << std::endl; } From 10d053a8388725f9398fd6de485fa7b71ab0619f Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 13 Jun 2007 00:07:17 +0200 Subject: [PATCH 101/116] comment the sample code a little bit --- samples/main-packet-printer.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/samples/main-packet-printer.cc b/samples/main-packet-printer.cc index aae9b54fe..d21210678 100644 --- a/samples/main-packet-printer.cc +++ b/samples/main-packet-printer.cc @@ -54,6 +54,8 @@ MY_HEADER(C,20); void DefaultPrint (void) { + // We create a packet with 1000 bytes of zero payload + // and add 3 headers to this packet. Packet p (1000); MyHeaderA a; MyHeaderB b; @@ -70,9 +72,11 @@ void DefaultPrint (void) std::cout << std::endl; + // Now, we fragment our packet in 3 consecutive pieces. Packet p1 = p.CreateFragment (0, 2); Packet p2 = p.CreateFragment (2, 1000); Packet p3 = p.CreateFragment (1002, 128); + std::cout << "fragment1" << std::endl; p1.Print (std::cout); std::cout << std::endl; @@ -83,6 +87,7 @@ void DefaultPrint (void) p3.Print (std::cout); std::cout << std::endl; + // And, finally, we re-aggregate the 3 consecutive pieces. Packet aggregate = p1; aggregate.AddAtEnd (p2); aggregate.AddAtEnd (p3); @@ -118,13 +123,26 @@ DoPrintMyHeaderAFragment (std::ostream &os, uint32_t packetUid, uint32_t size, void NonDefaultPrint (void) { + // create an adhoc packet printer. PacketPrinter printer; + // print from first header to last trailer printer.PrintForward (); + // set a string separator automatically inserted + // between each call to a printing function. printer.SetSeparator (" - "); + // set the default print function: invoked if no + // specialized function has been provided for a header + // or trailer printer.AddDefaultPrinter (MakeCallback (&DoPrintDefault)); + // set the payload print function printer.AddPayloadPrinter (MakeCallback (&DoPrintPayload)); + // set the print function for the header type MyHeaderA. printer.AddHeaderPrinter (MakeCallback (&DoPrintMyHeaderA), MakeCallback (&DoPrintMyHeaderAFragment)); + + + // We create a packet with 1000 bytes of zero payload + // and add 3 headers to this packet. Packet p (1000); MyHeaderA a; MyHeaderB b; @@ -141,6 +159,7 @@ void NonDefaultPrint (void) std::cout << std::endl; + // fragment our packet in 3 pieces Packet p1 = p.CreateFragment (0, 2); Packet p2 = p.CreateFragment (2, 1000); Packet p3 = p.CreateFragment (1002, 128); @@ -154,6 +173,8 @@ void NonDefaultPrint (void) p3.Print (std::cout, printer); std::cout << std::endl; + // aggregate all 3 fragments of the original packet + // to reconstruct a copy of the original packet. Packet aggregate = p1; aggregate.AddAtEnd (p2); aggregate.AddAtEnd (p3); From f4911e544b00d0b20d1941910d39d224e78eb842 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 13 Jun 2007 00:10:40 +0200 Subject: [PATCH 102/116] update packet benchmark --- utils/bench-packets.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index 75489e40d..a6986d272 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -195,24 +195,26 @@ int main (int argc, char *argv[]) char const *nAscii = argv[0] + strlen ("--n="); n = atoi (nAscii); } - if (strncmp ("--enable-metadata", argv[0], strlen ("--enable-metadata")) == 0) - { - Packet::EnableMetadata (); - } argc--; argv++; } - runBench (&benchPrint, n, "print"); - PacketMetadata::SetOptOne (false); runBench (&benchPtrA, n, "a"); runBench (&benchPtrB, n, "b"); runBench (&benchPtrC, n, "c"); + + Packet::EnableMetadata (); + runBench (&benchPrint, n, "print"); + PacketMetadata::SetOptOne (false); + runBench (&benchPtrA, n, "meta-a"); + runBench (&benchPtrB, n, "meta-b"); + runBench (&benchPtrC, n, "meta-c"); PacketMetadata::SetOptOne (true); - runBench (&benchPtrA, n, "a-opt"); - runBench (&benchPtrB, n, "b-opt"); - runBench (&benchPtrC, n, "c-opt"); + runBench (&benchPtrA, n, "meta-a-opt"); + runBench (&benchPtrB, n, "meta-b-opt"); + runBench (&benchPtrC, n, "meta-c-opt"); + return 0; } From 87c5cb570691ea6fd0318e06670cab1bbed2c1cb Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 13 Jun 2007 00:20:53 +0200 Subject: [PATCH 103/116] add separator support to backward printing --- src/common/packet-metadata.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 737cc7ac5..4db064d99 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -1053,6 +1053,10 @@ PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &print { break; } + if (item.prev != 0xffff) + { + os << printer.m_separator; + } current = item.prev; } } From 50f2fc5a164fa503445f338c38961271574fc27d Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 21 Jun 2007 11:01:15 +0200 Subject: [PATCH 104/116] fix small variable name typo --- src/common/packet.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/packet.h b/src/common/packet.h index 69ebdc392..09090164c 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -342,8 +342,8 @@ Packet::AddTrailer (T const &trailer) "Must pass Trailer subclass to Packet::AddTrailer"); uint32_t size = trailer.GetSize (); m_buffer.AddAtEnd (size); - Buffer::Iterator start = m_buffer.End (); - trailer.Serialize (start); + Buffer::Iterator end = m_buffer.End (); + trailer.Serialize (end); m_metadata.AddTrailer (trailer, size); } template From 2964b909258d3ddf3d5e6e7d27b732e3b34ce24b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 21 Jun 2007 11:07:04 +0200 Subject: [PATCH 105/116] add testcase, fix bug --- src/common/buffer.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 2c64f8920..07a370afa 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -224,7 +224,7 @@ Buffer::AddAtEnd (uint32_t end) uint32_t newSize = m_size + end; struct Buffer::BufferData *newData = Buffer::Allocate (newSize, 0); memcpy (newData->m_data, GetStart (), m_size); - newData->m_initialStart = m_data->m_initialStart; + newData->m_initialStart = m_data->m_initialStart - m_start; m_data->m_count--; if (m_data->m_count == 0) { @@ -663,6 +663,12 @@ BufferTest::RunTests (void) i.Prev (4); i.WriteU8 (1, 4); + buffer = Buffer (1); + buffer.AddAtEnd (100); + i = buffer.End (); + i.Prev (100); + i.WriteU8 (1, 100); + return ok; } From 993dc85f8f4321cc9f3b4dc536f53d7d539fd557 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 28 Jun 2007 11:07:38 +0200 Subject: [PATCH 106/116] change default pretty printing output format, add doc to metadata data structures --- src/common/packet-metadata.cc | 5 +-- src/common/packet-metadata.h | 59 +++++++++++++++++++++++++++++--- src/common/packet-printer.cc | 25 ++++++++++---- src/common/packet-printer.h | 11 ++++++ src/internet-node/ipv4-header.cc | 56 +++++++++++++++++------------- src/internet-node/udp-header.cc | 11 +++--- src/node/llc-snap-header.cc | 6 ++-- 7 files changed, 128 insertions(+), 45 deletions(-) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 4db064d99..120c742f7 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -953,13 +953,14 @@ PacketMetadata::DoPrint (struct PacketMetadata::SmallItem *item, uint32_t curren // payload. printer.PrintPayload (os, extraItem.packetUid, item->size, extraItem.fragmentStart, - extraItem.fragmentEnd); + item->size - extraItem.fragmentEnd); } else if (extraItem.fragmentStart != 0 || extraItem.fragmentEnd != item->size) { printer.PrintChunkFragment (uid, os, extraItem.packetUid, item->size, - extraItem.fragmentStart, extraItem.fragmentEnd); + extraItem.fragmentStart, + item->size - extraItem.fragmentEnd); } else if (PacketPrinter::IsHeader (uid)) { diff --git a/src/common/packet-metadata.h b/src/common/packet-metadata.h index cb96ddd10..839286950 100644 --- a/src/common/packet-metadata.h +++ b/src/common/packet-metadata.h @@ -66,27 +66,71 @@ public: static void PrintStats (void); private: - /** - head -(next)-> tail - ^ | - \---(prev)---| - */ struct Data { + /* number of references to this struct Data instance. */ uint16_t m_count; + /* size (in bytes) of m_data buffer below */ uint16_t m_size; + /* max of the m_used field over all objects which + * reference this struct Data instance */ uint16_t m_dirtyEnd; + /* variable-sized buffer of bytes */ uint8_t m_data[10]; }; + /* Note that since the next and prev fields are 16 bit integers + and since the value 0xffff is reserved to identify the + fact that the end or the start of the list is reached, + only a limited number of elements can be stored in + a m_data byte buffer. + */ struct SmallItem { + /* offset (in bytes) from start of m_data buffer + to next element in linked list. value is 0xffff + if next element does not exist. + */ uint16_t next; + /* offset (in bytes) from start of m_data buffer + to previous element in linked list. value is 0xffff + if previous element does not exist. + */ uint16_t prev; + /* the high 31 bits of this field identify the + type of the header or trailer represented by + this item: the value zero represents payload. + If the low bit of this uid is one, an ExtraItem + structure follows this SmallItem structure. + */ uint32_t typeUid; + /* the size (in bytes) of the header or trailer represented + by this element. + */ uint32_t size; + /* this field tries to uniquely identify each header or + trailer _instance_ while the typeUid field uniquely + identifies each header or trailer _type_. This field + is used to test whether two items are equal in the sense + that they represent the same header or trailer instance. + That equality test is based on the typeUid and chunkUid + fields so, the likelyhood that two header instances + share the same chunkUid _and_ typeUid is very small + unless they are really representations of the same header + instance. + */ uint16_t chunkUid; }; struct ExtraItem { + /* offset (in bytes) from start of original header to + the start of the fragment still present. + */ uint32_t fragmentStart; + /* offset (in bytes) from start of original header to + the end of the fragment still present. + */ uint32_t fragmentEnd; + /* the packetUid of the packet in which this header or trailer + was first added. It could be different from the m_packetUid + field if the user has aggregated multiple packets into one. + */ uint32_t packetUid; }; @@ -138,6 +182,11 @@ private: static uint16_t m_chunkUid; struct Data *m_data; + /** + head -(next)-> tail + ^ | + \---(prev)---| + */ uint16_t m_head; uint16_t m_tail; uint16_t m_used; diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 37cddbf59..4dfebf6dc 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -78,7 +78,7 @@ PacketPrinter::CreateStaticDefault (void) static PacketPrinter tmp; tmp.PrintForward (); tmp.AddPayloadPrinter (MakeCallback (&PacketPrinter::DoDefaultPrintPayload)); - tmp.SetSeparator ("\n"); + tmp.SetSeparator (" "); return &tmp; } @@ -158,9 +158,15 @@ PacketPrinter::DoDefaultPrintPayload (std::ostream & os, uint32_t size, struct PacketPrinter::FragmentInformation info) { - os << "data "; - os << "[" << info.start << ":" << info.end << "] -> " - << "[0:" << size << "]"; + os << "DATA (" + << "length " << size - (info.end + info.start); + if (info.start != 0 || info.end != 0) + { + os << " " + << "trim_start " << info.start << " " + << "trim_end " << info.end; + } + os << ")"; } void @@ -180,9 +186,14 @@ PacketPrinter::DoDefaultPrintFragment (std::ostream & os, std::string &name, struct PacketPrinter::FragmentInformation info) { - os << name << " "; - os << "[" << info.start << ":" << info.end << "] -> " - << "[0:" << size << "]"; + NS_ASSERT (info.start != 0 || info.end != 0); + os << name << " " + << "(" + << "length " << size - (info.end + info.start) << " " + << "trim_start " << info.start << " " + << "trim_end " << info.end + << ")" + ; } void diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index 9db70be9c..cd340545d 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -43,9 +43,19 @@ class Chunk; class PacketPrinter { public: + /** + * \brief indicates how many bytes were trimmed from a header + * or a trailer. + */ struct FragmentInformation { + /** + * The number of bytes trimmed from the start of the header or the trailer. + */ uint32_t start; + /** + * The number of bytes trimmed from the end of the header or the trailer. + */ uint32_t end; }; /** @@ -297,6 +307,7 @@ template void PacketPrinter::DoDefaultPrint (std::ostream &os, uint32_t packetUid, uint32_t size, const T *chunk) { + os << chunk->GetName () << " "; chunk->Print (os); } diff --git a/src/internet-node/ipv4-header.cc b/src/internet-node/ipv4-header.cc index 6242bec23..44bc46fd2 100644 --- a/src/internet-node/ipv4-header.cc +++ b/src/internet-node/ipv4-header.cc @@ -28,17 +28,6 @@ NS_DEBUG_COMPONENT_DEFINE ("Ipv4Header"); namespace ns3 { -static uint16_t -UtilsNtoh16 (uint16_t v) -{ - uint16_t val; - uint8_t *array; - array = (uint8_t *)&v; - val = (array[0] << 8) | (array[1] << 0); - return val; -} - - bool Ipv4Header::m_calcChecksum = false; Ipv4Header::Ipv4Header () @@ -193,24 +182,45 @@ Ipv4Header::IsChecksumOk (void) const std::string Ipv4Header::DoGetName (void) const { - return "Ipv4"; + return "IPV4"; } void Ipv4Header::PrintTo (std::ostream &os) const { // ipv4, right ? - os << "(ipv4)" - << " tos=" << (uint32_t)m_tos - << ", payload length=" << UtilsNtoh16 (m_payloadSize) - << ", id=" << m_identification - << ", " << (IsLastFragment ()?"last":"more") - << ", " << (IsDontFragment ()?"dont":"may") - << ", frag offset=" << m_fragmentOffset - << ", ttl=" << m_ttl - << ", protocol=" << m_protocol - << ", source=" << m_source - << ", destination=" << m_destination; + std::string flags; + if (m_flags == 0) + { + flags = "none"; + } + else if (m_flags & MORE_FRAGMENTS && + m_flags & DONT_FRAGMENT) + { + flags = "MF|DF"; + } + else if (m_flags & DONT_FRAGMENT) + { + flags = "DF"; + } + else if (m_flags & MORE_FRAGMENTS) + { + flags = "MF"; + } + else + { + flags = "XX"; + } + os << "(" + << "tos 0x" << std::hex << m_tos << std::dec << " " + << "ttl " << m_ttl << " " + << "id " << m_identification << " " + << "offset " << m_fragmentOffset << " " + << "flags [" << flags << "] " + << "length: " << (m_payloadSize + 5 * 4) + << ") " + << m_source << " > " << m_destination + ; } uint32_t Ipv4Header::GetSerializedSize (void) const diff --git a/src/internet-node/udp-header.cc b/src/internet-node/udp-header.cc index c4ef2642d..a7a95ca49 100644 --- a/src/internet-node/udp-header.cc +++ b/src/internet-node/udp-header.cc @@ -94,16 +94,17 @@ UdpHeader::InitializeChecksum (Ipv4Address source, std::string UdpHeader::DoGetName (void) const { - return "Udp"; + return "UDP"; } void UdpHeader::PrintTo (std::ostream &os) const { - os << "(udp)" - << ", port source=" << m_sourcePort - << ", port destination=" << m_destinationPort - << ", length=" << m_payloadSize; + os << "(" + << "length: " << m_payloadSize + GetSize () + << ") " + << m_sourcePort << " > " << m_destinationPort + ; } uint32_t diff --git a/src/node/llc-snap-header.cc b/src/node/llc-snap-header.cc index b7bd73121..ee37ffecf 100644 --- a/src/node/llc-snap-header.cc +++ b/src/node/llc-snap-header.cc @@ -50,17 +50,17 @@ LlcSnapHeader::GetSerializedSize (void) const std::string LlcSnapHeader::DoGetName (void) const { - return "LlcSnap"; + return "LLCSNAP"; } void LlcSnapHeader::PrintTo (std::ostream &os) const { - os << "(mac)" - << " EtherType: "; + os << "(type 0x"; os.setf (std::ios::hex, std::ios::basefield); os << m_etherType; os.setf (std::ios::dec, std::ios::basefield); + os << ")"; } void From 35f80fc5c39ef7852add96c1ea25184d429b13b3 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 28 Jun 2007 11:48:37 +0200 Subject: [PATCH 107/116] modify sample packet printer to use ipv4 and udp headers --- SConstruct | 6 +- samples/main-packet-printer.cc | 110 ++++++++++----------------------- src/common/packet-printer.cc | 2 +- 3 files changed, 35 insertions(+), 83 deletions(-) diff --git a/SConstruct b/SConstruct index eda19d7eb..eb287a041 100644 --- a/SConstruct +++ b/SConstruct @@ -307,8 +307,6 @@ inode.add_sources ([ 'udp-impl.cc', ]) inode.add_headers ([ - 'ipv4-header.h', - 'udp-header.h', 'ipv4-checksum.h', 'arp-header.h', 'arp-cache.h', @@ -338,6 +336,8 @@ inode.add_inst_headers ([ 'internet-node.h', 'ascii-trace.h', 'pcap-trace.h', + 'ipv4-header.h', + 'udp-header.h', ]) @@ -400,7 +400,7 @@ sample_debug.add_source('main-debug-other.cc') sample_packet_printer = build.Ns3Module('sample-packet-printer', 'samples') sample_packet_printer.set_executable() ns3.add(sample_packet_printer) -sample_packet_printer.add_dep('common') +sample_packet_printer.add_deps (['common', 'internet-node']) sample_packet_printer.add_source('main-packet-printer.cc') diff --git a/samples/main-packet-printer.cc b/samples/main-packet-printer.cc index d21210678..5e0612595 100644 --- a/samples/main-packet-printer.cc +++ b/samples/main-packet-printer.cc @@ -2,70 +2,25 @@ #include "ns3/packet.h" #include "ns3/header.h" #include "ns3/packet-printer.h" +#include "ns3/ipv4-header.h" +#include "ns3/udp-header.h" using namespace ns3; -#define MY_HEADER(name,size) \ -class MyHeader##name : public Header \ -{ \ -public: \ - void Set (uint8_t v) \ - { \ - m_v = v; \ - } \ - uint8_t Get (void) const \ - { \ - return m_v; \ - } \ -private: \ - virtual std::string DoGetName (void) const \ - { \ - return #name; \ - } \ - virtual void PrintTo (std::ostream &os) const \ - { \ - uint32_t v = m_v; \ - os << #name << ", v=" << v; \ - } \ - virtual uint32_t GetSerializedSize (void) const \ - { \ - return size; \ - } \ - virtual void SerializeTo (Buffer::Iterator start) const \ - { \ - start.WriteU8 (m_v, size); \ - } \ - virtual uint32_t DeserializeFrom (Buffer::Iterator start) \ - { \ - NS_ASSERT (size >= 1); \ - m_v = start.ReadU8 (); \ - for (uint32_t i = 2; i < size; i++) \ - { \ - NS_ASSERT (start.ReadU8 () == m_v); \ - } \ - return size; \ - } \ - uint8_t m_v; \ -}; - -MY_HEADER(A,10); -MY_HEADER(B,100); -MY_HEADER(C,20); void DefaultPrint (void) { // We create a packet with 1000 bytes of zero payload // and add 3 headers to this packet. Packet p (1000); - MyHeaderA a; - MyHeaderB b; - MyHeaderC c; - a.Set (1); - b.Set (3); - c.Set (2); - p.AddHeader (a); - p.AddHeader (b); - p.AddHeader (c); + Ipv4Header ipv4; + UdpHeader udp; + ipv4.SetSource (Ipv4Address ("192.168.0.1")); + ipv4.SetDestination (Ipv4Address ("192.168.0.2")); + udp.SetSource (1025); + udp.SetDestination (80); + p.AddHeader (udp); + p.AddHeader (ipv4); std::cout << "full packet size=" << p.GetSize () << std::endl; p.Print (std::cout); @@ -75,7 +30,7 @@ void DefaultPrint (void) // Now, we fragment our packet in 3 consecutive pieces. Packet p1 = p.CreateFragment (0, 2); Packet p2 = p.CreateFragment (2, 1000); - Packet p3 = p.CreateFragment (1002, 128); + Packet p3 = p.CreateFragment (1002, 26); std::cout << "fragment1" << std::endl; p1.Print (std::cout); @@ -98,27 +53,26 @@ void DefaultPrint (void) void DoPrintDefault (std::ostream &os,uint32_t packetUid, uint32_t size, - std::string &name, struct PacketPrinter::FragmentInformation info) + std::string &name, struct PacketPrinter::FragmentInformation info) { - os << "default name="<Get (); - os << "A v=" << v; + os << "IPV4 " << ipv4->GetSource () << " > " << ipv4->GetDestination (); } void -DoPrintMyHeaderAFragment (std::ostream &os, uint32_t packetUid, uint32_t size, - std::string &name, struct PacketPrinter::FragmentInformation info) +DoPrintIpv4HeaderFragment (std::ostream &os, uint32_t packetUid, uint32_t size, + std::string &name, struct PacketPrinter::FragmentInformation info) { - os << "A fragment"; + os << "IPV4 fragment"; } void NonDefaultPrint (void) @@ -136,23 +90,21 @@ void NonDefaultPrint (void) printer.AddDefaultPrinter (MakeCallback (&DoPrintDefault)); // set the payload print function printer.AddPayloadPrinter (MakeCallback (&DoPrintPayload)); - // set the print function for the header type MyHeaderA. - printer.AddHeaderPrinter (MakeCallback (&DoPrintMyHeaderA), - MakeCallback (&DoPrintMyHeaderAFragment)); + // set the print function for the header type Ipv4Header. + printer.AddHeaderPrinter (MakeCallback (&DoPrintIpv4Header), + MakeCallback (&DoPrintIpv4HeaderFragment)); // We create a packet with 1000 bytes of zero payload - // and add 3 headers to this packet. Packet p (1000); - MyHeaderA a; - MyHeaderB b; - MyHeaderC c; - a.Set (1); - b.Set (3); - c.Set (2); - p.AddHeader (a); - p.AddHeader (b); - p.AddHeader (c); + Ipv4Header ipv4; + UdpHeader udp; + ipv4.SetSource (Ipv4Address ("192.168.0.1")); + ipv4.SetDestination (Ipv4Address ("192.168.0.2")); + udp.SetSource (1025); + udp.SetDestination (80); + p.AddHeader (udp); + p.AddHeader (ipv4); std::cout << "full packet size=" << p.GetSize () << std::endl; p.Print (std::cout, printer); @@ -162,7 +114,7 @@ void NonDefaultPrint (void) // fragment our packet in 3 pieces Packet p1 = p.CreateFragment (0, 2); Packet p2 = p.CreateFragment (2, 1000); - Packet p3 = p.CreateFragment (1002, 128); + Packet p3 = p.CreateFragment (1002, 26); std::cout << "fragment1" << std::endl; p1.Print (std::cout, printer); std::cout << std::endl; diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index 4dfebf6dc..9ccda7668 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -105,7 +105,7 @@ PacketPrinter::PrintChunk (uint32_t chunkUid, std::string name = cb (); struct PacketPrinter::FragmentInformation info; info.start = 0; - info.end = size; + info.end = 0; if (!m_defaultPrinter.IsNull ()) { m_defaultPrinter (os, packetUid, size, name, info); From 18e53720d1efb435412dd2cef361e0d05bd0c799 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 28 Jun 2007 11:52:16 +0200 Subject: [PATCH 108/116] change arp pretty printing to new format --- src/internet-node/arp-header.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/internet-node/arp-header.cc b/src/internet-node/arp-header.cc index 0263a29ee..e340404f4 100644 --- a/src/internet-node/arp-header.cc +++ b/src/internet-node/arp-header.cc @@ -86,26 +86,33 @@ ArpHeader::GetDestinationIpv4Address (void) std::string ArpHeader::DoGetName (void) const { - return "Arp"; + return "ARP"; } void ArpHeader::PrintTo (std::ostream &os) const { - os << "(arp)"; if (IsRequest ()) { - os << " source mac: " << m_macSource - << " source ipv4: " << m_ipv4Source - << " dest ipv4: " << m_ipv4Dest; + os << "(" + << "request " + << "source mac: " << m_macSource << " " + << "source ipv4: " << m_ipv4Source << " " + << "dest ipv4: " << m_ipv4Dest + << ")" + ; } else { NS_ASSERT (IsReply ()); - os << " source mac: " << m_macSource - << " source ipv4: " << m_ipv4Source - << " dest mac: " << m_macDest - << " dest ipv4: " < Date: Thu, 28 Jun 2007 11:52:50 +0200 Subject: [PATCH 109/116] use pretty printing in ascii output --- src/internet-node/ascii-trace.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/internet-node/ascii-trace.cc b/src/internet-node/ascii-trace.cc index 7750bbdac..1314f2150 100644 --- a/src/internet-node/ascii-trace.cc +++ b/src/internet-node/ascii-trace.cc @@ -46,12 +46,14 @@ AsciiTrace::~AsciiTrace () void AsciiTrace::TraceAllQueues (void) { + Packet::EnableMetadata (); TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/*", MakeCallback (&AsciiTrace::LogDevQueue, this)); } void AsciiTrace::TraceAllNetDeviceRx (void) { + Packet::EnableMetadata (); TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/rx", MakeCallback (&AsciiTrace::LogDevRx, this)); } @@ -115,7 +117,7 @@ AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet) context.Get (interfaceIndex); m_os << "interface=" << interfaceIndex << " "; m_os << "pkt-uid=" << packet.GetUid () << " "; - PrintType (packet); + packet.Print (m_os); m_os << std::endl; } void @@ -129,7 +131,7 @@ AsciiTrace::LogDevRx (TraceContext const &context, Packet &p) context.Get (interfaceIndex); m_os << "interface=" << interfaceIndex << " "; m_os << "pkt-uid=" << p.GetUid () << " "; - PrintType (p); + p.Print (m_os); m_os << std::endl; } From b937ec5a8798593e29894ca794fbefe0c5d25003 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 28 Jun 2007 12:00:00 +0200 Subject: [PATCH 110/116] add failing assert --- src/common/packet-metadata.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 120c742f7..01125bd95 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -997,6 +997,7 @@ PacketMetadata::GetTotalSize (void) const { break; } + NS_ASSERT (current != item.next); current = item.next; } return totalSize; @@ -1036,6 +1037,7 @@ PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &print { os << printer.m_separator; } + NS_ASSERT (current != item.next); current = item.next; } } @@ -1058,6 +1060,7 @@ PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &print { os << printer.m_separator; } + NS_ASSERT (current != item.prev); current = item.prev; } } From 23f4e85f87a5a755b3f50fc0eb7109d0f42b1bfb Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 28 Jun 2007 12:29:21 +0200 Subject: [PATCH 111/116] fix basic tests, add new test, add a bunch of asserts, add XXX comment --- src/common/packet-metadata.cc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 01125bd95..b70f65fca 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -403,6 +403,7 @@ uint16_t PacketMetadata::AddSmall (const struct PacketMetadata::SmallItem *item) { NS_ASSERT (m_data != 0); + NS_ASSERT (m_used != item->prev && m_used != item->next); if (g_optOne) { uint32_t typeUidSize = GetUleb128Size (item->typeUid); @@ -452,6 +453,7 @@ PacketMetadata::AddSmall (const struct PacketMetadata::SmallItem *item) { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); + NS_ASSERT (written >= 8); return written; } } @@ -470,6 +472,7 @@ PacketMetadata::AddBig (uint32_t next, uint32_t prev, { NS_ASSERT (m_data != 0); uint32_t typeUid = ((item->typeUid & 0x1) == 0x1)?item->typeUid:item->typeUid+1; + NS_ASSERT (m_used != prev && m_used != next); append: uint8_t *start = &m_data->m_data[m_used]; uint8_t *end = &m_data->m_data[m_data->m_size]; @@ -493,6 +496,7 @@ PacketMetadata::AddBig (uint32_t next, uint32_t prev, { uintptr_t written = buffer - start; NS_ASSERT (written <= 0xffff); + NS_ASSERT (written >= 14); return written; } } @@ -796,6 +800,7 @@ PacketMetadata::AddAtEnd (PacketMetadata const&o) // replace previous tail. lastExtraItem.fragmentEnd = extraItem.fragmentEnd; NS_ASSERT (m_tail == lastTail); + // XXX This call might be wrong. ReplaceTail (&lastItem, &lastExtraItem, lastTailSize); } else @@ -1319,7 +1324,7 @@ PacketMetadataTest::PrintFragment (std::ostream &os,uint32_t packetUid, uint32_t size,std::string & name, struct PacketPrinter::FragmentInformation info) { - m_prints.push_back (info.end - info.start); + m_prints.push_back (size - (info.end + info.start)); } void PacketMetadataTest::PrintDefault (std::ostream& os,uint32_t packetUid, @@ -1333,7 +1338,7 @@ PacketMetadataTest::PrintPayload (std::ostream &os,uint32_t packetUid, uint32_t size, struct PacketPrinter::FragmentInformation info) { - m_prints.push_back (info.end - info.start); + m_prints.push_back (size - (info.end + info.start)); } @@ -1642,7 +1647,13 @@ PacketMetadataTest::RunTests (void) p = Packet (2000); CHECK_HISTORY (p, 1, 2000); - + p = Packet (); + ADD_TRAILER (p, 10); + ADD_HEADER (p, 5); + p1 = p.CreateFragment (0, 8); + p2 = p.CreateFragment (8, 7); + p1.AddAtEnd (p2); + CHECK_HISTORY (p, 2, 5, 10); return ok; } From ce57b5d156ac0ca81e86dc961b39d229fedba434 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 28 Jun 2007 13:01:40 +0200 Subject: [PATCH 112/116] more asserts, add failing tests, fix them --- src/common/packet-metadata.cc | 42 ++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index b70f65fca..52ff5bcd3 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -370,6 +370,7 @@ PacketMetadata::UpdateTail (uint16_t written) } NS_ASSERT (m_tail != 0xffff); NS_ASSERT (m_head != 0xffff); + NS_ASSERT (written >= 8); m_used += written; m_data->m_dirtyEnd = m_used; } @@ -395,6 +396,7 @@ PacketMetadata::UpdateHead (uint16_t written) } NS_ASSERT (m_tail != 0xffff); NS_ASSERT (m_head != 0xffff); + NS_ASSERT (written >= 8); m_used += written; m_data->m_dirtyEnd = m_used; } @@ -698,7 +700,7 @@ PacketMetadata::DoRemoveHeader (uint32_t uid, uint32_t size) } struct PacketMetadata::SmallItem item; struct PacketMetadata::ExtraItem extraItem; - ReadItems (m_head, &item, &extraItem); + uint32_t read = ReadItems (m_head, &item, &extraItem); if ((item.typeUid & 0xfffffffe) != uid || item.size != size) { @@ -710,11 +712,19 @@ PacketMetadata::DoRemoveHeader (uint32_t uid, uint32_t size) { NS_FATAL_ERROR ("Removing incomplete header."); } - m_head = item.next; - if (m_head > m_tail) + if (m_head + read == m_used) { m_used = m_head; } + if (item.next == 0xffff) + { + m_head = 0xffff; + m_tail = 0xffff; + } + else + { + m_head = item.next; + } } void PacketMetadata::DoAddTrailer (uint32_t uid, uint32_t size) @@ -742,7 +752,7 @@ PacketMetadata::DoRemoveTrailer (uint32_t uid, uint32_t size) } struct PacketMetadata::SmallItem item; struct PacketMetadata::ExtraItem extraItem; - ReadItems (m_tail, &item, &extraItem); + uint32_t read = ReadItems (m_tail, &item, &extraItem); if ((item.typeUid & 0xfffffffe) != uid || item.size != size) { @@ -754,10 +764,18 @@ PacketMetadata::DoRemoveTrailer (uint32_t uid, uint32_t size) { NS_FATAL_ERROR ("Removing incomplete trailer."); } - m_tail = item.prev; - if (m_tail > m_head) + if (m_tail + read == m_used) { m_used = m_tail; + } + if (item.prev == 0xffff) + { + m_head = 0xffff; + m_tail = 0xffff; + } + else + { + m_tail = item.prev; } } void @@ -1655,6 +1673,18 @@ PacketMetadataTest::RunTests (void) p1.AddAtEnd (p2); CHECK_HISTORY (p, 2, 5, 10); + p = Packet (); + ADD_TRAILER (p, 10); + REM_TRAILER (p, 10); + ADD_TRAILER (p, 10); + CHECK_HISTORY (p, 1, 10); + + p = Packet (); + ADD_HEADER (p, 10); + REM_HEADER (p, 10); + ADD_HEADER (p, 10); + CHECK_HISTORY (p, 1, 10); + return ok; } From 3bb28c049f752d7e78732d0acac6a6afa52424f7 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 28 Jun 2007 13:43:27 +0200 Subject: [PATCH 113/116] test and fix backward printing --- src/common/packet-metadata.cc | 117 ++++++++++++++++++++-------------- src/common/packet-metadata.h | 3 +- 2 files changed, 71 insertions(+), 49 deletions(-) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 52ff5bcd3..8839d79a4 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -964,44 +964,43 @@ PacketMetadata::PrintDefault (std::ostream &os, Buffer buffer) const } uint32_t -PacketMetadata::DoPrint (struct PacketMetadata::SmallItem *item, uint32_t current, - Buffer data, uint32_t offset, const PacketPrinter &printer, - std::ostream &os) const +PacketMetadata::DoPrint (const struct PacketMetadata::SmallItem *item, + const struct PacketMetadata::ExtraItem *extraItem, + Buffer data, uint32_t offset, const PacketPrinter &printer, + std::ostream &os) const { - PacketMetadata::ExtraItem extraItem; - ReadItems (current, item, &extraItem); uint32_t uid = item->typeUid & 0xfffffffe; if (uid == 0) { // payload. - printer.PrintPayload (os, extraItem.packetUid, item->size, - extraItem.fragmentStart, - item->size - extraItem.fragmentEnd); + printer.PrintPayload (os, extraItem->packetUid, item->size, + extraItem->fragmentStart, + item->size - extraItem->fragmentEnd); } - else if (extraItem.fragmentStart != 0 || - extraItem.fragmentEnd != item->size) + else if (extraItem->fragmentStart != 0 || + extraItem->fragmentEnd != item->size) { - printer.PrintChunkFragment (uid, os, extraItem.packetUid, item->size, - extraItem.fragmentStart, - item->size - extraItem.fragmentEnd); + printer.PrintChunkFragment (uid, os, extraItem->packetUid, item->size, + extraItem->fragmentStart, + item->size - extraItem->fragmentEnd); } else if (PacketPrinter::IsHeader (uid)) { ns3::Buffer::Iterator j = data.Begin (); j.Next (offset); - printer.PrintChunk (uid, j, os, extraItem.packetUid, item->size); + printer.PrintChunk (uid, j, os, extraItem->packetUid, item->size); } else if (PacketPrinter::IsTrailer (uid)) { ns3::Buffer::Iterator j = data.End (); j.Prev (data.GetSize () - (offset + item->size)); - printer.PrintChunk (uid, j, os, extraItem.packetUid, item->size); + printer.PrintChunk (uid, j, os, extraItem->packetUid, item->size); } else { NS_ASSERT (false); } - return extraItem.fragmentEnd - extraItem.fragmentStart; + return extraItem->fragmentEnd - extraItem->fragmentStart; } uint32_t @@ -1041,18 +1040,18 @@ PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &print } NS_ASSERT (m_data != 0); NS_ASSERT (GetTotalSize () == data.GetSize ()); + struct PacketMetadata::SmallItem item; + struct PacketMetadata::ExtraItem extraItem; if (printer.m_forward) { - uint32_t tail = m_tail; - uint32_t head = m_head; - uint32_t current = head; + uint32_t current = m_head; uint32_t offset = 0; while (current != 0xffff) { - struct PacketMetadata::SmallItem item; - uint32_t realSize = DoPrint (&item, current, data, offset, printer, os); + ReadItems (current, &item, &extraItem); + uint32_t realSize = DoPrint (&item, &extraItem, data, offset, printer, os); offset += realSize; - if (current == tail) + if (current == m_tail) { break; } @@ -1066,16 +1065,14 @@ PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &print } else { - uint32_t head = m_head; - uint32_t tail = m_tail; - uint32_t current = head; - uint32_t offset = 0; + uint32_t current = m_tail; + uint32_t offset = data.GetSize (); while (current != 0xffff) { - struct PacketMetadata::SmallItem item; - uint32_t realSize = DoPrint (&item, current, data, offset, printer, os); + ReadItems (current, &item, &extraItem); + uint32_t realSize = DoPrint (&item, &extraItem, data, offset - item.size, printer, os); offset -= realSize; - if (current == tail) + if (current == m_head) { break; } @@ -1248,7 +1245,7 @@ class PacketMetadataTest : public Test { public: PacketMetadataTest (); virtual ~PacketMetadataTest (); - bool CheckHistory (Packet p, char *file, int line, uint32_t n, ...); + bool CheckHistory (Packet p, const char *file, int line, uint32_t n, ...); virtual bool RunTests (void); private: template @@ -1269,6 +1266,7 @@ private: template void RegisterTrailer (void); void CleanupPrints (void); + bool Check (const char *file, int line, std::list expected); bool m_headerError; @@ -1366,14 +1364,9 @@ PacketMetadataTest::CleanupPrints (void) m_prints.clear (); } -bool -PacketMetadataTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ...) +bool +PacketMetadataTest::Check (const char *file, int line, std::list expected) { - m_headerError = false; - m_trailerError = false; - va_list ap; - p.Print (std::cerr, m_printer); - va_start (ap, n); if (m_headerError) { std::cout << "PacketMetadata header error. file=" << file @@ -1386,21 +1379,20 @@ PacketMetadataTest::CheckHistory (Packet p, char *file, int line, uint32_t n, .. << ", line=" << line << std::endl; return false; } - if (n != m_prints.size ()) + if (expected.size () != m_prints.size ()) { goto error; } - for (std::list::iterator i = m_prints.begin (); - i != m_prints.end (); i++) + for (std::list::iterator i = m_prints.begin (), + j = expected.begin (); + i != m_prints.end (); i++, j++) { - int v = va_arg (ap, int); - if (v != *i) + NS_ASSERT (j != expected.end ()); + if (*j != *i) { - va_end (ap); goto error; } } - va_end (ap); return true; error: std::cout << "PacketMetadata error. file="<< file @@ -1411,15 +1403,45 @@ PacketMetadataTest::CheckHistory (Packet p, char *file, int line, uint32_t n, .. std::cout << *i << ", "; } std::cout << "\", expected: \""; + for (std::list::iterator j = expected.begin (); + j != expected.end (); j++) + { + std::cout << *j << ", "; + } + std::cout << "\"" << std::endl; + return false; +} + +bool +PacketMetadataTest::CheckHistory (Packet p, const char *file, int line, uint32_t n, ...) +{ + m_headerError = false; + m_trailerError = false; + std::list expected; + va_list ap; va_start (ap, n); for (uint32_t j = 0; j < n; j++) { int v = va_arg (ap, int); - std::cout << v << ", "; + expected.push_back (v); } va_end (ap); - std::cout << "\"" << std::endl; - return false; + + m_printer.PrintForward (); + p.Print (std::cerr, m_printer); + bool ok = Check (file, line, expected); + CleanupPrints (); + if (!ok) + { + return false; + } + + m_printer.PrintBackward (); + p.Print (std::cerr, m_printer); + expected.reverse (); + ok = Check (file, line, expected); + CleanupPrints (); + return ok; } #define ADD_HEADER(p, n) \ @@ -1453,7 +1475,6 @@ PacketMetadataTest::CheckHistory (Packet p, char *file, int line, uint32_t n, .. { \ ok = false; \ } \ - CleanupPrints (); \ } bool diff --git a/src/common/packet-metadata.h b/src/common/packet-metadata.h index 839286950..a26e4fbd4 100644 --- a/src/common/packet-metadata.h +++ b/src/common/packet-metadata.h @@ -162,7 +162,8 @@ private: void AppendValueExtra (uint32_t value, uint8_t *buffer); inline void Reserve (uint32_t n); void ReserveCopy (uint32_t n); - uint32_t DoPrint (struct PacketMetadata::SmallItem *item, uint32_t current, + uint32_t DoPrint (const struct PacketMetadata::SmallItem *item, + const struct PacketMetadata::ExtraItem *extraItem, Buffer data, uint32_t offset, const PacketPrinter &printer, std::ostream &os) const; uint32_t GetTotalSize (void) const; From 27567324587cc0d2962c45d01b9de38d8d0e89c4 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 28 Jun 2007 13:59:51 +0200 Subject: [PATCH 114/116] add more internal documentation --- src/common/packet-metadata.h | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/common/packet-metadata.h b/src/common/packet-metadata.h index a26e4fbd4..f24b35bed 100644 --- a/src/common/packet-metadata.h +++ b/src/common/packet-metadata.h @@ -32,6 +32,46 @@ namespace ns3 { class Chunk; class Buffer; +/** + * \internal + * \brief handle packet metadata about packet headers and trailers + * + * This class is used by the Packet class to record every operation + * performed on the packet's buffer. This class also provides + * an implementation of the Packet::Print methods which uses + * the metadata to analyse the content of the packet's buffer. + * + * To achieve this, this class maintains a linked list of so-called + * "items", each of which represents a header or a trailer, or + * payload, or a fragment of any of these. Each item contains a "next" + * and a "prev" field which point to the next and previous entries + * in the linked list. The PacketMetadata class maintains a pair + * of pointers to the head and the tail of the linked list. + * + * Each entry in the list also maintains: + * - its native size (the size it had when it was first added + * to the packet) + * - its type: identifies what kind of header, what kind of trailer, + * if it is payload or not + * - the uid of the packet to which it was first added + * - the start and end of the area represented by a fragment + * if it is one. + * + * This linked list is flattened in a byte buffer stored in + * struct PacketMetadata::Data. Each entry of the linked list is + * identified by an offset which identifies the first byte of the + * entry from the start of the data buffer. The size of this data + * buffer is 2^16-1 bytes maximum which somewhat limits the number + * of entries which can be stored in this linked list but it is + * quite unlikely to hit this limit in practice. + * + * Each item of the linked list is a variable-sized byte buffer + * made of a number of fields. Some of these fields are stored + * as fixed-size 32 bit integers, others as fixed-size 16 bit + * integers, and some others as variable-size 32-bit integers. + * The variable-size 32 bit integers are stored using the uleb128 + * encoding. + */ class PacketMetadata { public: static void Enable (void); @@ -87,11 +127,13 @@ private: /* offset (in bytes) from start of m_data buffer to next element in linked list. value is 0xffff if next element does not exist. + stored as a fixed-size 16 bit integer. */ uint16_t next; /* offset (in bytes) from start of m_data buffer to previous element in linked list. value is 0xffff if previous element does not exist. + stored as a fixed-size 16 bit integer. */ uint16_t prev; /* the high 31 bits of this field identify the @@ -99,10 +141,12 @@ private: this item: the value zero represents payload. If the low bit of this uid is one, an ExtraItem structure follows this SmallItem structure. + stored as a variable-size 32 bit integer. */ uint32_t typeUid; /* the size (in bytes) of the header or trailer represented by this element. + stored as a variable-size 32 bit integer. */ uint32_t size; /* this field tries to uniquely identify each header or @@ -115,21 +159,25 @@ private: share the same chunkUid _and_ typeUid is very small unless they are really representations of the same header instance. + stored as a fixed-size 16 bit integer. */ uint16_t chunkUid; }; struct ExtraItem { /* offset (in bytes) from start of original header to the start of the fragment still present. + stored as a variable-size 32 bit integer. */ uint32_t fragmentStart; /* offset (in bytes) from start of original header to the end of the fragment still present. + stored as a variable-size 32 bit integer. */ uint32_t fragmentEnd; /* the packetUid of the packet in which this header or trailer was first added. It could be different from the m_packetUid field if the user has aggregated multiple packets into one. + stored as a fixed-size 32 bit integer. */ uint32_t packetUid; }; From bedbfd18d79e00d2b91ae2ca3fe26bae1ebc26ef Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 29 Jun 2007 08:18:16 +0200 Subject: [PATCH 115/116] add dox doc for header and trailer PrintTo and DoGetName --- src/common/header.h | 13 +++++++++++++ src/common/trailer.h | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/common/header.h b/src/common/header.h index 480dbe65e..609729b26 100644 --- a/src/common/header.h +++ b/src/common/header.h @@ -43,11 +43,24 @@ public: private: /** * \returns a user-readable name to identify this type of header. + * + * The string returned is expected to be a single word with + * all capital letters */ virtual std::string DoGetName (void) const = 0; /** * \param os the std output stream in which this * protocol header must print itself. + * + * Although the header is free to format its output as it + * wishes, it is recommended to follow a few rules to integrate + * with the packet pretty printer: + * - start with flags, small field values located between a + * pair of parens. Values should be separated by whitespace. + * - follow the parens with the important fields, separated by + * whitespace. + * i.e.: + * (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5 */ virtual void PrintTo (std::ostream &os) const = 0; diff --git a/src/common/trailer.h b/src/common/trailer.h index c63fd5d85..92aef295f 100644 --- a/src/common/trailer.h +++ b/src/common/trailer.h @@ -69,11 +69,24 @@ public: private: /** * \returns a user-readable name to identify this type of header. + * + * The string returned is expected to be a single word with + * all capital letters */ virtual std::string DoGetName (void) const = 0; /** * \param os the std output stream in which this * protocol trailer must print itself. + * + * Although the header is free to format its output as it + * wishes, it is recommended to follow a few rules to integrate + * with the packet pretty printer: + * - start with flags, small field values located between a + * pair of parens. Values should be separated by whitespace. + * - follow the parens with the important fields, separated by + * whitespace. + * i.e.: + * (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5 */ virtual void PrintTo (std::ostream &os) const = 0; From fd479088eccf0d2812c3be1307407a7699b3127c Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 2 Jul 2007 18:23:52 +0100 Subject: [PATCH 116/116] WAF scripts update --- src/common/wscript | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/common/wscript b/src/common/wscript index 65753d930..c6f3be7f0 100644 --- a/src/common/wscript +++ b/src/common/wscript @@ -10,9 +10,11 @@ def build(bld): common.uselib_local = ['ns3-core', 'ns3-simulator'] common.source = [ 'buffer.cc', - 'header.cc', 'chunk.cc', + 'header.cc', 'trailer.cc', + 'packet-printer.cc', + 'packet-metadata.cc', 'packet.cc', 'tags.cc', 'pcap-writer.cc', @@ -28,11 +30,13 @@ def build(bld): headers = bld.create_obj('ns3header') headers.source = [ 'buffer.h', - 'header.h', 'chunk.h', + 'header.h', 'trailer.h', 'tags.h', 'packet.h', + 'packet-printer.h', + 'packet-metadata.h', 'uv-trace-source.h', 'sv-trace-source.h', 'fv-trace-source.h',