|
IBR-DTNSuite 0.6
|
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 }