ds_like.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef __DS_LIKE_H
  15. #define __DS_LIKE_H 1
  16. #include <stdint.h>
  17. #include <string>
  18. #include <vector>
  19. struct DSImpl {
  20. // straightforward representation of DS RDATA fields
  21. DSImpl(uint16_t tag, uint8_t algorithm, uint8_t digest_type,
  22. const vector<uint8_t>& digest) :
  23. tag_(tag), algorithm_(algorithm), digest_type_(digest_type),
  24. digest_(digest)
  25. {}
  26. uint16_t tag_;
  27. uint8_t algorithm_;
  28. uint8_t digest_type_;
  29. const vector<uint8_t> digest_;
  30. };
  31. template<class RTYPE, uint16_t typeCode>class DS_LIKE : public Rdata {
  32. public:
  33. DS_LIKE(const string& ds_str) :
  34. impl_(NULL)
  35. {
  36. istringstream iss(ds_str);
  37. unsigned int tag, algorithm, digest_type;
  38. stringbuf digestbuf;
  39. iss >> tag >> algorithm >> digest_type >> &digestbuf;
  40. if (iss.bad() || iss.fail()) {
  41. isc_throw(InvalidRdataText, "Invalid " +
  42. RRParamRegistry::getRegistry().codeToTypeText(typeCode) +
  43. " text");
  44. }
  45. if (tag > 0xffff) {
  46. isc_throw(InvalidRdataText,
  47. RRParamRegistry::getRegistry().codeToTypeText(typeCode) +
  48. " tag out of range");
  49. }
  50. if (algorithm > 0xff) {
  51. isc_throw(InvalidRdataText,
  52. RRParamRegistry::getRegistry().codeToTypeText(typeCode) +
  53. " algorithm out of range");
  54. }
  55. if (digest_type > 0xff) {
  56. isc_throw(InvalidRdataText,
  57. RRParamRegistry::getRegistry().codeToTypeText(typeCode) +
  58. " digest type out of range");
  59. }
  60. vector<uint8_t> digest;
  61. decodeHex(digestbuf.str(), digest);
  62. impl_ = new DSImpl(tag, algorithm, digest_type, digest);
  63. }
  64. DS_LIKE(InputBuffer& buffer, size_t rdata_len) {
  65. if (rdata_len < 4) {
  66. isc_throw(InvalidRdataLength,
  67. RRParamRegistry::getRegistry().codeToTypeText(typeCode) +
  68. " too short");
  69. }
  70. uint16_t tag = buffer.readUint16();
  71. uint16_t algorithm = buffer.readUint8();
  72. uint16_t digest_type = buffer.readUint8();
  73. rdata_len -= 4;
  74. vector<uint8_t> digest(rdata_len);
  75. buffer.readData(&digest[0], rdata_len);
  76. impl_ = new DSImpl(tag, algorithm, digest_type, digest);
  77. }
  78. DS_LIKE(const DS_LIKE& source) :
  79. Rdata(), impl_(new DSImpl(*source.impl_))
  80. {}
  81. DS_LIKE&
  82. operator=(const DS_LIKE& source) {
  83. if (impl_ == source.impl_) {
  84. return (*this);
  85. }
  86. DSImpl* newimpl = new DSImpl(*source.impl_);
  87. delete impl_;
  88. impl_ = newimpl;
  89. return (*this);
  90. }
  91. ~DS_LIKE() {
  92. delete impl_;
  93. }
  94. string
  95. toText() const {
  96. using namespace boost;
  97. return (lexical_cast<string>(static_cast<int>(impl_->tag_)) +
  98. " " + lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
  99. " " + lexical_cast<string>(static_cast<int>(impl_->digest_type_)) +
  100. " " + encodeHex(impl_->digest_));
  101. }
  102. void
  103. toWire(OutputBuffer& buffer) const {
  104. buffer.writeUint16(impl_->tag_);
  105. buffer.writeUint8(impl_->algorithm_);
  106. buffer.writeUint8(impl_->digest_type_);
  107. buffer.writeData(&impl_->digest_[0], impl_->digest_.size());
  108. }
  109. void
  110. toWire(AbstractMessageRenderer& renderer) const {
  111. renderer.writeUint16(impl_->tag_);
  112. renderer.writeUint8(impl_->algorithm_);
  113. renderer.writeUint8(impl_->digest_type_);
  114. renderer.writeData(&impl_->digest_[0], impl_->digest_.size());
  115. }
  116. int
  117. compare(const Rdata& other) const {
  118. const RTYPE& other_ds = dynamic_cast<const RTYPE&>(other);
  119. if (impl_->tag_ != other_ds.impl_->tag_) {
  120. return (impl_->tag_ < other_ds.impl_->tag_ ? -1 : 1);
  121. }
  122. if (impl_->algorithm_ != other_ds.impl_->algorithm_) {
  123. return (impl_->algorithm_ < other_ds.impl_->algorithm_ ? -1 : 1);
  124. }
  125. if (impl_->digest_type_ != other_ds.impl_->digest_type_) {
  126. return (impl_->digest_type_ < other_ds.impl_->digest_type_ ? -1 : 1);
  127. }
  128. size_t this_len = impl_->digest_.size();
  129. size_t other_len = other_ds.impl_->digest_.size();
  130. size_t cmplen = min(this_len, other_len);
  131. int cmp = memcmp(&impl_->digest_[0], &other_ds.impl_->digest_[0], cmplen);
  132. if (cmp != 0) {
  133. return (cmp);
  134. } else {
  135. return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
  136. }
  137. }
  138. uint16_t
  139. getTag() const {
  140. return (impl_->tag_);
  141. }
  142. private:
  143. DSImpl* impl_;
  144. };
  145. #endif // __DS_LIKE_H
  146. // Local Variables:
  147. // mode: c++
  148. // End: