• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

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                                 obj.serialize(_stream);
00115                         };
00116 
00117                         return (*this);
00118                 }
00119 
00120                 size_t MutualSerializer::getLength(const dtn::data::Bundle&)
00121                 {
00122 #ifdef __DEVELOPMENT_ASSERTIONS__
00123                         assert(false);
00124 #endif
00125                         return 0;
00126                 }
00127 
00128                 size_t MutualSerializer::getLength(const dtn::data::PrimaryBlock &obj) const
00129                 {
00130                         // predict the block length
00131                         // length in bytes
00132                         // starting with the fields after the length field
00133 
00134                         // dest id length
00135                         u_int32_t length = 4;
00136                         // dest id
00137                         length += obj._destination.getString().size();
00138                         // source id length
00139                         length += 4;
00140                         // source id
00141                         length += obj._source.getString().size();
00142                         // report to id length
00143                         length += 4;
00144                         // report to id
00145                         length += obj._reportto.getString().size();
00146                         // creation time: 2*SDNV
00147                         length += 2*sdnv_size;
00148                         // lifetime: SDNV
00149                         length += sdnv_size;
00150 
00151                         IBRCOMMON_LOGGER_DEBUG_ex(ibrcommon::Logger::LOGGER_DEBUG) << "length: " << length << IBRCOMMON_LOGGER_ENDL;
00152 
00153                         return length;
00154                 }
00155 
00156                 size_t MutualSerializer::getLength(const dtn::data::Block &obj) const
00157                 {
00158                         size_t len = 0;
00159 
00160                         len += sizeof(obj._blocktype);
00161                         // proc flags
00162                         len += sdnv_size;
00163 
00164 #ifdef __DEVELOPMENT_ASSERTIONS__
00165                         // test: BLOCK_CONTAINS_EIDS => (_eids.size() > 0)
00166                         assert(!obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00167 #endif
00168 
00169                         if (obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS))
00170                                 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00171                                         len += it->getString().size();
00172 
00173                         // size-field of the size of the payload in the block
00174                         len += sdnv_size;
00175 
00176                         try {
00177                                 const dtn::security::SecurityBlock &sb = dynamic_cast<const dtn::security::SecurityBlock&>(obj);
00178 
00179                                 // add size of the payload in the block
00180                                 len += sb.getLength_mutable();
00181                         } catch (const std::bad_cast&) {
00182                                 // add size of the payload in the block
00183                                 len += obj.getLength();
00184                         };
00185 
00186                         return len;
00187                 }
00188 
00189 
00190                 dtn::data::Serializer& MutualSerializer::operator<<(const u_int32_t value)
00191                 {
00192                         u_int32_t be = htonl(value);
00193                         _stream.write(reinterpret_cast<char*>(&be), sizeof(u_int32_t));
00194                         return *this;
00195                 }
00196 
00197                 dtn::data::Serializer& MutualSerializer::operator<<(const dtn::data::EID& value)
00198                 {
00199                         dtn::data::BundleString bs(value.getString());
00200                         _stream << bs;
00201 
00202                         return *this;
00203                 }
00204 
00205                 dtn::data::Serializer& MutualSerializer::operator<<(const dtn::data::SDNV& value)
00206                 {
00207                         // endianess muahahaha ...
00208                         // and now we are gcc centric, even older versions work
00209                         u_int64_t be = _ibrdtn_htobe64(value.getValue());
00210                         _stream.write(reinterpret_cast<char*>(&be), sizeof(u_int64_t));
00211                         return *this;
00212                 }
00213 
00214                 dtn::data::Serializer& MutualSerializer::operator<<(const dtn::security::SecurityBlock::TLVList& list)
00215                 {
00216                         (*this) << dtn::data::SDNV(list.getLength());
00217                         _stream << list.toString();
00218                         return *this;
00219                 }
00220         }
00221 }

Generated on Wed Mar 30 2011 11:11:49 for IBR-DTNSuite by  doxygen 1.7.1