IBR-DTNSuite 0.6

ibrdtn/ibrdtn/security/MutualSerializer.cpp

Go to the documentation of this file.
00001 #include "ibrdtn/security/MutualSerializer.h"
00002 #include "ibrdtn/data/Bundle.h"
00003 #include "ibrdtn/data/Block.h"
00004 #include "ibrdtn/data/EID.h"
00005 #include "ibrdtn/security/SecurityBlock.h"
00006 #include <ibrcommon/Logger.h>
00007 
00008 #include <arpa/inet.h>
00009 #include <endian.h>
00010 
00011 #ifdef __DEVELOPMENT_ASSERTIONS__
00012 #include <cassert>
00013 #endif
00014 
00015 // needed for Debian Lenny, whichs older clibrary does not provide htobe64(x)
00016 #include <bits/byteswap.h>
00017 #if __BYTE_ORDER == __LITTLE_ENDIAN
00018 #define _ibrdtn_htobe64(x)  __bswap_64(x)
00019 #else
00020 #define _ibrdtn_htobe64(x) (x)
00021 #endif
00022 
00023 namespace dtn
00024 {
00025         namespace security
00026         {
00027                 MutualSerializer::MutualSerializer(std::ostream& stream, const dtn::data::Block *ignore)
00028                  : dtn::data::DefaultSerializer(stream), _ignore(ignore), _ignore_previous_bundles(ignore != NULL)
00029                  {
00030                  }
00031 
00032                 MutualSerializer::~MutualSerializer()
00033                 {
00034                 }
00035 
00036                 dtn::data::Serializer& MutualSerializer::operator<<(const dtn::data::PrimaryBlock &obj)
00037                 {
00038                         // we want to ignore all block before "ignore"
00039                         if (_ignore != NULL) _ignore_previous_bundles = true;
00040 
00041                         // write unpacked primary block
00042                         // bundle version
00043                         _stream << dtn::data::BUNDLE_VERSION;
00044 
00045                         // processing flags
00046                         (*this) << dtn::data::SDNV(obj._procflags & 0x0000000007C1BE);
00047 
00048                         // length of header
00049                         (*this) << dtn::data::SDNV(getLength(obj));
00050 
00051                         // dest, source, report to id
00052                         (*this) << obj._destination;
00053                         (*this) << obj._source;
00054                         (*this) << obj._reportto;
00055 
00056                         // timestamp
00057                         (*this) << dtn::data::SDNV(obj._timestamp);
00058                         (*this) << dtn::data::SDNV(obj._sequencenumber);
00059 
00060                         // lifetime
00061                         (*this) << dtn::data::SDNV(obj._lifetime);
00062 
00063                         return *this;
00064                 }
00065 
00066                 dtn::data::Serializer& MutualSerializer::operator<<(const dtn::data::Block &obj)
00067                 {
00068                         // do we ignore the current block?
00069                         if (_ignore_previous_bundles && (&obj != _ignore))
00070                         {
00071                                 return *this;
00072                         }
00073                         else
00074                         {
00075                                 // process all following bundles
00076                                 _ignore_previous_bundles = false;
00077                         }
00078 
00079                         // only take payload related blocks
00080                         if (obj.getType() != dtn::data::PayloadBlock::BLOCK_TYPE
00081                                 && obj.getType() != SecurityBlock::PAYLOAD_INTEGRITY_BLOCK
00082                                 && obj.getType() != SecurityBlock::PAYLOAD_CONFIDENTIAL_BLOCK)
00083                         {
00084                                 return *this;
00085                         }
00086 
00087                         _stream << obj._blocktype;
00088                         (*this) << dtn::data::SDNV(obj._procflags & 0x0000000000000077);
00089 
00090 #ifdef __DEVELOPMENT_ASSERTIONS__
00091                         // test: BLOCK_CONTAINS_EIDS => (_eids.size() > 0)
00092                         assert(!obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00093 #endif
00094 
00095                         if (obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS))
00096                                 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00097                                         (*this) << (*it);
00098 
00099                         try {
00100                                 const dtn::security::SecurityBlock &sb = dynamic_cast<const dtn::security::SecurityBlock&>(obj);
00101                                 
00102                                 if ( (sb.getType() == SecurityBlock::PAYLOAD_INTEGRITY_BLOCK) || (sb.getType() == SecurityBlock::PAYLOAD_CONFIDENTIAL_BLOCK) )
00103                                 {
00104                                         // write size of the payload in the block
00105                                         (*this) << dtn::data::SDNV(sb.getLength_mutable());
00106 
00107                                         sb.serialize_mutable_without_security_result(*this);
00108                                 }
00109                         } catch (const std::bad_cast&) {
00110                                 // write size of the payload in the block
00111                                 (*this) << dtn::data::SDNV(obj.getLength());
00112 
00113                                 // write the payload of the block
00114                                 size_t slength = 0;
00115                                 obj.serialize(_stream, slength);
00116                         };
00117 
00118                         return (*this);
00119                 }
00120 
00121                 size_t MutualSerializer::getLength(const dtn::data::Bundle&)
00122                 {
00123 #ifdef __DEVELOPMENT_ASSERTIONS__
00124                         assert(false);
00125 #endif
00126                         return 0;
00127                 }
00128 
00129                 size_t MutualSerializer::getLength(const dtn::data::PrimaryBlock &obj) const
00130                 {
00131                         // predict the block length
00132                         // length in bytes
00133                         // starting with the fields after the length field
00134 
00135                         // dest id length
00136                         u_int32_t length = 4;
00137                         // dest id
00138                         length += obj._destination.getString().size();
00139                         // source id length
00140                         length += 4;
00141                         // source id
00142                         length += obj._source.getString().size();
00143                         // report to id length
00144                         length += 4;
00145                         // report to id
00146                         length += obj._reportto.getString().size();
00147                         // creation time: 2*SDNV
00148                         length += 2*sdnv_size;
00149                         // lifetime: SDNV
00150                         length += sdnv_size;
00151 
00152                         IBRCOMMON_LOGGER_DEBUG_ex(ibrcommon::Logger::LOGGER_DEBUG) << "length: " << length << IBRCOMMON_LOGGER_ENDL;
00153 
00154                         return length;
00155                 }
00156 
00157                 size_t MutualSerializer::getLength(const dtn::data::Block &obj) const
00158                 {
00159                         size_t len = 0;
00160 
00161                         len += sizeof(obj._blocktype);
00162                         // proc flags
00163                         len += sdnv_size;
00164 
00165 #ifdef __DEVELOPMENT_ASSERTIONS__
00166                         // test: BLOCK_CONTAINS_EIDS => (_eids.size() > 0)
00167                         assert(!obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00168 #endif
00169 
00170                         if (obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS))
00171                                 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00172                                         len += it->getString().size();
00173 
00174                         // size-field of the size of the payload in the block
00175                         len += sdnv_size;
00176 
00177                         try {
00178                                 const dtn::security::SecurityBlock &sb = dynamic_cast<const dtn::security::SecurityBlock&>(obj);
00179 
00180                                 // add size of the payload in the block
00181                                 len += sb.getLength_mutable();
00182                         } catch (const std::bad_cast&) {
00183                                 // add size of the payload in the block
00184                                 len += obj.getLength();
00185                         };
00186 
00187                         return len;
00188                 }
00189 
00190 
00191                 dtn::data::Serializer& MutualSerializer::operator<<(const u_int32_t value)
00192                 {
00193                         u_int32_t be = htonl(value);
00194                         _stream.write(reinterpret_cast<char*>(&be), sizeof(u_int32_t));
00195                         return *this;
00196                 }
00197 
00198                 dtn::data::Serializer& MutualSerializer::operator<<(const dtn::data::EID& value)
00199                 {
00200                         dtn::data::BundleString bs(value.getString());
00201                         _stream << bs;
00202 
00203                         return *this;
00204                 }
00205 
00206                 dtn::data::Serializer& MutualSerializer::operator<<(const dtn::data::SDNV& value)
00207                 {
00208                         // endianess muahahaha ...
00209                         // and now we are gcc centric, even older versions work
00210                         u_int64_t be = _ibrdtn_htobe64(value.getValue());
00211                         _stream.write(reinterpret_cast<char*>(&be), sizeof(u_int64_t));
00212                         return *this;
00213                 }
00214 
00215                 dtn::data::Serializer& MutualSerializer::operator<<(const dtn::security::SecurityBlock::TLVList& list)
00216                 {
00217                         (*this) << dtn::data::SDNV(list.getLength());
00218                         _stream << list.toString();
00219                         return *this;
00220                 }
00221         }
00222 }