前言
data.cpp
和 interest.cpp
用于处理兴趣包和数据包。
data.hpp
删掉了部分我认为不重要的东西,比如 class Error
。这里面的 wireEncode
属于是经典的模板编程的例子,看这种代码真是吐了。不过看懂了其实还好,这个代码的意思就是先用 EncodingEstimator
计算出需要的 buffer
的大小,然后再用 EncodingBuffer
造出一个真正的 buffer
,对这个 buffer
执行 wireDecode
函数,更新自己的成员函数。
class Data : public PacketBase, public std::enable_shared_from_this<Data>
{
public:
// 构造一个Name为name的空Data包
explicit Data(const Name& name = Name());
// 通过对Block进行解码,构造出一个Data包
explicit Data(const Block& wire);
// 对内容进行Encode,其中TAG分为EncodingEstimator和EncodingBuffer
template<encoding::Tag TAG>
size_t wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
const Block& wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
// 先执行wireEncode<EncodingEstimator>,这部分用于计算buffer的大小,不执行操作
// 再执行wireEncode<EncodingBuffer>,这部分用于真正创建一个buffer,并对它进行Encode操作
// 最后把buffer用于执行wireDecode,更新本Data的成员函数
const Block& wireEncode() const;
// 按照Name->MetaInfo(?)->Content(?)->SignatureInfo->SignatureValue的顺序解码到自己的成员函数里
void wireDecode(const Block& wire);
bool hasWire() const { return m_wire.hasWire(); }
const Name& getFullName() const; // return m_name(以及对应的ImplicitSha256Digest组件)
public: // 数据的Get和Set
const Name& getName() const { return m_name; }
Data& setName(const Name& name); // return m_name
const MetaInfo& getMetaInfo() const { return m_metaInfo; }
Data& setMetaInfo(const MetaInfo& metaInfo);
const Block& getContent() const;
Data& setContent(const Block& block);
Data& setContent(const uint8_t* value, size_t valueSize);
Data& setContent(ConstBufferPtr value);
const Signature& getSignature() const { return m_signature; }
Data& setSignature(const Signature& signature);
Data& setSignatureValue(const Block& value);
public: // MetaInfo的Get和Set
uint32_t getContentType() const { return m_metaInfo.getType(); }
Data& setContentType(uint32_t type);
time::milliseconds getFreshnessPeriod() const { return m_metaInfo.getFreshnessPeriod(); }
Data& setFreshnessPeriod(time::milliseconds freshnessPeriod);
const optional<name::Component>& getFinalBlock() const { return m_metaInfo.getFinalBlock(); }
Data& setFinalBlock(optional<name::Component> finalBlockId);
protected:
void resetWire(); // 每次set后都要重置wire
private:
Name m_name;
MetaInfo m_metaInfo;
Block m_content;
Signature m_signature;
mutable Block m_wire;
mutable Name m_fullName; ///< cached FullName computed from m_wire
};
#ifndef DOXYGEN
extern template size_t
Data::wireEncode<encoding::EncoderTag>(EncodingBuffer&, bool) const;
extern template size_t
Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
#endif
std::ostream& operator<<(std::ostream& os, const Data& data);
bool operator==(const Data& lhs, const Data& rhs);
inline bool operator!=(const Data& lhs, const Data& rhs) { return !(lhs == rhs); }
关于具体的编解码过程,请参考ndnSIM学习(五)——data包和interest包的tlv编码、解码过程以及如何判断包的类型这篇文章,这里面主要讲了 tlv
相关的东西。ndnSIM学习(八)——apps之ndn-producer.cpp和ndn-consumer.cpp源码分析这篇文章里主要讲了发包和收包的过程。
interest.hpp
删掉了部分我认为不重要的东西,比如 class Error
。大部分内容和 Data
是类似的,不过其中关于 SHA256
加密这块我还是没怎么搞明白。
// 默认interest生存时间为4s
const time::milliseconds DEFAULT_INTEREST_LIFETIME = 4_s;
class Interest : public PacketBase, public std::enable_shared_from_this<Interest>
{
public:
// 初始化Name&lifetime
explicit Interest(const Name& name = Name(), time::milliseconds lifetime = DEFAULT_INTEREST_LIFETIME);
// 用Block造一个Interest
explicit Interest(const Block& wire);
template<encoding::Tag TAG>
size_t wireEncode(EncodingImpl<TAG>& encoder) const;
// 先执行wireEncode<EncodingEstimator>,这部分用于计算buffer的大小,不执行操作
// 再执行wireEncode<EncodingBuffer>,这部分用于真正创建一个buffer,并对它进行Encode操作
// 最后把buffer用于执行wireDecode,更新本Data的成员函数
const Block& wireEncode() const;
// Name(SHA256?)->CanBePrefix?->MustBeFresh?->ForwardingHint?->Nonce->InterestLifetime?->HopLimit?->ApplicationParameters?
void wireDecode(const Block& wire);
bool hasWire() const { return m_wire.hasWire(); }
std::string toUri() const;
public: // 匹配
// 看Interest是否能匹配上Data
bool matchesData(const Data& data) const;
// 比较Name和CanBePrefix和MustBeFresh
bool matchesInterest(const Interest& other) const;
public: // element access
const Name& getName() const noexcept { return m_name; }
// set m_name,并且如果自己的m_parameters有SHA256参数,则添加到m_name
Interest& setName(const Name& name);
static void setDefaultCanBePrefix(bool canBePrefix) { s_defaultCanBePrefix = canBePrefix; }
bool getCanBePrefix() const noexcept { return m_canBePrefix; }
Interest& setCanBePrefix(bool canBePrefix) {
m_canBePrefix = canBePrefix;
m_wire.reset();
m_isCanBePrefixSet = true;
return *this;
}
bool getMustBeFresh() const noexcept { return m_mustBeFresh; }
Interest& setMustBeFresh(bool mustBeFresh) {
m_mustBeFresh = mustBeFresh;
m_wire.reset();
return *this;
}
const DelegationList& getForwardingHint() const noexcept { return m_forwardingHint; }
Interest& setForwardingHint(const DelegationList& value);
template<typename Modifier>
Interest& modifyForwardingHint(const Modifier& modifier) {
modifier(m_forwardingHint);
m_wire.reset();
return *this;
}
bool hasNonce() const noexcept { return m_nonce.has_value(); }
uint32_t getNonce() const;
Interest& setNonce(uint32_t nonce);
void refreshNonce();
time::milliseconds getInterestLifetime() const noexcept { return m_interestLifetime; }
Interest& setInterestLifetime(time::milliseconds lifetime);
optional<uint8_t> getHopLimit() const noexcept { return m_hopLimit; }
Interest& setHopLimit(optional<uint8_t> hopLimit);
bool hasApplicationParameters() const noexcept { return !m_parameters.empty(); }
Block getApplicationParameters() const {
if (m_parameters.empty())
return {};
else
return m_parameters.front();
}
Interest& setApplicationParameters(const Block& parameters);
Interest& setApplicationParameters(const uint8_t* value, size_t length);
Interest& setApplicationParameters(ConstBufferPtr value);
Interest& unsetApplicationParameters();
public: // ParametersSha256DigestComponent support
static bool getAutoCheckParametersDigest() { return s_autoCheckParametersDigest; }
static void setAutoCheckParametersDigest(bool b) { s_autoCheckParametersDigest = b; }
bool isParametersDigestValid() const;
private:
void setApplicationParametersInternal(Block parameters);
NDN_CXX_NODISCARD shared_ptr<Buffer> computeParametersDigest() const;
// 添加SHA256组件
void addOrReplaceParametersDigestComponent();
// 如果有1个SHA256组件,返回pos;没有返回-1;多个返回-2
static ssize_t findParametersDigestComponent(const Name& name);
#ifdef NDN_CXX_HAVE_TESTS
public:
/// If true, not setting CanBePrefix results in an error in wireEncode().
static bool s_errorIfCanBePrefixUnset;
#endif // NDN_CXX_HAVE_TESTS
private:
static boost::logic::tribool s_defaultCanBePrefix;
static bool s_autoCheckParametersDigest;
Name m_name;
DelegationList m_forwardingHint;
mutable optional<uint32_t> m_nonce;
time::milliseconds m_interestLifetime;
optional<uint8_t> m_hopLimit;
mutable bool m_isCanBePrefixSet = false;
bool m_canBePrefix = true;
bool m_mustBeFresh = false;
std::vector<Block> m_parameters;
mutable Block m_wire;
};
// 输出CanBePrefix和MustBeFresh和Nonce和Lifetime和HopLimit
std::ostream& operator<<(std::ostream& os, const Interest& interest);
总结
里面内容细节太多了,其中部分我在其他文章中分析过,所以只给 .hpp
文件加了注释,没有分析 .cpp
文件的函数。这篇文章写得有点水……