aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/namestore_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore/namestore_common.c')
-rw-r--r--src/namestore/namestore_common.c422
1 files changed, 306 insertions, 116 deletions
diff --git a/src/namestore/namestore_common.c b/src/namestore/namestore_common.c
index 95f6364..71e89f4 100644
--- a/src/namestore/namestore_common.c
+++ b/src/namestore/namestore_common.c
@@ -32,11 +32,13 @@
#include "gnunet_arm_service.h"
#include "gnunet_namestore_service.h"
#include "gnunet_dnsparser_lib.h"
+#include "gns_protocol.h"
#include "namestore.h"
#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
+GNUNET_NETWORK_STRUCT_BEGIN
/**
* Internal format of a record in the serialized form.
@@ -45,27 +47,45 @@ struct NetworkRecord
{
/**
- * Expiration time for the DNS record.
+ * Expiration time for the DNS record; relative or absolute depends
+ * on 'flags', network byte order.
*/
- struct GNUNET_TIME_AbsoluteNBO expiration;
+ uint64_t expiration_time GNUNET_PACKED;
/**
* Number of bytes in 'data', network byte order.
*/
- uint32_t data_size;
+ uint32_t data_size GNUNET_PACKED;
/**
* Type of the GNS/DNS record, network byte order.
*/
- uint32_t record_type;
+ uint32_t record_type GNUNET_PACKED;
/**
* Flags for the record, network byte order.
*/
- uint32_t flags;
+ uint32_t flags GNUNET_PACKED;
};
+GNUNET_NETWORK_STRUCT_END
+
+/**
+ * Convert a UTF-8 string to UTF-8 lowercase
+ * @param src source string
+ * @return converted result
+ */
+char *
+GNUNET_NAMESTORE_normalize_string (const char *src)
+{
+ GNUNET_assert (NULL != src);
+ char *res = strdup (src);
+ /* normalize */
+ GNUNET_STRINGS_utf8_tolower(src, &res);
+ return res;
+}
+
/**
* Convert a short hash to a string (for printing debug messages).
@@ -120,7 +140,7 @@ GNUNET_NAMESTORE_records_get_size (unsigned int rd_count,
* @param dest_size size of the destination array
* @param dest where to write the result
*
- * @return the size of serialized records
+ * @return the size of serialized records, -1 if records do not fit
*/
ssize_t
GNUNET_NAMESTORE_records_serialize (unsigned int rd_count,
@@ -135,7 +155,7 @@ GNUNET_NAMESTORE_records_serialize (unsigned int rd_count,
off = 0;
for (i=0;i<rd_count;i++)
{
- rec.expiration = GNUNET_TIME_absolute_hton (rd[i].expiration);
+ rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
rec.data_size = htonl ((uint32_t) rd[i].data_size);
rec.record_type = htonl (rd[i].record_type);
rec.flags = htonl (rd[i].flags);
@@ -151,25 +171,59 @@ GNUNET_NAMESTORE_records_serialize (unsigned int rd_count,
return off;
}
+
/**
- * Compares if two records are equal
+ * Compares if two records are equal (ignoring flags such
+ * as authority, private and pending, but not relative vs.
+ * absolute expiration time).
*
* @param a record
* @param b record
- *
- * @return GNUNET_YES or GNUNET_NO
+ * @return GNUNET_YES if the records are equal or GNUNET_NO if they are not
*/
int
GNUNET_NAMESTORE_records_cmp (const struct GNUNET_NAMESTORE_RecordData *a,
const struct GNUNET_NAMESTORE_RecordData *b)
{
- if ((a->record_type == b->record_type) &&
- (a->expiration.abs_value == b->expiration.abs_value) &&
- (a->data_size == b->data_size) &&
- (0 == memcmp (a->data, b->data, a->data_size)))
- return GNUNET_YES;
- else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Comparing records\n");
+ if (a->record_type != b->record_type)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Record type %lu != %lu\n", a->record_type, b->record_type);
+ return GNUNET_NO;
+ }
+ if ((a->expiration_time != b->expiration_time) &&
+ ((a->expiration_time != 0) && (b->expiration_time != 0)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Expiration time %llu != %llu\n", a->expiration_time, b->expiration_time);
+ return GNUNET_NO;
+ }
+ if ((a->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS)
+ != (b->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Flags %lu (%lu) != %lu (%lu)\n", a->flags,
+ a->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS, b->flags,
+ b->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS);
+ return GNUNET_NO;
+ }
+ if (a->data_size != b->data_size)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Data size %lu != %lu\n", a->data_size, b->data_size);
return GNUNET_NO;
+ }
+ if (0 != memcmp (a->data, b->data, a->data_size))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Data contents do not match\n");
+ return GNUNET_NO;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Records are equal\n");
+ return GNUNET_YES;
}
@@ -199,7 +253,7 @@ GNUNET_NAMESTORE_records_deserialize (size_t len,
if (off + sizeof (rec) > len)
return GNUNET_SYSERR;
memcpy (&rec, &src[off], sizeof (rec));
- dest[i].expiration = GNUNET_TIME_absolute_ntoh (rec.expiration);
+ dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
dest[i].data_size = ntohl ((uint32_t) rec.data_size);
dest[i].record_type = ntohl (rec.record_type);
dest[i].flags = ntohl (rec.flags);
@@ -213,6 +267,7 @@ GNUNET_NAMESTORE_records_deserialize (size_t len,
return GNUNET_OK;
}
+
/**
* Sign name and records
*
@@ -226,48 +281,49 @@ GNUNET_NAMESTORE_records_deserialize (size_t len,
*/
struct GNUNET_CRYPTO_RsaSignature *
GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
- struct GNUNET_TIME_Absolute expire,
- const char *name,
- const struct GNUNET_NAMESTORE_RecordData *rd,
- unsigned int rd_count)
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ unsigned int rd_count)
{
- struct GNUNET_CRYPTO_RsaSignature *sig = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignature));
+ struct GNUNET_CRYPTO_RsaSignature *sig;
struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose;
- struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton(expire);
+ struct GNUNET_TIME_AbsoluteNBO expire_nbo;
size_t rd_ser_len;
size_t name_len;
-
struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
char * name_tmp;
char * rd_tmp;
int res;
+ uint32_t sig_len;
- if (name == NULL)
+ if (NULL == name)
{
GNUNET_break (0);
- GNUNET_free (sig);
return NULL;
}
+ sig = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaSignature));
name_len = strlen (name) + 1;
-
- rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
- char rd_ser[rd_ser_len];
- GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
-
- sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len);
- sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len);
- sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
- expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
- name_tmp = (char *) &expire_tmp[1];
- rd_tmp = &name_tmp[name_len];
- memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
- memcpy (name_tmp, name, name_len);
- memcpy (rd_tmp, rd_ser, rd_ser_len);
-
- res = GNUNET_CRYPTO_rsa_sign (key, sig_purpose, sig);
-
- GNUNET_free (sig_purpose);
-
+ expire_nbo = GNUNET_TIME_absolute_hton (expire);
+ rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
+ {
+ char rd_ser[rd_ser_len];
+
+ GNUNET_assert (rd_ser_len ==
+ GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser));
+ sig_len = sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len;
+ sig_purpose = GNUNET_malloc (sig_len);
+ sig_purpose->size = htonl (sig_len);
+ sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+ expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
+ memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
+ name_tmp = (char *) &expire_tmp[1];
+ memcpy (name_tmp, name, name_len);
+ rd_tmp = &name_tmp[name_len];
+ memcpy (rd_tmp, rd_ser, rd_ser_len);
+ res = GNUNET_CRYPTO_rsa_sign (key, sig_purpose, sig);
+ GNUNET_free (sig_purpose);
+ }
if (GNUNET_OK != res)
{
GNUNET_break (0);
@@ -277,22 +333,6 @@ GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key
return sig;
}
-/**
- * Checks if a name is wellformed
- *
- * @param name the name to check
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-int
-GNUNET_NAMESTORE_check_name (const char * name)
-{
- if (name == NULL)
- return GNUNET_SYSERR;
- if (strlen (name) > 63)
- return GNUNET_SYSERR;
- return GNUNET_OK;
-}
-
/**
* Convert the 'value' of a record to a string.
@@ -307,18 +347,21 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
const void *data,
size_t data_size)
{
- char tmp[INET6_ADDRSTRLEN];
- struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
uint16_t mx_pref;
+ const struct soa_data *soa;
+ const struct vpn_data *vpn;
+ const struct srv_data *srv;
+ const struct tlsa_data *tlsa;
+ struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
+ struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
+ const char *cdata;
+ char* vpn_str;
+ char* srv_str;
+ char* tlsa_str;
char* result;
- char* soa_rname;
- char* soa_mname;
- uint32_t* soa_data;
- uint32_t soa_serial;
- uint32_t soa_refresh;
- uint32_t soa_retry;
- uint32_t soa_expire;
- uint32_t soa_min;
+ const char* soa_rname;
+ const char* soa_mname;
+ char tmp[INET6_ADDRSTRLEN];
switch (type)
{
@@ -335,20 +378,26 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
case GNUNET_DNSPARSER_TYPE_CNAME:
return GNUNET_strndup (data, data_size);
case GNUNET_DNSPARSER_TYPE_SOA:
- soa_rname = (char*)data;
- soa_mname = (char*)data+strlen(soa_rname)+1;
- soa_data = (uint32_t*)(soa_mname+strlen(soa_mname)+1);
- soa_serial = ntohl(soa_data[0]);
- soa_refresh = ntohl(soa_data[1]);
- soa_retry = ntohl(soa_data[2]);
- soa_expire = ntohl(soa_data[3]);
- soa_min = ntohl(soa_data[4]);
- if (GNUNET_asprintf(&result, "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu",
- soa_rname, soa_mname,
- soa_serial, soa_refresh, soa_retry, soa_expire, soa_min))
- return result;
- else
+ if (data_size <= sizeof (struct soa_data))
+ return NULL;
+ soa = data;
+ soa_rname = (const char*) &soa[1];
+ soa_mname = memchr (soa_rname, 0, data_size - sizeof (struct soa_data) - 1);
+ if (NULL == soa_mname)
return NULL;
+ soa_mname++;
+ if (NULL == memchr (soa_mname, 0,
+ data_size - (sizeof (struct soa_data) + strlen (soa_rname) + 1)))
+ return NULL;
+ GNUNET_asprintf (&result,
+ "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu",
+ soa_rname, soa_mname,
+ ntohl (soa->serial),
+ ntohl (soa->refresh),
+ ntohl (soa->retry),
+ ntohl (soa->expire),
+ ntohl (soa->minimum));
+ return result;
case GNUNET_DNSPARSER_TYPE_PTR:
return GNUNET_strndup (data, data_size);
case GNUNET_DNSPARSER_TYPE_MX:
@@ -357,7 +406,10 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
!= 0)
return result;
else
+ {
+ GNUNET_free (result);
return NULL;
+ }
case GNUNET_DNSPARSER_TYPE_TXT:
return GNUNET_strndup (data, data_size);
case GNUNET_DNSPARSER_TYPE_AAAA:
@@ -376,6 +428,57 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
return GNUNET_strndup (data, data_size);
case GNUNET_NAMESTORE_TYPE_LEHO:
return GNUNET_strndup (data, data_size);
+ case GNUNET_NAMESTORE_TYPE_VPN:
+ cdata = data;
+ if ( (data_size <= sizeof (struct vpn_data)) ||
+ ('\0' != cdata[data_size - 1]) )
+ return NULL; /* malformed */
+ vpn = data;
+ GNUNET_CRYPTO_hash_to_enc (&vpn->peer, &s_peer);
+ if (0 == GNUNET_asprintf (&vpn_str, "%u %s %s",
+ (unsigned int) ntohs (vpn->proto),
+ (const char*) &s_peer,
+ (const char*) &vpn[1]))
+ {
+ GNUNET_free (vpn_str);
+ return NULL;
+ }
+ return vpn_str;
+ case GNUNET_DNSPARSER_TYPE_SRV:
+ cdata = data;
+ if ( (data_size <= sizeof (struct srv_data)) ||
+ ('\0' != cdata[data_size - 1]) )
+ return NULL; /* malformed */
+ srv = data;
+
+ if (0 == GNUNET_asprintf (&srv_str,
+ "%d %d %d %s",
+ ntohs (srv->prio),
+ ntohs (srv->weight),
+ ntohs (srv->port),
+ (const char *)&srv[1]))
+ {
+ GNUNET_free (srv_str);
+ return NULL;
+ }
+ return srv_str;
+ case GNUNET_DNSPARSER_TYPE_TLSA:
+ cdata = data;
+ if ( (data_size <= sizeof (struct tlsa_data)) ||
+ ('\0' != cdata[data_size - 1]) )
+ return NULL; /* malformed */
+ tlsa = data;
+ if (0 == GNUNET_asprintf (&tlsa_str,
+ "%c %c %c %s",
+ tlsa->usage,
+ tlsa->selector,
+ tlsa->matching_type,
+ (const char *) &tlsa[1]))
+ {
+ GNUNET_free (tlsa_str);
+ return NULL;
+ }
+ return tlsa_str;
default:
GNUNET_break (0);
}
@@ -403,65 +506,84 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
struct in_addr value_a;
struct in6_addr value_aaaa;
struct GNUNET_CRYPTO_ShortHashCode pkey;
+ struct soa_data *soa;
+ struct vpn_data *vpn;
+ struct tlsa_data *tlsa;
+ char result[253 + 1];
+ char soa_rname[253 + 1];
+ char soa_mname[253 + 1];
+ char s_peer[103 + 1];
+ char s_serv[253 + 1];
+ unsigned int soa_serial;
+ unsigned int soa_refresh;
+ unsigned int soa_retry;
+ unsigned int soa_expire;
+ unsigned int soa_min;
uint16_t mx_pref;
uint16_t mx_pref_n;
- uint32_t soa_data[5];
- char result[253];
- char soa_rname[63];
- char soa_mname[63];
- uint32_t soa_serial;
- uint32_t soa_refresh;
- uint32_t soa_retry;
- uint32_t soa_expire;
- uint32_t soa_min;
+ unsigned int proto;
switch (type)
{
case 0:
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unsupported record type %d\n"),
+ (int) type);
return GNUNET_SYSERR;
case GNUNET_DNSPARSER_TYPE_A:
if (1 != inet_pton (AF_INET, s, &value_a))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse IPv4 address `%s'\n"),
+ s);
return GNUNET_SYSERR;
+ }
*data = GNUNET_malloc (sizeof (struct in_addr));
memcpy (*data, &value_a, sizeof (value_a));
*data_size = sizeof (value_a);
return GNUNET_OK;
case GNUNET_DNSPARSER_TYPE_NS:
*data = GNUNET_strdup (s);
- *data_size = strlen (s);
+ *data_size = strlen (s) + 1;
return GNUNET_OK;
case GNUNET_DNSPARSER_TYPE_CNAME:
*data = GNUNET_strdup (s);
- *data_size = strlen (s);
+ *data_size = strlen (s) + 1;
return GNUNET_OK;
case GNUNET_DNSPARSER_TYPE_SOA:
-
- if (SSCANF(s, "rname=%s mname=%s %u,%u,%u,%u,%u",
- soa_rname, soa_mname,
- &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min)
- != 7)
+ if (7 != SSCANF (s,
+ "rname=%253s mname=%253s %u,%u,%u,%u,%u",
+ soa_rname, soa_mname,
+ &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse SOA record `%s'\n"),
+ s);
return GNUNET_SYSERR;
-
- *data_size = sizeof (soa_data)+strlen(soa_rname)+strlen(soa_mname)+2;
+ }
+ *data_size = sizeof (struct soa_data)+strlen(soa_rname)+strlen(soa_mname)+2;
*data = GNUNET_malloc (*data_size);
- soa_data[0] = htonl(soa_serial);
- soa_data[1] = htonl(soa_refresh);
- soa_data[2] = htonl(soa_retry);
- soa_data[3] = htonl(soa_expire);
- soa_data[4] = htonl(soa_min);
- strcpy(*data, soa_rname);
- strcpy(*data+strlen(*data)+1, soa_mname);
- memcpy(*data+strlen(*data)+1+strlen(soa_mname)+1,
- soa_data, sizeof(soa_data));
+ soa = (struct soa_data*)*data;
+ soa->serial = htonl(soa_serial);
+ soa->refresh = htonl(soa_refresh);
+ soa->retry = htonl(soa_retry);
+ soa->expire = htonl(soa_expire);
+ soa->minimum = htonl(soa_min);
+ strcpy((char*)&soa[1], soa_rname);
+ strcpy((char*)&soa[1]+strlen(*data)+1, soa_mname);
return GNUNET_OK;
-
case GNUNET_DNSPARSER_TYPE_PTR:
*data = GNUNET_strdup (s);
*data_size = strlen (s);
return GNUNET_OK;
case GNUNET_DNSPARSER_TYPE_MX:
- if (SSCANF(s, "%hu,%s", &mx_pref, result) != 2)
+ if (2 != SSCANF(s, "%hu,%253s", &mx_pref, result))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse MX record `%s'\n"),
+ s);
return GNUNET_SYSERR;
+ }
*data_size = sizeof (uint16_t)+strlen(result)+1;
*data = GNUNET_malloc (*data_size);
mx_pref_n = htons(mx_pref);
@@ -474,7 +596,12 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
return GNUNET_OK;
case GNUNET_DNSPARSER_TYPE_AAAA:
if (1 != inet_pton (AF_INET6, s, &value_aaaa))
- return GNUNET_SYSERR;
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse IPv6 address `%s'\n"),
+ s);
+ return GNUNET_SYSERR;
+ }
*data = GNUNET_malloc (sizeof (struct in6_addr));
*data_size = sizeof (struct in6_addr);
memcpy (*data, &value_aaaa, sizeof (value_aaaa));
@@ -482,7 +609,12 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
case GNUNET_NAMESTORE_TYPE_PKEY:
if (GNUNET_OK !=
GNUNET_CRYPTO_short_hash_from_string (s, &pkey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse PKEY record `%s'\n"),
+ s);
return GNUNET_SYSERR;
+ }
*data = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode));
memcpy (*data, &pkey, sizeof (pkey));
*data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
@@ -495,10 +627,50 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
*data = GNUNET_strdup (s);
*data_size = strlen (s);
return GNUNET_OK;
+ case GNUNET_NAMESTORE_TYPE_VPN:
+ if (3 != SSCANF (s,"%u %103s %253s",
+ &proto, s_peer, s_serv))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse VPN record string `%s'\n"),
+ s);
+ return GNUNET_SYSERR;
+ }
+ *data_size = sizeof (struct vpn_data) + strlen (s_serv) + 1;
+ *data = vpn = GNUNET_malloc (*data_size);
+ if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer,
+ &vpn->peer))
+ {
+ GNUNET_free (vpn);
+ *data_size = 0;
+ return GNUNET_SYSERR;
+ }
+ vpn->proto = htons ((uint16_t) proto);
+ strcpy ((char*)&vpn[1], s_serv);
+ return GNUNET_OK;
+ case GNUNET_DNSPARSER_TYPE_TLSA:
+ *data_size = sizeof (struct tlsa_data) + strlen (s) - 6;
+ *data = tlsa = GNUNET_malloc (*data_size);
+ if (4 != SSCANF (s, "%c %c %c %s",
+ &tlsa->usage,
+ &tlsa->selector,
+ &tlsa->matching_type,
+ (char*)&tlsa[1]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse TLSA record string `%s'\n"),
+ s);
+ *data_size = 0;
+ GNUNET_free (tlsa);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
default:
- GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unsupported record type %d\n"),
+ (int) type);
+ return GNUNET_SYSERR;
}
- return GNUNET_SYSERR;
}
@@ -517,6 +689,8 @@ static struct {
{ "PKEY", GNUNET_NAMESTORE_TYPE_PKEY },
{ "PSEU", GNUNET_NAMESTORE_TYPE_PSEU },
{ "LEHO", GNUNET_NAMESTORE_TYPE_LEHO },
+ { "VPN", GNUNET_NAMESTORE_TYPE_VPN },
+ { "TLSA", GNUNET_DNSPARSER_TYPE_TLSA },
{ NULL, UINT32_MAX }
};
@@ -558,6 +732,22 @@ GNUNET_NAMESTORE_number_to_typename (uint32_t type)
return name_map[i].name;
}
+/**
+ * Test if a given record is expired.
+ *
+ * @return GNUNET_YES if the record is expired,
+ * GNUNET_NO if not
+ */
+int
+GNUNET_NAMESTORE_is_expired (const struct GNUNET_NAMESTORE_RecordData *rd)
+{
+ struct GNUNET_TIME_Absolute at;
+
+ if (0 != (rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
+ return GNUNET_NO;
+ at.abs_value = rd->expiration_time;
+ return (0 == GNUNET_TIME_absolute_get_remaining (at).rel_value) ? GNUNET_YES : GNUNET_NO;
+}
/* end of namestore_common.c */