View | Details | Raw Unified | Return to bug 2221
Collapse All | Expand All

(-)a/src/network/model/packet-tag-list.cc (-13 / +24 lines)
 Lines 34-39    Link Here 
34
34
35
NS_LOG_COMPONENT_DEFINE ("PacketTagList");
35
NS_LOG_COMPONENT_DEFINE ("PacketTagList");
36
36
37
PacketTagList::TagData::TagData (size_t dataSize)
38
  : size (dataSize)
39
{
40
  NS_ASSERT_MSG (dataSize < std::numeric_limits<decltype(size)>::max (),
41
                 "Requested TagData size " << dataSize
42
                 << " exceeds maximum "
43
                 << std::numeric_limits<decltype(size)>::max () );
44
  data = (uint8_t *) std::malloc (size);
45
}
46
47
PacketTagList::TagData::~TagData (void)
48
{
49
  free (data);
50
}
51
37
bool
52
bool
38
PacketTagList::COWTraverse (Tag & tag, PacketTagList::COWWriter Writer)
53
PacketTagList::COWTraverse (Tag & tag, PacketTagList::COWWriter Writer)
39
{
54
{
 Lines 133-142    Link Here 
133
      NS_ASSERT (cur != 0);
148
      NS_ASSERT (cur != 0);
134
      NS_ASSERT (cur->count > 1);
149
      NS_ASSERT (cur->count > 1);
135
      cur->count--;                       // unmerge cur
150
      cur->count--;                       // unmerge cur
136
      struct TagData * copy = new struct TagData ();
151
      struct TagData * copy = new struct TagData (cur->size);
137
      copy->tid = cur->tid;
152
      copy->tid = cur->tid;
138
      copy->count = 1;
153
      copy->count = 1;
139
      memcpy (copy->data, cur->data, TagData::MAX_SIZE);
154
      memcpy (copy->data, cur->data, copy->size);
140
      copy->next = cur->next;             // merge into tail
155
      copy->next = cur->next;             // merge into tail
141
      copy->next->count++;                // mark new merge
156
      copy->next->count++;                // mark new merge
142
      *prevNext = copy;                   // point prior list at copy
157
      *prevNext = copy;                   // point prior list at copy
 Lines 170-177    Link Here 
170
185
171
  // found tid
186
  // found tid
172
  bool found = true;
187
  bool found = true;
173
  tag.Deserialize (TagBuffer (cur->data,
188
  tag.Deserialize (TagBuffer (cur->data, cur->data + cur->size));
174
                              cur->data + TagData::MAX_SIZE));
175
  *prevNext = cur->next;            // link around cur
189
  *prevNext = cur->next;            // link around cur
176
190
177
  if (preMerge)
191
  if (preMerge)
 Lines 217-235    Link Here 
217
  if (preMerge)
231
  if (preMerge)
218
    {
232
    {
219
      // found tid before first merge, so just rewrite
233
      // found tid before first merge, so just rewrite
220
      tag.Serialize (TagBuffer (cur->data,
234
      tag.Serialize (TagBuffer (cur->data, cur->data + cur->size));
221
                                cur->data + tag.GetSerializedSize ()));
222
    }
235
    }
223
  else
236
  else
224
    {
237
    {
225
      // cur is always a merge at this point
238
      // cur is always a merge at this point
226
      // need to copy, replace, and link past cur
239
      // need to copy, replace, and link past cur
227
      cur->count--;                     // unmerge cur
240
      cur->count--;                     // unmerge cur
228
      struct TagData * copy = new struct TagData ();
241
      struct TagData * copy = new struct TagData (tag.GetSerializedSize ());
229
      copy->tid = tag.GetInstanceTypeId ();
242
      copy->tid = tag.GetInstanceTypeId ();
230
      copy->count = 1;
243
      copy->count = 1;
231
      tag.Serialize (TagBuffer (copy->data,
244
      tag.Serialize (TagBuffer (copy->data, copy->data + copy->size));
232
                                copy->data + tag.GetSerializedSize ()));
233
      copy->next = cur->next;           // merge into tail
245
      copy->next = cur->next;           // merge into tail
234
      if (copy->next != 0)
246
      if (copy->next != 0)
235
        {
247
        {
 Lines 249-261    Link Here 
249
    {
261
    {
250
      NS_ASSERT_MSG (cur->tid != tag.GetInstanceTypeId (), "Error: cannot add the same kind of tag twice.");
262
      NS_ASSERT_MSG (cur->tid != tag.GetInstanceTypeId (), "Error: cannot add the same kind of tag twice.");
251
    }
263
    }
252
  struct TagData * head = new struct TagData ();
264
  struct TagData * head = new struct TagData (tag.GetSerializedSize ());
253
  head->count = 1;
265
  head->count = 1;
254
  head->next = 0;
266
  head->next = 0;
255
  head->tid = tag.GetInstanceTypeId ();
267
  head->tid = tag.GetInstanceTypeId ();
256
  head->next = m_next;
268
  head->next = m_next;
257
  NS_ASSERT (tag.GetSerializedSize () <= TagData::MAX_SIZE);
269
  tag.Serialize (TagBuffer (head->data, head->data + head->size));
258
  tag.Serialize (TagBuffer (head->data, head->data + tag.GetSerializedSize ()));
259
270
260
  const_cast<PacketTagList *> (this)->m_next = head;
271
  const_cast<PacketTagList *> (this)->m_next = head;
261
}
272
}
 Lines 270-276    Link Here 
270
      if (cur->tid == tid) 
281
      if (cur->tid == tid) 
271
        {
282
        {
272
          /* found tag */
283
          /* found tag */
273
          tag.Deserialize (TagBuffer (cur->data, cur->data + TagData::MAX_SIZE));
284
          tag.Deserialize (TagBuffer (cur->data, cur->data + cur->size));
274
          return true;
285
          return true;
275
        }
286
        }
276
    }
287
    }
(-)a/src/network/model/packet-tag-list.h (-30 / +16 lines)
 Lines 134-170    Link Here 
134
   *
134
   *
135
   * See PacketTagList for a discussion of the data structure.
135
   * See PacketTagList for a discussion of the data structure.
136
   *
136
   *
137
   * See TagData::TagData_e for a discussion of the size limit on
137
   * \internal
138
   * tag serialization.
138
   * Unfortunately this has to be public, because
139
   * PacketTagIterator::Item::GetTag() needs the data and size values.
140
   * The Item nested class can't be forward declared, so friending isn't
141
   * possible.
139
   */
142
   */
140
  struct TagData
143
  struct TagData
141
  {
144
  {
142
    /**
145
    TagData (size_t dataSize);  /**< Construct with dataSize bytes */
143
     * \brief Packet Tag maximum size
146
    ~TagData (void);            /**< Destructor */
144
     *
147
    
145
     * The maximum size (in bytes) of a Tag is stored
148
    struct TagData * next;      /**< Pointer to next in list */
146
     * in this constant.
149
    uint32_t count;             /**< Number of incoming links */
147
     *
150
    TypeId tid;                 /**< Type of the tag serialized into #data */
148
     * \internal
151
    uint32_t size;              /**< Size of the \c data buffer */
149
     * Ideally, TagData would be 32 bytes in size, so they require
152
    uint8_t * data;             /**< Serialization buffer */
150
     * no padding on 64-bit architectures.  (The architecture
151
     * affects the size because of the \c #next pointer.)
152
     * This would leave 18 bytes for \c #data.  However,
153
     * ns3:Ipv6PacketInfoTag needs 19 bytes!  The current
154
     * implementation allows 20 bytes, which gives TagData
155
     * a size of 30 bytes on 32-byte machines (which gets
156
     * padded with 2 bytes), and 34 bytes on 64-bit machines, which
157
     * gets padded to 40 bytes.
158
     */
159
    enum TagData_e
160
    {
161
      MAX_SIZE = 21           /**< Size of serialization buffer #data */
162
  };
163
164
    uint8_t data[MAX_SIZE];   /**< Serialization buffer */
165
    struct TagData * next;   /**< Pointer to next in list */
166
    TypeId tid;               /**< Type of the tag serialized into #data */
167
    uint32_t count;           /**< Number of incoming links */
168
  };  /* struct TagData */
153
  };  /* struct TagData */
169
154
170
  /**
155
  /**
 Lines 272-278    Link Here 
272
   *          pointing to \pname{cur}.
257
   *          pointing to \pname{cur}.
273
   * \returns True, since tag will definitely be removed.
258
   * \returns True, since tag will definitely be removed.
274
   */
259
   */
275
  bool RemoveWriter  (Tag       & tag, bool         preMerge,
260
  bool RemoveWriter  (Tag & tag, bool preMerge,
276
                      struct TagData * cur, struct TagData ** prevNext);
261
                      struct TagData * cur, struct TagData ** prevNext);
277
  /**
262
  /**
278
   * Copy-on-write implementing Replace
263
   * Copy-on-write implementing Replace
 Lines 285-291    Link Here 
285
   *          pointing to \pname{cur}.
270
   *          pointing to \pname{cur}.
286
   * \returns True, since tag value will definitely be replaced.
271
   * \returns True, since tag value will definitely be replaced.
287
   */
272
   */
288
  bool ReplaceWriter (Tag & tag, bool preMerge, struct TagData * cur, struct TagData ** prevNext);
273
  bool ReplaceWriter (Tag & tag, bool preMerge,
274
                      struct TagData * cur, struct TagData ** prevNext);
289
275
290
  /**
276
  /**
291
   * Pointer to first \ref TagData on the list
277
   * Pointer to first \ref TagData on the list
(-)a/src/network/model/packet.cc (-2 / +1 lines)
 Lines 113-120    Link Here 
113
{
113
{
114
  NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
114
  NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
115
  tag.Deserialize (TagBuffer ((uint8_t*)m_data->data,
115
  tag.Deserialize (TagBuffer ((uint8_t*)m_data->data,
116
                              (uint8_t*)m_data->data
116
                              (uint8_t*)m_data->data + m_data->size));
117
                              + PacketTagList::TagData::MAX_SIZE));
118
}
117
}
119
118
120
119
(-)a/src/network/utils/packet-socket.cc (-3 lines)
 Lines 643-649    Link Here 
643
DeviceNameTag::GetSerializedSize (void) const
643
DeviceNameTag::GetSerializedSize (void) const
644
{
644
{
645
  uint32_t s = 1 + m_deviceName.size();  // +1 for name length field
645
  uint32_t s = 1 + m_deviceName.size();  // +1 for name length field
646
  s = std::min (s, (uint32_t)PacketTagList::TagData::MAX_SIZE);
647
  return s;
646
  return s;
648
}
647
}
649
void
648
void
 Lines 652-659    Link Here 
652
  const char *n = m_deviceName.c_str();
651
  const char *n = m_deviceName.c_str();
653
  uint8_t l = (uint8_t) m_deviceName.size ();
652
  uint8_t l = (uint8_t) m_deviceName.size ();
654
653
655
  l = std::min ((uint32_t)l, (uint32_t)PacketTagList::TagData::MAX_SIZE - 1);
656
657
  i.WriteU8 (l);
654
  i.WriteU8 (l);
658
  i.Write ( (uint8_t*) n , (uint32_t) l);
655
  i.Write ( (uint8_t*) n , (uint32_t) l);
659
}
656
}

Return to bug 2221