IBR-DTNSuite  0.10
MutualSerializer.cpp
Go to the documentation of this file.
1 /*
2  * MutualSerializer.cpp
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #include "ibrdtn/config.h"
24 #include "ibrdtn/data/Bundle.h"
25 #include "ibrdtn/data/Block.h"
26 #include "ibrdtn/data/EID.h"
28 #include <ibrcommon/Logger.h>
29 
30 #include <arpa/inet.h>
31 
32 #ifdef __DEVELOPMENT_ASSERTIONS__
33 #include <cassert>
34 #endif
35 
36 #ifdef HAVE_GLIB
37 #include <glib.h>
38 #else
39 // needed for Debian Lenny whichs older clibrary does not provide htobe64(x)
40 #include <endian.h>
41 #if __BYTE_ORDER == __LITTLE_ENDIAN
42 #ifdef ANDROID
43 #include <byteswap.h>
44 #define GUINT64_TO_BE(x) bswap_64(x)
45 #else
46 #include <bits/byteswap.h>
47 #define GUINT64_TO_BE(x) __bswap_64(x)
48 #endif
49 #else
50 #define GUINT64_TO_BE(x) (x)
51 #endif
52 #endif
53 
54 namespace dtn
55 {
56  namespace security
57  {
58  MutualSerializer::MutualSerializer(std::ostream& stream, const dtn::data::Block *ignore)
59  : dtn::data::DefaultSerializer(stream), _ignore(ignore), _ignore_previous_bundles(ignore != NULL)
60  {
61  }
62 
64  {
65  }
66 
68  {
69  // we want to ignore all block before "ignore"
70  if (_ignore != NULL) _ignore_previous_bundles = true;
71 
72  // write unpacked primary block
73  // bundle version
74  _stream << dtn::data::BUNDLE_VERSION;
75 
76  // processing flags
77  (*this) << (obj.procflags & 0x0000000007C1BE);
78 
79  // length of header
80  (*this) << (uint32_t)getLength(obj);
81 
82  // dest, source, report to id
83  (*this) << obj.destination;
84  (*this) << obj.source;
85  (*this) << obj.reportto;
86 
87  // timestamp
88  (*this) << obj.timestamp;
89  (*this) << obj.sequencenumber;
90 
91  // lifetime
92  (*this) << obj.lifetime;
93 
94  return *this;
95  }
96 
98  {
99  // do we ignore the current block?
100  if (_ignore_previous_bundles && (&obj != _ignore))
101  {
102  return *this;
103  }
104  else
105  {
106  // process all following bundles
107  _ignore_previous_bundles = false;
108  }
109 
110  // only take payload related blocks
114  {
115  return *this;
116  }
117 
118  _stream << obj.getType();
119  (*this) << (obj.getProcessingFlags() & 0x0000000000000077);
120 
121  const dtn::data::Block::eid_list &eids = obj.getEIDList();
122 
123 #ifdef __DEVELOPMENT_ASSERTIONS__
124  // test: BLOCK_CONTAINS_EIDS => (_eids.size() > 0)
125  assert(!obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS) || (eids.size() > 0));
126 #endif
127 
129  for (dtn::data::Block::eid_list::const_iterator it = eids.begin(); it != eids.end(); ++it)
130  (*this) << (*it);
131 
132  try {
133  const dtn::security::SecurityBlock &sb = dynamic_cast<const dtn::security::SecurityBlock&>(obj);
134 
136  {
137  // write size of the payload in the block
138  (*this) << dtn::data::Number(sb.getLength_mutable());
139 
141  }
142  } catch (const std::bad_cast&) {
143  // write size of the payload in the block
144  (*this) << dtn::data::Number(obj.getLength());
145 
146  // write the payload of the block
147  dtn::data::Length slength = 0;
148  obj.serialize(_stream, slength);
149  };
150 
151  return (*this);
152  }
153 
155  {
156 #ifdef __DEVELOPMENT_ASSERTIONS__
157  assert(false);
158 #endif
159  return 0;
160  }
161 
163  {
164  // predict the block length
165  // length in bytes
166  // starting with the fields after the length field
167 
168  // dest id length
169  uint32_t length = 4;
170  // dest id
171  length += static_cast<uint32_t>(obj.destination.getString().size());
172  // source id length
173  length += 4;
174  // source id
175  length += static_cast<uint32_t>(obj.source.getString().size());
176  // report to id length
177  length += 4;
178  // report to id
179  length += static_cast<uint32_t>(obj.reportto.getString().size());
180  // creation time: 2*SDNV
181  length += static_cast<uint32_t>(2 * sdnv_size);
182  // lifetime: SDNV
183  length += static_cast<uint32_t>(sdnv_size);
184 
186 
187  return length;
188  }
189 
191  {
192  dtn::data::Length len = 0;
193 
194  len += sizeof(obj.getType());
195  // proc flags
196  len += sdnv_size;
197 
198  const dtn::data::Block::eid_list &eids = obj.getEIDList();
199 
200 #ifdef __DEVELOPMENT_ASSERTIONS__
201  // test: BLOCK_CONTAINS_EIDS => (_eids.size() > 0)
202  assert(!obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS) || (eids.size() > 0));
203 #endif
204 
206  for (dtn::data::Block::eid_list::const_iterator it = eids.begin(); it != eids.end(); ++it)
207  len += it->getString().size();
208 
209  // size-field of the size of the payload in the block
210  len += sdnv_size;
211 
212  try {
213  const dtn::security::SecurityBlock &sb = dynamic_cast<const dtn::security::SecurityBlock&>(obj);
214 
215  // add size of the payload in the block
216  len += sb.getLength_mutable();
217  } catch (const std::bad_cast&) {
218  // add size of the payload in the block
219  len += obj.getLength();
220  };
221 
222  return len;
223  }
224 
225 
227  {
228  uint32_t be = htonl(value);
229  _stream.write(reinterpret_cast<char*>(&be), sizeof(uint32_t));
230  return *this;
231  }
232 
234  {
235  uint32_t length = static_cast<uint32_t>(value.getString().length());
236  (*this) << length;
237  _stream << value.getString();
238 
239  return *this;
240  }
241 
243  {
244  // endianess muahahaha ...
245  // and now we are gcc centric, even older versions work
246  uint64_t be = GUINT64_TO_BE(value.get<uint64_t>());
247  _stream.write(reinterpret_cast<char*>(&be), sizeof(uint64_t));
248  return *this;
249  }
250 
252  {
253  (*this) << dtn::data::Number(list.getLength());
254  _stream << list.toString();
255  return *this;
256  }
257  }
258 }