peerstore_common.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2012-2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file peerstore/peerstore_common.c
  18. * @brief Helper peerstore functions
  19. * @author Omar Tarabai
  20. */
  21. #include "peerstore_common.h"
  22. /**
  23. * Creates a hash of the given key combination
  24. *
  25. */
  26. void
  27. PEERSTORE_hash_key (const char *sub_system,
  28. const struct GNUNET_PeerIdentity *peer,
  29. const char *key,
  30. struct GNUNET_HashCode *ret)
  31. {
  32. size_t sssize;
  33. size_t psize;
  34. size_t ksize;
  35. size_t totalsize;
  36. void *block;
  37. void *blockptr;
  38. sssize = strlen (sub_system) + 1;
  39. psize = sizeof (struct GNUNET_PeerIdentity);
  40. ksize = strlen (key) + 1;
  41. totalsize = sssize + psize + ksize;
  42. block = GNUNET_malloc (totalsize);
  43. blockptr = block;
  44. GNUNET_memcpy (blockptr, sub_system, sssize);
  45. blockptr += sssize;
  46. GNUNET_memcpy (blockptr, peer, psize);
  47. blockptr += psize;
  48. GNUNET_memcpy (blockptr, key, ksize);
  49. GNUNET_CRYPTO_hash (block, totalsize, ret);
  50. GNUNET_free (block);
  51. }
  52. /**
  53. * Creates a MQ envelope for a single record
  54. *
  55. * @param sub_system sub system string
  56. * @param peer Peer identity (can be NULL)
  57. * @param key record key string (can be NULL)
  58. * @param value record value BLOB (can be NULL)
  59. * @param value_size record value size in bytes (set to 0 if value is NULL)
  60. * @param expiry time after which the record expires
  61. * @param options options specific to the storage operation
  62. * @param msg_type message type to be set in header
  63. * @return pointer to record message struct
  64. */
  65. struct GNUNET_MQ_Envelope *
  66. PEERSTORE_create_record_mq_envelope (const char *sub_system,
  67. const struct GNUNET_PeerIdentity *peer,
  68. const char *key,
  69. const void *value,
  70. size_t value_size,
  71. struct GNUNET_TIME_Absolute expiry,
  72. enum GNUNET_PEERSTORE_StoreOption options,
  73. uint16_t msg_type)
  74. {
  75. struct StoreRecordMessage *srm;
  76. struct GNUNET_MQ_Envelope *ev;
  77. size_t ss_size;
  78. size_t key_size;
  79. size_t msg_size;
  80. void *dummy;
  81. GNUNET_assert (NULL != sub_system);
  82. ss_size = strlen (sub_system) + 1;
  83. if (NULL == key)
  84. key_size = 0;
  85. else
  86. key_size = strlen (key) + 1;
  87. msg_size = ss_size + key_size + value_size;
  88. ev = GNUNET_MQ_msg_extra (srm, msg_size, msg_type);
  89. srm->key_size = htons (key_size);
  90. srm->expiry = GNUNET_TIME_absolute_hton (expiry);
  91. if (NULL == peer)
  92. srm->peer_set = htons (GNUNET_NO);
  93. else
  94. {
  95. srm->peer_set = htons (GNUNET_YES);
  96. srm->peer = *peer;
  97. }
  98. srm->sub_system_size = htons (ss_size);
  99. srm->value_size = htons (value_size);
  100. srm->options = htonl (options);
  101. dummy = &srm[1];
  102. GNUNET_memcpy (dummy, sub_system, ss_size);
  103. dummy += ss_size;
  104. GNUNET_memcpy (dummy, key, key_size);
  105. dummy += key_size;
  106. GNUNET_memcpy (dummy, value, value_size);
  107. return ev;
  108. }
  109. /**
  110. * Parses a message carrying a record
  111. *
  112. * @param srm the actual message
  113. * @return Pointer to record or NULL if error
  114. */
  115. struct GNUNET_PEERSTORE_Record *
  116. PEERSTORE_parse_record_message (const struct StoreRecordMessage *srm)
  117. {
  118. struct GNUNET_PEERSTORE_Record *record;
  119. uint16_t req_size;
  120. uint16_t ss_size;
  121. uint16_t key_size;
  122. uint16_t value_size;
  123. char *dummy;
  124. req_size = ntohs (srm->header.size) - sizeof (*srm);
  125. ss_size = ntohs (srm->sub_system_size);
  126. key_size = ntohs (srm->key_size);
  127. value_size = ntohs (srm->value_size);
  128. if (ss_size + key_size + value_size != req_size)
  129. {
  130. GNUNET_break (0);
  131. return NULL;
  132. }
  133. record = GNUNET_new (struct GNUNET_PEERSTORE_Record);
  134. if (GNUNET_YES == ntohs (srm->peer_set))
  135. {
  136. record->peer = srm->peer;
  137. }
  138. record->expiry = GNUNET_TIME_absolute_ntoh (srm->expiry);
  139. dummy = (char *) &srm[1];
  140. if (ss_size > 0)
  141. {
  142. record->sub_system = GNUNET_strdup (dummy);
  143. dummy += ss_size;
  144. }
  145. if (key_size > 0)
  146. {
  147. record->key = GNUNET_strdup (dummy);
  148. dummy += key_size;
  149. }
  150. if (value_size > 0)
  151. {
  152. record->value = GNUNET_malloc (value_size);
  153. GNUNET_memcpy (record->value,
  154. dummy,
  155. value_size);
  156. }
  157. record->value_size = value_size;
  158. return record;
  159. }
  160. /**
  161. * Free any memory allocated for this record
  162. *
  163. * @param record
  164. */
  165. void
  166. PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record)
  167. {
  168. if (NULL != record->sub_system)
  169. GNUNET_free (record->sub_system);
  170. if (NULL != record->key)
  171. GNUNET_free (record->key);
  172. if (NULL != record->value)
  173. {
  174. GNUNET_free (record->value);
  175. record->value = 0;
  176. }
  177. GNUNET_free (record);
  178. }