# HG changeset patch # User Mathieu Lacage # Date 1181213332 -7200 # Node ID 777fcfabc1c8040d0e40893b83b6546f412c9a4b # Parent 62901fdaeb6826e1f59a6c040e53373550cba066 rename packet-history.h to packet-metadata.h diff -r 62901fdaeb68 -r 777fcfabc1c8 SConstruct --- a/SConstruct Thu Jun 07 12:44:44 2007 +0200 +++ b/SConstruct Thu Jun 07 12:48:52 2007 +0200 @@ -189,7 +189,7 @@ 'header.cc', 'trailer.cc', 'packet-printer.cc', - 'packet-history.cc', + 'packet-metadata.cc', 'packet.cc', 'tags.cc', 'pcap-writer.cc', @@ -212,7 +212,7 @@ '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 -r 62901fdaeb68 -r 777fcfabc1c8 src/common/packet-history.cc --- a/src/common/packet-history.cc Thu Jun 07 12:44:44 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1631 +0,0 @@ -/* -*- 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 -#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"); - -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 g_optOne = false; - -void -PacketHistory::Enable (void) -{ - m_enable = true; -} - -void -PacketHistory::SetOptOne (bool optOne) -{ - g_optOne = optOne; -} - -void -PacketHistory::ReserveCopy (uint32_t size) -{ - struct PacketHistory::Data *newData = PacketHistory::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); - } - 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) -{ - NS_ASSERT (m_data != 0); - if (m_data->m_size >= m_used + size && - (m_head == 0xffff || - m_data->m_count == 1 || - m_data->m_dirtyEnd == m_used)) - { - /* enough room, not dirty. */ - } - else - { - /* (enough room and dirty) or (not enough room) */ - ReserveCopy (size); - } -} - -uint32_t -PacketHistory::GetUleb128Size (uint32_t value) const -{ - 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 -{ - 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 *buffer) -{ - buffer[0] = value & 0xff; - value >>= 8; - buffer[1] = value; -} -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::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; - 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; - byte = value & (~0x80); - start[1] = 0x80 | byte; - value >>= 7; - byte = value & (~0x80); - start[2] = value; - *pBuffer = start + 3; - return true; - } - 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; -} - -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) -{ - if (m_head == 0xffff) - { - NS_ASSERT (m_tail == 0xffff); - m_head = m_used; - m_tail = 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; -} - - -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) -{ - 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]; - if (end - start >= 8 && - (m_head == 0xffff || - m_data->m_count == 1 || - m_used == m_data->m_dirtyEnd)) - { - uint8_t *buffer = start; - - Append16 (item->next, buffer); - buffer += 2; - Append16 (item->prev, buffer); - buffer += 2; - if (TryToAppendFast (item->typeUid, &buffer, end) && - TryToAppendFast (item->size, &buffer, end) && - TryToAppend16 (item->chunkUid, &buffer, end)) - { - uintptr_t written = buffer - start; - NS_ASSERT (written <= 0xffff); - return written; - } - } - uint32_t n = GetUleb128Size (item->typeUid); - n += GetUleb128Size (item->size); - n += 2; - n += 2 + 2; - Reserve (n); - goto append; -} - -uint16_t -PacketHistory::AddBig (uint32_t next, uint32_t prev, - const PacketHistory::SmallItem *item, - const PacketHistory::ExtraItem *extraItem) -{ - 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]; - if (end - start >= 14 && - (m_head == 0xffff || - m_data->m_count == 1 || - m_used == m_data->m_dirtyEnd)) - { - uint8_t *buffer = start; - - Append16 (next, buffer); - buffer += 2; - Append16 (prev, buffer); - buffer += 2; - if (TryToAppend (typeUid, &buffer, end) && - TryToAppend (item->size, &buffer, end) && - TryToAppend16 (item->chunkUid, &buffer, end) && - TryToAppend (extraItem->fragmentStart, &buffer, end) && - TryToAppend (extraItem->fragmentEnd, &buffer, end) && - TryToAppend32 (extraItem->packetUid, &buffer, end)) - { - uintptr_t written = buffer - start; - NS_ASSERT (written <= 0xffff); - return written; - } - } - - uint32_t n = GetUleb128Size (typeUid); - n += GetUleb128Size (item->size); - n += 2; - n += GetUleb128Size (extraItem->fragmentStart); - n += GetUleb128Size (extraItem->fragmentEnd); - n += 4; - n += 2 + 2; - ReserveCopy (n); - goto append; -} - -void -PacketHistory::ReplaceTail (PacketHistory::SmallItem *item, - PacketHistory::ExtraItem *extraItem, - uint32_t available) -{ - NS_ASSERT (m_data != 0); - if (available >= 14 && - m_data->m_count == 1) - { - uint8_t *buffer = &m_data->m_data[m_tail]; - uint8_t *end = buffer + available; - - Append16 (item->next, buffer); - buffer += 2; - Append16 (item->prev, buffer); - buffer += 2; - if (TryToAppend (item->typeUid, &buffer, end) && - TryToAppend (item->size, &buffer, end) && - TryToAppend16 (item->chunkUid, &buffer, end) && - TryToAppend (extraItem->fragmentStart, &buffer, end) && - TryToAppend (extraItem->fragmentEnd, &buffer, end) && - TryToAppend32 (extraItem->packetUid, &buffer, end)) - { - m_used = buffer - &m_data->m_data[0]; - m_data->m_dirtyEnd = m_used; - 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); - uint16_t written = h.AddBig (0xffff, h.m_tail, - &tmpItem, &tmpExtraItem); - h.UpdateTail (written); - } - // append new tail. - uint16_t written = h.AddBig (0xffff, h.m_tail, item, extraItem); - h.UpdateTail (written); - - *this = h; -} - -uint32_t -PacketHistory::ReadItems (uint16_t current, - struct PacketHistory::SmallItem *item, - struct PacketHistory::ExtraItem *extraItem) const -{ - const uint8_t *buffer = &m_data->m_data[current]; - 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 = 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 = buffer[0]; - extraItem->packetUid |= buffer[1] << 8; - extraItem->packetUid |= buffer[2] << 16; - extraItem->packetUid |= buffer[3] << 24; - buffer += 4; - } - else - { - extraItem->fragmentStart = 0; - extraItem->fragmentEnd = item->size; - extraItem->packetUid = m_packetUid; - } - NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); - return buffer - &m_data->m_data[current]; -} - -struct PacketHistory::Data * -PacketHistory::Create (uint32_t size) -{ - NS_DEBUG ("create size="< m_tail) - { - m_used = m_head; - } -} -void -PacketHistory::DoAddTrailer (uint32_t uid, uint32_t size) -{ - if (!m_enable) - { - return; - } - 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); - UpdateTail (written); -} -void -PacketHistory::DoRemoveTrailer (uint32_t uid, uint32_t size) -{ - if (!m_enable) - { - return; - } - struct PacketHistory::SmallItem item; - 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 && - (extraItem.fragmentStart != 0 || - extraItem.fragmentEnd != size)) - { - NS_FATAL_ERROR ("Removing incomplete trailer."); - } - m_tail = item.prev; - if (m_tail > m_head) - { - m_used = m_tail; - } -} -void -PacketHistory::AddAtEnd (PacketHistory const&o) -{ - if (!m_enable) - { - return; - } - if (m_tail == 0xffff) - { - *this = o; - return; - } - NS_ASSERT (m_head != 0xffff && m_tail != 0xffff); - - uint16_t lastTail; - lastTail = m_tail; - struct PacketHistory::SmallItem lastItem; - PacketHistory::ExtraItem 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 - m_tail; - } - - 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) - { - // replace previous tail. - lastExtraItem.fragmentEnd = extraItem.fragmentEnd; - NS_ASSERT (m_tail == lastTail); - ReplaceTail (&lastItem, &lastExtraItem, lastTailSize); - } - else - { - // append the extra items. - uint16_t written = AddBig (0xffff, m_tail, &item, &extraItem); - UpdateTail (written); - } - if (current == o.m_tail) - { - break; - } - current = item.next; - } -} -void -PacketHistory::AddPaddingAtEnd (uint32_t end) -{ - if (!m_enable) - { - return; - } -} -void -PacketHistory::RemoveAtStart (uint32_t start) -{ - if (!m_enable) - { - return; - } - NS_ASSERT (m_data != 0); - uint32_t leftToRemove = start; - uint16_t current = m_head; - 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_head = item.next; - leftToRemove -= itemRealSize; - } - else - { - // fragment the list item. - PacketHistory fragment (m_packetUid, 0); - extraItem.fragmentStart += leftToRemove; - leftToRemove = 0; - 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 (0xffff, fragment.m_tail, - &item, &extraItem); - fragment.UpdateTail (written); - if (current == m_tail) - { - break; - } - current = item.next; - } - *this = fragment; - } - NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart && - extraItem.fragmentStart <= extraItem.fragmentEnd); - if (current == m_tail) - { - break; - } - current = item.next; - } - NS_ASSERT (leftToRemove == 0); -} -void -PacketHistory::RemoveAtEnd (uint32_t end) -{ - if (!m_enable) - { - return; - } - NS_ASSERT (m_data != 0); - - 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); - NS_ASSERT (extraItem.fragmentEnd > leftToRemove); - extraItem.fragmentEnd -= leftToRemove; - leftToRemove = 0; - 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 (fragment.m_head, 0xffff, - &item, &extraItem); - fragment.UpdateHead (written); - 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 -PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const -{ - Print (os, buffer, PacketPrinter::GetDefault ()); -} - -uint32_t -PacketHistory::DoPrint (struct PacketHistory::SmallItem *item, uint32_t current, - Buffer data, uint32_t offset, const PacketPrinter &printer, - std::ostream &os) const -{ - PacketHistory::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, - extraItem.fragmentEnd); - } - else if (extraItem.fragmentStart != 0 || - extraItem.fragmentEnd != item->size) - { - 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, 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); - } - else - { - NS_ASSERT (false); - } - return extraItem.fragmentEnd - extraItem.fragmentStart; -} - -uint32_t -PacketHistory::GetTotalSize (void) const -{ - uint32_t totalSize = 0; - uint16_t current = m_head; - uint16_t tail = m_tail; - while (current != 0xffff) - { - struct PacketHistory::SmallItem item; - PacketHistory::ExtraItem extraItem; - ReadItems (current, &item, &extraItem); - totalSize += extraItem.fragmentEnd - extraItem.fragmentStart; - if (current == tail) - { - break; - } - current = item.next; - } - return totalSize; -} - -void -PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printer) const -{ - if (!m_enable) - { - return; - } - NS_ASSERT (m_data != 0); - NS_ASSERT (GetTotalSize () == data.GetSize ()); - if (printer.m_forward) - { - uint32_t tail = m_tail; - uint32_t head = m_head; - uint32_t current = head; - uint32_t offset = 0; - while (current != 0xffff) - { - struct PacketHistory::SmallItem item; - uint32_t realSize = DoPrint (&item, current, data, offset, printer, os); - offset += realSize; - if (current == tail) - { - break; - } - current = item.next; - } - } - else - { - uint32_t head = m_head; - uint32_t tail = m_tail; - uint32_t current = head; - uint32_t offset = 0; - while (current != 0xffff) - { - struct PacketHistory::SmallItem item; - uint32_t realSize = DoPrint (&item, current, data, offset, printer, os); - offset -= realSize; - if (current == tail) - { - break; - } - current = item.prev; - } - } -} - - - -}; // namespace ns3 - -#include -#include -#include -#include "ns3/test.h" -#include "header.h" -#include "trailer.h" -#include "packet.h" - -namespace ns3 { - -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 -{ - std::ostringstream oss; - oss << N; - return oss.str (); -} - -template -void -HistoryHeader::PrintTo (std::ostream &os) const -{ - NS_ASSERT (false); -} -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) -{ - m_ok = true; - for (int i = 0; i < N; i++) - { - if (start.ReadU8 () != N) - { - m_ok = false; - } - } - return N; -} - -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 -{ - std::ostringstream oss; - oss << N; - return oss.str (); -} -template -void -HistoryTrailer::PrintTo (std::ostream &os) const -{ - NS_ASSERT (false); -} -template -uint32_t -HistoryTrailer::GetSerializedSize (void) const -{ - return N; -} -template -void -HistoryTrailer::SerializeTo (Buffer::Iterator start) const -{ - start.Prev (N); - start.WriteU8 (N, N); -} -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) - { - m_ok = false; - } - } - 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); -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.AddHeaderPrinter (MakeCallback (&PacketHistoryTest::PrintHeader, this), - MakeCallback (&PacketHistoryTest::PrintFragment, this)); - registered = true; - } -} - -template -void -PacketHistoryTest::RegisterTrailer (void) -{ - static bool registered = false; - if (!registered) - { - m_printer.AddTrailerPrinter (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) -{ - m_prints.push_back (info.end - info.start); -} -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) -{ - m_prints.push_back (info.end - info.start); -} - - -void -PacketHistoryTest::CleanupPrints (void) -{ - m_prints.clear (); -} - -bool -PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ...) -{ - m_headerError = false; - m_trailerError = false; - va_list ap; - p.Print (std::cerr, m_printer); - va_start (ap, n); - if (m_headerError) - { - std::cout << "PacketHistory header error. file=" << file - << ", line=" << line << std::endl; - return false; - } - if (m_trailerError) - { - std::cout << "PacketHistory trailer error. file=" << file - << ", line=" << line << std::endl; - return false; - } - if (n != m_prints.size ()) - { - goto error; - } - for (std::list::iterator i = m_prints.begin (); - i != m_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 = m_prints.begin (); - i != m_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; \ - 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, ...) \ - { \ - 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, 2, 10, 100); - - p = Packet (10); - ADD_HEADER (p, 1); - ADD_HEADER (p, 2); - ADD_HEADER (p, 3); - CHECK_HISTORY (p, 4, - 3, 2, 1, 10); - ADD_HEADER (p, 5); - CHECK_HISTORY (p, 5, - 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, 3, - 2, 1, 10); - - 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, 2, - 1, 10); - - 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, 1, 10); - - 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, 1, 10); - CHECK_HISTORY (p, 4, - 3, 2, 1, 10); - ADD_HEADER (p1, 1); - ADD_HEADER (p1, 2); - CHECK_HISTORY (p1, 3, - 2, 1, 10); - CHECK_HISTORY (p, 4, - 3, 2, 1, 10); - ADD_HEADER (p, 3); - CHECK_HISTORY (p, 5, - 3, 3, 2, 1, 10); - ADD_TRAILER (p, 4); - CHECK_HISTORY (p, 6, - 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, 6, - 3, 2, 1, 10, 4, 5); - REM_TRAILER (p, 5); - CHECK_HISTORY (p, 5, - 3, 2, 1, 10, 4); - p1 = p; - REM_TRAILER (p, 4); - CHECK_HISTORY (p, 4, - 3, 2, 1, 10); - CHECK_HISTORY (p1, 5, - 3, 2, 1, 10, 4); - p1.RemoveAtStart (3); - CHECK_HISTORY (p1, 4, - 2, 1, 10, 4); - p1.RemoveAtStart (1); - CHECK_HISTORY (p1, 4, - 1, 1, 10, 4); - p1.RemoveAtStart (1); - CHECK_HISTORY (p1, 3, - 1, 10, 4); - p1.RemoveAtEnd (4); - CHECK_HISTORY (p1, 2, - 1, 10); - p1.RemoveAtStart (1); - CHECK_HISTORY (p1, 1, 10); - - 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, 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); - 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); - - Packet p2 = Packet (0); - Packet p3 = Packet (0); - - 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); - p1.AddAtEnd (p3); - 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); - - 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); - - p = Packet (0); - CHECK_HISTORY (p, 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); - - - - - return ok; -} - -static PacketHistoryTest g_packetHistoryTest; - -}//namespace ns3 diff -r 62901fdaeb68 -r 777fcfabc1c8 src/common/packet-history.h --- a/src/common/packet-history.h Thu Jun 07 12:44:44 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* -*- 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" -#include "ns3/assert.h" -#include "packet-printer.h" - -namespace ns3 { - -class Chunk; -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); - inline PacketHistory &operator = (PacketHistory const& o); - inline ~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 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 Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const; - - static void PrintStats (void); - -private: - /** - head -(next)-> tail - ^ | - \---(prev)---| - */ - struct Data { - uint16_t m_count; - uint16_t m_size; - uint16_t m_dirtyEnd; - uint8_t m_data[10]; - }; - struct SmallItem { - uint16_t next; - uint16_t prev; - uint32_t typeUid; - uint32_t size; - uint16_t chunkUid; - }; - struct ExtraItem { - uint32_t fragmentStart; - uint32_t fragmentEnd; - uint32_t packetUid; - }; - - typedef std::vector DataFreeList; - - PacketHistory (); - 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); - 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, - uint32_t available); - inline void UpdateHead (uint16_t written); - inline void UpdateTail (uint16_t written); - 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); - 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, - 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; - - - 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 Data *m_data; - uint16_t m_head; - uint16_t m_tail; - uint16_t m_used; - uint32_t m_packetUid; -}; - -}; // namespace ns3 - -namespace ns3 { - -template -void -PacketHistory::AddHeader (T const &header, uint32_t size) -{ - DoAddHeader (PacketPrinter::GetHeaderUid (), size); -} - -template -void -PacketHistory::RemoveHeader (T const &header, uint32_t size) -{ - DoRemoveHeader (PacketPrinter::GetHeaderUid (), size); -} -template -void -PacketHistory::AddTrailer (T const &trailer, uint32_t size) -{ - DoAddTrailer (PacketPrinter::GetTrailerUid (), size); -} -template -void -PacketHistory::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)), - 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); - } -} -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) -{ - NS_ASSERT (m_data != 0); - m_data->m_count++; -} -PacketHistory & -PacketHistory::operator = (PacketHistory const& o) -{ - if (m_data == o.m_data) - { - // self assignment - return *this; - } - NS_ASSERT (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; - NS_ASSERT (m_data != 0); - m_data->m_count++; - return *this; -} -PacketHistory::~PacketHistory () -{ - NS_ASSERT (m_data != 0); - m_data->m_count--; - if (m_data->m_count == 0) - { - PacketHistory::Recycle (m_data); - } -} - -}; // namespace ns3 - - -#endif /* PACKET_HISTORY_H */ diff -r 62901fdaeb68 -r 777fcfabc1c8 src/common/packet-metadata.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/common/packet-metadata.cc Thu Jun 07 12:48:52 2007 +0200 @@ -0,0 +1,1631 @@ +/* -*- 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 +#include "ns3/assert.h" +#include "ns3/fatal-error.h" +#include "ns3/debug.h" +#include "packet-metadata.h" +#include "chunk.h" +#include "buffer.h" + +NS_DEBUG_COMPONENT_DEFINE ("PacketHistory"); + +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 g_optOne = false; + +void +PacketHistory::Enable (void) +{ + m_enable = true; +} + +void +PacketHistory::SetOptOne (bool optOne) +{ + g_optOne = optOne; +} + +void +PacketHistory::ReserveCopy (uint32_t size) +{ + struct PacketHistory::Data *newData = PacketHistory::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); + } + 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) +{ + NS_ASSERT (m_data != 0); + if (m_data->m_size >= m_used + size && + (m_head == 0xffff || + m_data->m_count == 1 || + m_data->m_dirtyEnd == m_used)) + { + /* enough room, not dirty. */ + } + else + { + /* (enough room and dirty) or (not enough room) */ + ReserveCopy (size); + } +} + +uint32_t +PacketHistory::GetUleb128Size (uint32_t value) const +{ + 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 +{ + 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 *buffer) +{ + buffer[0] = value & 0xff; + value >>= 8; + buffer[1] = value; +} +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::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; + 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; + byte = value & (~0x80); + start[1] = 0x80 | byte; + value >>= 7; + byte = value & (~0x80); + start[2] = value; + *pBuffer = start + 3; + return true; + } + 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; +} + +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) +{ + if (m_head == 0xffff) + { + NS_ASSERT (m_tail == 0xffff); + m_head = m_used; + m_tail = 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; +} + + +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) +{ + 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]; + if (end - start >= 8 && + (m_head == 0xffff || + m_data->m_count == 1 || + m_used == m_data->m_dirtyEnd)) + { + uint8_t *buffer = start; + + Append16 (item->next, buffer); + buffer += 2; + Append16 (item->prev, buffer); + buffer += 2; + if (TryToAppendFast (item->typeUid, &buffer, end) && + TryToAppendFast (item->size, &buffer, end) && + TryToAppend16 (item->chunkUid, &buffer, end)) + { + uintptr_t written = buffer - start; + NS_ASSERT (written <= 0xffff); + return written; + } + } + uint32_t n = GetUleb128Size (item->typeUid); + n += GetUleb128Size (item->size); + n += 2; + n += 2 + 2; + Reserve (n); + goto append; +} + +uint16_t +PacketHistory::AddBig (uint32_t next, uint32_t prev, + const PacketHistory::SmallItem *item, + const PacketHistory::ExtraItem *extraItem) +{ + 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]; + if (end - start >= 14 && + (m_head == 0xffff || + m_data->m_count == 1 || + m_used == m_data->m_dirtyEnd)) + { + uint8_t *buffer = start; + + Append16 (next, buffer); + buffer += 2; + Append16 (prev, buffer); + buffer += 2; + if (TryToAppend (typeUid, &buffer, end) && + TryToAppend (item->size, &buffer, end) && + TryToAppend16 (item->chunkUid, &buffer, end) && + TryToAppend (extraItem->fragmentStart, &buffer, end) && + TryToAppend (extraItem->fragmentEnd, &buffer, end) && + TryToAppend32 (extraItem->packetUid, &buffer, end)) + { + uintptr_t written = buffer - start; + NS_ASSERT (written <= 0xffff); + return written; + } + } + + uint32_t n = GetUleb128Size (typeUid); + n += GetUleb128Size (item->size); + n += 2; + n += GetUleb128Size (extraItem->fragmentStart); + n += GetUleb128Size (extraItem->fragmentEnd); + n += 4; + n += 2 + 2; + ReserveCopy (n); + goto append; +} + +void +PacketHistory::ReplaceTail (PacketHistory::SmallItem *item, + PacketHistory::ExtraItem *extraItem, + uint32_t available) +{ + NS_ASSERT (m_data != 0); + if (available >= 14 && + m_data->m_count == 1) + { + uint8_t *buffer = &m_data->m_data[m_tail]; + uint8_t *end = buffer + available; + + Append16 (item->next, buffer); + buffer += 2; + Append16 (item->prev, buffer); + buffer += 2; + if (TryToAppend (item->typeUid, &buffer, end) && + TryToAppend (item->size, &buffer, end) && + TryToAppend16 (item->chunkUid, &buffer, end) && + TryToAppend (extraItem->fragmentStart, &buffer, end) && + TryToAppend (extraItem->fragmentEnd, &buffer, end) && + TryToAppend32 (extraItem->packetUid, &buffer, end)) + { + m_used = buffer - &m_data->m_data[0]; + m_data->m_dirtyEnd = m_used; + 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); + uint16_t written = h.AddBig (0xffff, h.m_tail, + &tmpItem, &tmpExtraItem); + h.UpdateTail (written); + } + // append new tail. + uint16_t written = h.AddBig (0xffff, h.m_tail, item, extraItem); + h.UpdateTail (written); + + *this = h; +} + +uint32_t +PacketHistory::ReadItems (uint16_t current, + struct PacketHistory::SmallItem *item, + struct PacketHistory::ExtraItem *extraItem) const +{ + const uint8_t *buffer = &m_data->m_data[current]; + 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 = 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 = buffer[0]; + extraItem->packetUid |= buffer[1] << 8; + extraItem->packetUid |= buffer[2] << 16; + extraItem->packetUid |= buffer[3] << 24; + buffer += 4; + } + else + { + extraItem->fragmentStart = 0; + extraItem->fragmentEnd = item->size; + extraItem->packetUid = m_packetUid; + } + NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]); + return buffer - &m_data->m_data[current]; +} + +struct PacketHistory::Data * +PacketHistory::Create (uint32_t size) +{ + NS_DEBUG ("create size="< m_tail) + { + m_used = m_head; + } +} +void +PacketHistory::DoAddTrailer (uint32_t uid, uint32_t size) +{ + if (!m_enable) + { + return; + } + 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); + UpdateTail (written); +} +void +PacketHistory::DoRemoveTrailer (uint32_t uid, uint32_t size) +{ + if (!m_enable) + { + return; + } + struct PacketHistory::SmallItem item; + 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 && + (extraItem.fragmentStart != 0 || + extraItem.fragmentEnd != size)) + { + NS_FATAL_ERROR ("Removing incomplete trailer."); + } + m_tail = item.prev; + if (m_tail > m_head) + { + m_used = m_tail; + } +} +void +PacketHistory::AddAtEnd (PacketHistory const&o) +{ + if (!m_enable) + { + return; + } + if (m_tail == 0xffff) + { + *this = o; + return; + } + NS_ASSERT (m_head != 0xffff && m_tail != 0xffff); + + uint16_t lastTail; + lastTail = m_tail; + struct PacketHistory::SmallItem lastItem; + PacketHistory::ExtraItem 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 - m_tail; + } + + 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) + { + // replace previous tail. + lastExtraItem.fragmentEnd = extraItem.fragmentEnd; + NS_ASSERT (m_tail == lastTail); + ReplaceTail (&lastItem, &lastExtraItem, lastTailSize); + } + else + { + // append the extra items. + uint16_t written = AddBig (0xffff, m_tail, &item, &extraItem); + UpdateTail (written); + } + if (current == o.m_tail) + { + break; + } + current = item.next; + } +} +void +PacketHistory::AddPaddingAtEnd (uint32_t end) +{ + if (!m_enable) + { + return; + } +} +void +PacketHistory::RemoveAtStart (uint32_t start) +{ + if (!m_enable) + { + return; + } + NS_ASSERT (m_data != 0); + uint32_t leftToRemove = start; + uint16_t current = m_head; + 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_head = item.next; + leftToRemove -= itemRealSize; + } + else + { + // fragment the list item. + PacketHistory fragment (m_packetUid, 0); + extraItem.fragmentStart += leftToRemove; + leftToRemove = 0; + 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 (0xffff, fragment.m_tail, + &item, &extraItem); + fragment.UpdateTail (written); + if (current == m_tail) + { + break; + } + current = item.next; + } + *this = fragment; + } + NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart && + extraItem.fragmentStart <= extraItem.fragmentEnd); + if (current == m_tail) + { + break; + } + current = item.next; + } + NS_ASSERT (leftToRemove == 0); +} +void +PacketHistory::RemoveAtEnd (uint32_t end) +{ + if (!m_enable) + { + return; + } + NS_ASSERT (m_data != 0); + + 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); + NS_ASSERT (extraItem.fragmentEnd > leftToRemove); + extraItem.fragmentEnd -= leftToRemove; + leftToRemove = 0; + 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 (fragment.m_head, 0xffff, + &item, &extraItem); + fragment.UpdateHead (written); + 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 +PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const +{ + Print (os, buffer, PacketPrinter::GetDefault ()); +} + +uint32_t +PacketHistory::DoPrint (struct PacketHistory::SmallItem *item, uint32_t current, + Buffer data, uint32_t offset, const PacketPrinter &printer, + std::ostream &os) const +{ + PacketHistory::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, + extraItem.fragmentEnd); + } + else if (extraItem.fragmentStart != 0 || + extraItem.fragmentEnd != item->size) + { + 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, 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); + } + else + { + NS_ASSERT (false); + } + return extraItem.fragmentEnd - extraItem.fragmentStart; +} + +uint32_t +PacketHistory::GetTotalSize (void) const +{ + uint32_t totalSize = 0; + uint16_t current = m_head; + uint16_t tail = m_tail; + while (current != 0xffff) + { + struct PacketHistory::SmallItem item; + PacketHistory::ExtraItem extraItem; + ReadItems (current, &item, &extraItem); + totalSize += extraItem.fragmentEnd - extraItem.fragmentStart; + if (current == tail) + { + break; + } + current = item.next; + } + return totalSize; +} + +void +PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printer) const +{ + if (!m_enable) + { + return; + } + NS_ASSERT (m_data != 0); + NS_ASSERT (GetTotalSize () == data.GetSize ()); + if (printer.m_forward) + { + uint32_t tail = m_tail; + uint32_t head = m_head; + uint32_t current = head; + uint32_t offset = 0; + while (current != 0xffff) + { + struct PacketHistory::SmallItem item; + uint32_t realSize = DoPrint (&item, current, data, offset, printer, os); + offset += realSize; + if (current == tail) + { + break; + } + current = item.next; + } + } + else + { + uint32_t head = m_head; + uint32_t tail = m_tail; + uint32_t current = head; + uint32_t offset = 0; + while (current != 0xffff) + { + struct PacketHistory::SmallItem item; + uint32_t realSize = DoPrint (&item, current, data, offset, printer, os); + offset -= realSize; + if (current == tail) + { + break; + } + current = item.prev; + } + } +} + + + +}; // namespace ns3 + +#include +#include +#include +#include "ns3/test.h" +#include "header.h" +#include "trailer.h" +#include "packet.h" + +namespace ns3 { + +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 +{ + std::ostringstream oss; + oss << N; + return oss.str (); +} + +template +void +HistoryHeader::PrintTo (std::ostream &os) const +{ + NS_ASSERT (false); +} +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) +{ + m_ok = true; + for (int i = 0; i < N; i++) + { + if (start.ReadU8 () != N) + { + m_ok = false; + } + } + return N; +} + +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 +{ + std::ostringstream oss; + oss << N; + return oss.str (); +} +template +void +HistoryTrailer::PrintTo (std::ostream &os) const +{ + NS_ASSERT (false); +} +template +uint32_t +HistoryTrailer::GetSerializedSize (void) const +{ + return N; +} +template +void +HistoryTrailer::SerializeTo (Buffer::Iterator start) const +{ + start.Prev (N); + start.WriteU8 (N, N); +} +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) + { + m_ok = false; + } + } + 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); +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.AddHeaderPrinter (MakeCallback (&PacketHistoryTest::PrintHeader, this), + MakeCallback (&PacketHistoryTest::PrintFragment, this)); + registered = true; + } +} + +template +void +PacketHistoryTest::RegisterTrailer (void) +{ + static bool registered = false; + if (!registered) + { + m_printer.AddTrailerPrinter (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) +{ + m_prints.push_back (info.end - info.start); +} +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) +{ + m_prints.push_back (info.end - info.start); +} + + +void +PacketHistoryTest::CleanupPrints (void) +{ + m_prints.clear (); +} + +bool +PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ...) +{ + m_headerError = false; + m_trailerError = false; + va_list ap; + p.Print (std::cerr, m_printer); + va_start (ap, n); + if (m_headerError) + { + std::cout << "PacketHistory header error. file=" << file + << ", line=" << line << std::endl; + return false; + } + if (m_trailerError) + { + std::cout << "PacketHistory trailer error. file=" << file + << ", line=" << line << std::endl; + return false; + } + if (n != m_prints.size ()) + { + goto error; + } + for (std::list::iterator i = m_prints.begin (); + i != m_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 = m_prints.begin (); + i != m_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; \ + 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, ...) \ + { \ + 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, 2, 10, 100); + + p = Packet (10); + ADD_HEADER (p, 1); + ADD_HEADER (p, 2); + ADD_HEADER (p, 3); + CHECK_HISTORY (p, 4, + 3, 2, 1, 10); + ADD_HEADER (p, 5); + CHECK_HISTORY (p, 5, + 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, 3, + 2, 1, 10); + + 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, 2, + 1, 10); + + 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, 1, 10); + + 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, 1, 10); + CHECK_HISTORY (p, 4, + 3, 2, 1, 10); + ADD_HEADER (p1, 1); + ADD_HEADER (p1, 2); + CHECK_HISTORY (p1, 3, + 2, 1, 10); + CHECK_HISTORY (p, 4, + 3, 2, 1, 10); + ADD_HEADER (p, 3); + CHECK_HISTORY (p, 5, + 3, 3, 2, 1, 10); + ADD_TRAILER (p, 4); + CHECK_HISTORY (p, 6, + 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, 6, + 3, 2, 1, 10, 4, 5); + REM_TRAILER (p, 5); + CHECK_HISTORY (p, 5, + 3, 2, 1, 10, 4); + p1 = p; + REM_TRAILER (p, 4); + CHECK_HISTORY (p, 4, + 3, 2, 1, 10); + CHECK_HISTORY (p1, 5, + 3, 2, 1, 10, 4); + p1.RemoveAtStart (3); + CHECK_HISTORY (p1, 4, + 2, 1, 10, 4); + p1.RemoveAtStart (1); + CHECK_HISTORY (p1, 4, + 1, 1, 10, 4); + p1.RemoveAtStart (1); + CHECK_HISTORY (p1, 3, + 1, 10, 4); + p1.RemoveAtEnd (4); + CHECK_HISTORY (p1, 2, + 1, 10); + p1.RemoveAtStart (1); + CHECK_HISTORY (p1, 1, 10); + + 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, 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); + 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); + + Packet p2 = Packet (0); + Packet p3 = Packet (0); + + 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); + p1.AddAtEnd (p3); + 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); + + 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); + + p = Packet (0); + CHECK_HISTORY (p, 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); + + + + + return ok; +} + +static PacketHistoryTest g_packetHistoryTest; + +}//namespace ns3 diff -r 62901fdaeb68 -r 777fcfabc1c8 src/common/packet-metadata.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/common/packet-metadata.h Thu Jun 07 12:48:52 2007 +0200 @@ -0,0 +1,235 @@ +/* -*- 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" +#include "ns3/assert.h" +#include "packet-printer.h" + +namespace ns3 { + +class Chunk; +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); + inline PacketHistory &operator = (PacketHistory const& o); + inline ~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 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 Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const; + + static void PrintStats (void); + +private: + /** + head -(next)-> tail + ^ | + \---(prev)---| + */ + struct Data { + uint16_t m_count; + uint16_t m_size; + uint16_t m_dirtyEnd; + uint8_t m_data[10]; + }; + struct SmallItem { + uint16_t next; + uint16_t prev; + uint32_t typeUid; + uint32_t size; + uint16_t chunkUid; + }; + struct ExtraItem { + uint32_t fragmentStart; + uint32_t fragmentEnd; + uint32_t packetUid; + }; + + typedef std::vector DataFreeList; + + PacketHistory (); + 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); + 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, + uint32_t available); + inline void UpdateHead (uint16_t written); + inline void UpdateTail (uint16_t written); + 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); + 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, + 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; + + + 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 Data *m_data; + uint16_t m_head; + uint16_t m_tail; + uint16_t m_used; + uint32_t m_packetUid; +}; + +}; // namespace ns3 + +namespace ns3 { + +template +void +PacketHistory::AddHeader (T const &header, uint32_t size) +{ + DoAddHeader (PacketPrinter::GetHeaderUid (), size); +} + +template +void +PacketHistory::RemoveHeader (T const &header, uint32_t size) +{ + DoRemoveHeader (PacketPrinter::GetHeaderUid (), size); +} +template +void +PacketHistory::AddTrailer (T const &trailer, uint32_t size) +{ + DoAddTrailer (PacketPrinter::GetTrailerUid (), size); +} +template +void +PacketHistory::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)), + 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); + } +} +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) +{ + NS_ASSERT (m_data != 0); + m_data->m_count++; +} +PacketHistory & +PacketHistory::operator = (PacketHistory const& o) +{ + if (m_data == o.m_data) + { + // self assignment + return *this; + } + NS_ASSERT (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; + NS_ASSERT (m_data != 0); + m_data->m_count++; + return *this; +} +PacketHistory::~PacketHistory () +{ + NS_ASSERT (m_data != 0); + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } +} + +}; // namespace ns3 + + +#endif /* PACKET_HISTORY_H */ diff -r 62901fdaeb68 -r 777fcfabc1c8 src/common/packet.h --- a/src/common/packet.h Thu Jun 07 12:44:44 2007 +0200 +++ b/src/common/packet.h Thu Jun 07 12:48:52 2007 +0200 @@ -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 -r 62901fdaeb68 -r 777fcfabc1c8 utils/bench-packets.cc --- a/utils/bench-packets.cc Thu Jun 07 12:44:44 2007 +0200 +++ b/utils/bench-packets.cc Thu Jun 07 12:48:52 2007 +0200 @@ -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