2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * @file gnsrecord/gnsrecord_misc.c
21 * @brief MISC functions related to GNS records
22 * @author Martin Schanzenbach
23 * @author Matthias Wachs
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_signatures.h"
30 #include "gnunet_arm_service.h"
31 #include "gnunet_gnsrecord_lib.h"
32 #include "gnunet_dnsparser_lib.h"
33 #include "gnunet_tun_lib.h"
36 #define LOG(kind,...) GNUNET_log_from (kind, "gnsrecord",__VA_ARGS__)
39 * Convert a UTF-8 string to UTF-8 lowercase
40 * @param src source string
41 * @return converted result
44 GNUNET_GNSRECORD_string_to_lowercase (const char *src)
48 res = GNUNET_strdup (src);
49 GNUNET_STRINGS_utf8_tolower (src, res);
55 * Convert a zone key to a string (for printing debug messages).
56 * This is one of the very few calls in the entire API that is
59 * @param z the zone key
60 * @return string form; will be overwritten by next call to #GNUNET_GNSRECORD_z2s
63 GNUNET_GNSRECORD_z2s (const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
65 static char buf[sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) * 8];
68 end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z,
69 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
82 * Compares if two records are equal (ignoring flags such
83 * as authority, private and pending, but not relative vs.
84 * absolute expiration time).
88 * @return #GNUNET_YES if the records are equal or #GNUNET_NO if they are not
91 GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a,
92 const struct GNUNET_GNSRECORD_Data *b)
94 LOG (GNUNET_ERROR_TYPE_DEBUG,
95 "Comparing records\n");
96 if (a->record_type != b->record_type)
98 LOG (GNUNET_ERROR_TYPE_DEBUG,
99 "Record type %lu != %lu\n", a->record_type, b->record_type);
102 if ((a->expiration_time != b->expiration_time) &&
103 ((a->expiration_time != 0) && (b->expiration_time != 0)))
105 LOG (GNUNET_ERROR_TYPE_DEBUG,
106 "Expiration time %llu != %llu\n",
111 if ((a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS)
112 != (b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS))
114 LOG (GNUNET_ERROR_TYPE_DEBUG,
115 "Flags %lu (%lu) != %lu (%lu)\n", a->flags,
116 a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS, b->flags,
117 b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS);
120 if (a->data_size != b->data_size)
122 LOG (GNUNET_ERROR_TYPE_DEBUG,
123 "Data size %lu != %lu\n",
128 if (0 != memcmp (a->data, b->data, a->data_size))
130 LOG (GNUNET_ERROR_TYPE_DEBUG,
131 "Data contents do not match\n");
134 LOG (GNUNET_ERROR_TYPE_DEBUG,
135 "Records are equal\n");
141 * Returns the expiration time of the given block of records. The block
142 * expiration time is the expiration time of the record with smallest
145 * @param rd_count number of records given in @a rd
146 * @param rd array of records
147 * @return absolute expiration time
149 struct GNUNET_TIME_Absolute
150 GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count,
151 const struct GNUNET_GNSRECORD_Data *rd)
153 struct GNUNET_TIME_Absolute expire;
154 struct GNUNET_TIME_Absolute at;
155 struct GNUNET_TIME_Relative rt;
156 struct GNUNET_TIME_Absolute at_shadow;
157 struct GNUNET_TIME_Relative rt_shadow;
160 return GNUNET_TIME_UNIT_ZERO_ABS;
161 expire = GNUNET_TIME_UNIT_FOREVER_ABS;
162 for (unsigned int c = 0; c < rd_count; c++)
164 if (0 != (rd[c].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
166 rt.rel_value_us = rd[c].expiration_time;
167 at = GNUNET_TIME_relative_to_absolute (rt);
171 at.abs_value_us = rd[c].expiration_time;
174 for (unsigned int c2 = 0; c2 < rd_count; c2++)
176 /* Check for shadow record */
178 (rd[c].record_type != rd[c2].record_type) ||
179 (0 == (rd[c2].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) )
181 /* We have a shadow record */
182 if (0 != (rd[c2].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
184 rt_shadow.rel_value_us = rd[c2].expiration_time;
185 at_shadow = GNUNET_TIME_relative_to_absolute (rt_shadow);
189 at_shadow.abs_value_us = rd[c2].expiration_time;
191 at = GNUNET_TIME_absolute_max (at,
194 expire = GNUNET_TIME_absolute_min (at,
197 LOG (GNUNET_ERROR_TYPE_DEBUG,
198 "Determined expiration time for block with %u records to be %s\n",
200 GNUNET_STRINGS_absolute_time_to_string (expire));
206 * Test if a given record is expired.
208 * @return #GNUNET_YES if the record is expired,
212 GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd)
214 struct GNUNET_TIME_Absolute at;
216 if (0 != (rd->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
218 at.abs_value_us = rd->expiration_time;
219 return (0 == GNUNET_TIME_absolute_get_remaining (at).rel_value_us) ? GNUNET_YES : GNUNET_NO;
224 * Convert public key to the respective absolute domain name in the
226 * This is one of the very few calls in the entire API that is
229 * @param pkey a public key with a point on the eliptic curve
230 * @return string "X.zkey" where X is the public
231 * key in an encoding suitable for DNS labels.
234 GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
236 static char ret[128];
239 pkeys = GNUNET_CRYPTO_ecdsa_public_key_to_string (pkey);
240 GNUNET_snprintf (ret,
250 * Convert an absolute domain name to the
251 * respective public key.
253 * @param zkey string encoding the coordinates of the public
254 * key in an encoding suitable for DNS labels.
255 * @param pkey set to a public key on the eliptic curve
256 * @return #GNUNET_SYSERR if @a zkey has the wrong syntax
259 GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey,
260 struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
263 GNUNET_CRYPTO_ecdsa_public_key_from_string (zkey,
266 return GNUNET_SYSERR;
271 /* end of gnsrecord_misc.c */