gnsrecord_serialization.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2009-2013 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. 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. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file gnsrecord/gnsrecord_serialization.c
  19. * @brief API to serialize and deserialize GNS records
  20. * @author Martin Schanzenbach
  21. * @author Matthias Wachs
  22. * @author Christian Grothoff
  23. */
  24. #include "platform.h"
  25. #include "gnunet_util_lib.h"
  26. #include "gnunet_constants.h"
  27. #include "gnunet_signatures.h"
  28. #include "gnunet_arm_service.h"
  29. #include "gnunet_gnsrecord_lib.h"
  30. #include "gnunet_dnsparser_lib.h"
  31. #include "gnunet_tun_lib.h"
  32. #define LOG(kind,...) GNUNET_log_from (kind, "gnsrecord",__VA_ARGS__)
  33. GNUNET_NETWORK_STRUCT_BEGIN
  34. /**
  35. * Internal format of a record in the serialized form.
  36. */
  37. struct NetworkRecord
  38. {
  39. /**
  40. * Expiration time for the DNS record; relative or absolute depends
  41. * on 'flags', network byte order.
  42. */
  43. uint64_t expiration_time GNUNET_PACKED;
  44. /**
  45. * Number of bytes in 'data', network byte order.
  46. */
  47. uint32_t data_size GNUNET_PACKED;
  48. /**
  49. * Type of the GNS/DNS record, network byte order.
  50. */
  51. uint32_t record_type GNUNET_PACKED;
  52. /**
  53. * Flags for the record, network byte order.
  54. */
  55. uint32_t flags GNUNET_PACKED;
  56. };
  57. GNUNET_NETWORK_STRUCT_END
  58. /**
  59. * Calculate how many bytes we will need to serialize the given
  60. * records.
  61. *
  62. * @param rd_count number of records in the rd array
  63. * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements
  64. * @return the required size to serialize
  65. */
  66. size_t
  67. GNUNET_GNSRECORD_records_get_size (unsigned int rd_count,
  68. const struct GNUNET_GNSRECORD_Data *rd)
  69. {
  70. unsigned int i;
  71. size_t ret;
  72. ret = sizeof (struct NetworkRecord) * rd_count;
  73. for (i=0;i<rd_count;i++)
  74. {
  75. GNUNET_assert ((ret + rd[i].data_size) >= ret);
  76. ret += rd[i].data_size;
  77. }
  78. return ret;
  79. }
  80. /**
  81. * Serialize the given records to the given destination buffer.
  82. *
  83. * @param rd_count number of records in the rd array
  84. * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements
  85. * @param dest_size size of the destination array
  86. * @param dest where to write the result
  87. * @return the size of serialized records, -1 if records do not fit
  88. */
  89. ssize_t
  90. GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
  91. const struct GNUNET_GNSRECORD_Data *rd,
  92. size_t dest_size,
  93. char *dest)
  94. {
  95. struct NetworkRecord rec;
  96. unsigned int i;
  97. size_t off;
  98. off = 0;
  99. for (i=0;i<rd_count;i++)
  100. {
  101. #if 0
  102. LOG (GNUNET_ERROR_TYPE_DEBUG,
  103. "Serializing record %u with flags %d and expiration time %llu\n",
  104. i,
  105. rd[i].flags,
  106. (unsigned long long) rd[i].expiration_time);
  107. #endif
  108. rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
  109. rec.data_size = htonl ((uint32_t) rd[i].data_size);
  110. rec.record_type = htonl (rd[i].record_type);
  111. rec.flags = htonl (rd[i].flags);
  112. if (off + sizeof (rec) > dest_size)
  113. return -1;
  114. memcpy (&dest[off], &rec, sizeof (rec));
  115. off += sizeof (rec);
  116. if (off + rd[i].data_size > dest_size)
  117. return -1;
  118. memcpy (&dest[off], rd[i].data, rd[i].data_size);
  119. off += rd[i].data_size;
  120. }
  121. return off;
  122. }
  123. /**
  124. * Deserialize the given records to the given destination.
  125. *
  126. * @param len size of the serialized record data
  127. * @param src the serialized record data
  128. * @param rd_count number of records in the rd array
  129. * @param dest where to put the data
  130. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  131. */
  132. int
  133. GNUNET_GNSRECORD_records_deserialize (size_t len,
  134. const char *src,
  135. unsigned int rd_count,
  136. struct GNUNET_GNSRECORD_Data *dest)
  137. {
  138. struct NetworkRecord rec;
  139. unsigned int i;
  140. size_t off;
  141. off = 0;
  142. for (i=0;i<rd_count;i++)
  143. {
  144. if (off + sizeof (rec) > len)
  145. return GNUNET_SYSERR;
  146. memcpy (&rec, &src[off], sizeof (rec));
  147. dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
  148. dest[i].data_size = ntohl ((uint32_t) rec.data_size);
  149. dest[i].record_type = ntohl (rec.record_type);
  150. dest[i].flags = ntohl (rec.flags);
  151. off += sizeof (rec);
  152. if (off + dest[i].data_size > len)
  153. return GNUNET_SYSERR;
  154. dest[i].data = &src[off];
  155. off += dest[i].data_size;
  156. #if 0
  157. LOG (GNUNET_ERROR_TYPE_DEBUG,
  158. "Deserialized record %u with flags %d and expiration time %llu\n",
  159. i,
  160. dest[i].flags,
  161. (unsigned long long) dest[i].expiration_time);
  162. #endif
  163. }
  164. return GNUNET_OK;
  165. }
  166. /* end of gnsrecord_serialization.c */