ReplySerializer.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "benc/Dict.h"
  16. #include "benc/String.h"
  17. #include "crypto/AddressCalc.h"
  18. #include "dht/CJDHTConstants.h"
  19. #include "dht/dhtcore/ReplySerializer.h"
  20. #include "dht/dhtcore/VersionList.h"
  21. #include "dht/Address.h"
  22. #include "memory/Allocator.h"
  23. #include "switch/LabelSplicer.h"
  24. #include "util/Identity.h"
  25. #include "util/log/Log.h"
  26. #include "util/Assert.h"
  27. /**
  28. * For serializing and parsing responses to getPeers and search requests.
  29. */
  30. struct Address_List* ReplySerializer_parse(struct Address* fromNode,
  31. Dict* result,
  32. struct Log* log,
  33. bool splicePath,
  34. struct Allocator* alloc)
  35. {
  36. String* nodes = Dict_getString(result, CJDHTConstants_NODES);
  37. if (!nodes) { return NULL; }
  38. if (nodes->len == 0 || nodes->len % Address_SERIALIZED_SIZE != 0) {
  39. Log_debug(log, "Dropping unrecognized reply");
  40. return NULL;
  41. }
  42. struct VersionList* versions = NULL;
  43. String* versionsStr = Dict_getString(result, CJDHTConstants_NODE_PROTOCOLS);
  44. if (versionsStr) {
  45. versions = VersionList_parse(versionsStr, alloc);
  46. }
  47. if (!versions || versions->length != (nodes->len / Address_SERIALIZED_SIZE)) {
  48. Log_debug(log, "Reply with missing or invalid versions");
  49. return NULL;
  50. }
  51. struct Address_List* out = Address_List_new(versions->length, alloc);
  52. uint32_t j = 0;
  53. for (uint32_t i = 0; nodes && i < nodes->len; i += Address_SERIALIZED_SIZE) {
  54. struct Address addr = { .path = 0 };
  55. Address_parse(&addr, (uint8_t*) &nodes->bytes[i]);
  56. addr.protocolVersion = versions->versions[i / Address_SERIALIZED_SIZE];
  57. // calculate the ipv6
  58. Address_getPrefix(&addr);
  59. if (splicePath) {
  60. // We need to splice the given address on to the end of the
  61. // address of the node which gave it to us.
  62. uint64_t path = LabelSplicer_splice(addr.path, fromNode->path);
  63. if (path == UINT64_MAX) {
  64. /* common, lots of noise
  65. uint8_t discovered[60];
  66. uint8_t fromAddr[60];
  67. Address_print(discovered, &addr);
  68. Address_print(fromAddr, fromNode);
  69. Log_debug(log,
  70. "Dropping response [%s] from [%s] because route could not be spliced",
  71. discovered, fromAddr);*/
  72. continue;
  73. }
  74. addr.path = path;
  75. }
  76. /*#ifdef Log_DEBUG
  77. uint8_t printedAddr[60];
  78. Address_print(printedAddr, &addr);
  79. Log_debug(log, "discovered node [%s]", printedAddr);
  80. #endif*/
  81. Address_getPrefix(&addr);
  82. if (!AddressCalc_validAddress(addr.ip6.bytes)) {
  83. Log_debug(log, "Was told garbage.\n");
  84. // This should never happen, badnode.
  85. continue;
  86. }
  87. Bits_memcpyConst(&out->elems[j++], &addr, sizeof(struct Address));
  88. }
  89. out->length = j;
  90. return out;
  91. }