ds_43.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright (C) 2010 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. // $Id$
  15. #include <config.h>
  16. #include <iostream>
  17. #include <string>
  18. #include <sstream>
  19. #include <vector>
  20. #include "buffer.h"
  21. #include "hex.h"
  22. #include "messagerenderer.h"
  23. #include "name.h"
  24. #include "rdata.h"
  25. #include "rdataclass.h"
  26. #include <boost/lexical_cast.hpp>
  27. #include <stdio.h>
  28. #include <time.h>
  29. using namespace std;
  30. // BEGIN_ISC_NAMESPACE
  31. // BEGIN_RDATA_NAMESPACE
  32. struct DSImpl {
  33. // straightforward representation of DS RDATA fields
  34. DSImpl(uint16_t tag, uint8_t algorithm, uint8_t digest_type,
  35. const vector<uint8_t>& digest) :
  36. tag_(tag), algorithm_(algorithm), digest_type_(digest_type),
  37. digest_(digest)
  38. {}
  39. uint16_t tag_;
  40. uint8_t algorithm_;
  41. uint8_t digest_type_;
  42. const vector<uint8_t> digest_;
  43. };
  44. DS::DS(const string& ds_str) :
  45. impl_(NULL)
  46. {
  47. istringstream iss(ds_str);
  48. unsigned int tag, algorithm, digest_type;
  49. stringbuf digestbuf;
  50. iss >> tag >> algorithm >> digest_type >> &digestbuf;
  51. if (iss.bad() || iss.fail()) {
  52. isc_throw(InvalidRdataText, "Invalid DS text");
  53. }
  54. if (tag > 0xffff) {
  55. isc_throw(InvalidRdataText, "DS tag out of range");
  56. }
  57. if (algorithm > 0xff) {
  58. isc_throw(InvalidRdataText, "DS algorithm out of range");
  59. }
  60. if (digest_type > 0xff) {
  61. isc_throw(InvalidRdataText, "DS digest type out of range");
  62. }
  63. vector<uint8_t> digest;
  64. decodeHex(digestbuf.str(), digest);
  65. impl_ = new DSImpl(tag, algorithm, digest_type, digest);
  66. }
  67. DS::DS(InputBuffer& buffer, size_t rdata_len)
  68. {
  69. if (rdata_len < 4) {
  70. isc_throw(InvalidRdataLength, "DS too short");
  71. }
  72. uint16_t tag = buffer.readUint16();
  73. uint16_t algorithm = buffer.readUint8();
  74. uint16_t digest_type = buffer.readUint8();
  75. rdata_len -= 4;
  76. vector<uint8_t> digest(rdata_len);
  77. buffer.readData(&digest[0], rdata_len);
  78. impl_ = new DSImpl(tag, algorithm, digest_type, digest);
  79. }
  80. DS::DS(const DS& source) :
  81. Rdata(), impl_(new DSImpl(*source.impl_))
  82. {}
  83. DS&
  84. DS::operator=(const DS& source)
  85. {
  86. if (impl_ == source.impl_) {
  87. return (*this);
  88. }
  89. DSImpl* newimpl = new DSImpl(*source.impl_);
  90. delete impl_;
  91. impl_ = newimpl;
  92. return (*this);
  93. }
  94. DS::~DS()
  95. {
  96. delete impl_;
  97. }
  98. string
  99. DS::toText() const
  100. {
  101. using namespace boost;
  102. return (lexical_cast<string>(static_cast<int>(impl_->tag_)) +
  103. " " + lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
  104. " " + lexical_cast<string>(static_cast<int>(impl_->digest_type_)) +
  105. " " + encodeHex(impl_->digest_));
  106. }
  107. void
  108. DS::toWire(OutputBuffer& buffer) const
  109. {
  110. buffer.writeUint16(impl_->tag_);
  111. buffer.writeUint8(impl_->algorithm_);
  112. buffer.writeUint8(impl_->digest_type_);
  113. buffer.writeData(&impl_->digest_[0], impl_->digest_.size());
  114. }
  115. void
  116. DS::toWire(MessageRenderer& renderer) const
  117. {
  118. renderer.writeUint16(impl_->tag_);
  119. renderer.writeUint8(impl_->algorithm_);
  120. renderer.writeUint8(impl_->digest_type_);
  121. renderer.writeData(&impl_->digest_[0], impl_->digest_.size());
  122. }
  123. int
  124. DS::compare(const Rdata& other) const
  125. {
  126. const DS& other_ds = dynamic_cast<const DS&>(other);
  127. if (impl_->tag_ != other_ds.impl_->tag_) {
  128. return (impl_->tag_ < other_ds.impl_->tag_ ? -1 : 1);
  129. }
  130. if (impl_->algorithm_ != other_ds.impl_->algorithm_) {
  131. return (impl_->algorithm_ < other_ds.impl_->algorithm_ ? -1 : 1);
  132. }
  133. if (impl_->digest_type_ != other_ds.impl_->digest_type_) {
  134. return (impl_->digest_type_ < other_ds.impl_->digest_type_ ? -1 : 1);
  135. }
  136. size_t this_len = impl_->digest_.size();
  137. size_t other_len = other_ds.impl_->digest_.size();
  138. size_t cmplen = min(this_len, other_len);
  139. int cmp = memcmp(&impl_->digest_[0], &other_ds.impl_->digest_[0], cmplen);
  140. if (cmp != 0) {
  141. return (cmp);
  142. } else {
  143. return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
  144. }
  145. }
  146. uint16_t
  147. DS::getTag() const {
  148. return impl_->tag_;
  149. }
  150. // END_RDATA_NAMESPACE
  151. // END_ISC_NAMESPACE