-consistently use struct GNUNET_HashCode
[oweals/gnunet.git] / src / namestore / namestore_common.c
index 22368d478dd59b9650823594e6e390afc0dada8c..95f6364a12f17205d4a65b3ee68af437061851b1 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2009, 2010 Christian Grothoff (and other contributing authors)
+     (C) 2009, 2010, 2012 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -33,7 +33,7 @@
 #include "gnunet_namestore_service.h"
 #include "gnunet_dnsparser_lib.h"
 #include "namestore.h"
-#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING
+
 
 #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
 
@@ -66,6 +66,25 @@ struct NetworkRecord
   
 };
 
+
+/**
+ * Convert a short hash to a string (for printing debug messages).
+ * This is one of the very few calls in the entire API that is
+ * NOT reentrant!
+ *
+ * @param hc the short hash code
+ * @return string form; will be overwritten by next call to GNUNET_h2s.
+ */
+const char *
+GNUNET_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc)
+{
+  static struct GNUNET_CRYPTO_ShortHashAsciiEncoded ret;
+
+  GNUNET_CRYPTO_short_hash_to_enc (hc, &ret);
+  return (const char *) &ret;
+}
+
+
 /**
  * Calculate how many bytes we will need to serialize the given
  * records.
@@ -86,7 +105,7 @@ GNUNET_NAMESTORE_records_get_size (unsigned int rd_count,
   ret = sizeof (struct NetworkRecord) * rd_count;
   for (i=0;i<rd_count;i++)
   {
-    GNUNET_assert (ret + rd[i].data_size >= ret);
+    GNUNET_assert ((ret + rd[i].data_size) >= ret);
     ret += rd[i].data_size;
   }
   return ret;  
@@ -198,6 +217,7 @@ GNUNET_NAMESTORE_records_deserialize (size_t len,
  * Sign name and records
  *
  * @param key the private key
+ * @param expire block expiration
  * @param name the name
  * @param rd record data
  * @param rd_count number of records
@@ -206,14 +226,18 @@ 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_CRYPTO_RsaSignature *sig = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignature));
   struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose;
+  struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton(expire);
   size_t rd_ser_len;
   size_t name_len;
+
+  struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
   char * name_tmp;
   char * rd_tmp;
   int res;
@@ -230,12 +254,13 @@ GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key
   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) + rd_ser_len + name_len);
-
+  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);
-  name_tmp = (char *) &sig_purpose[1];
+  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);
 
@@ -252,6 +277,22 @@ 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.
@@ -267,6 +308,17 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
                                  size_t data_size)
 {
   char tmp[INET6_ADDRSTRLEN];
+  struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
+  uint16_t mx_pref;
+  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;
 
   switch (type)
   {
@@ -283,17 +335,29 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
   case GNUNET_DNSPARSER_TYPE_CNAME:
     return GNUNET_strndup (data, data_size);
   case GNUNET_DNSPARSER_TYPE_SOA:
-    GNUNET_break (0);
-    // FIXME
-    return NULL;
+    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
+      return NULL;
   case GNUNET_DNSPARSER_TYPE_PTR:
-    GNUNET_break (0);
-    // FIXME
-    return NULL;
+    return GNUNET_strndup (data, data_size);
   case GNUNET_DNSPARSER_TYPE_MX:
-    GNUNET_break (0);
-    // FIXME
-    return NULL;
+    mx_pref = ntohs(*((uint16_t*)data));
+    if (GNUNET_asprintf(&result, "%hu,%s", mx_pref, data+sizeof(uint16_t))
+        != 0)
+      return result;
+    else
+      return NULL;
   case GNUNET_DNSPARSER_TYPE_TXT:
     return GNUNET_strndup (data, data_size);
   case GNUNET_DNSPARSER_TYPE_AAAA:
@@ -303,11 +367,15 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
       return NULL;
     return GNUNET_strdup (tmp);
   case GNUNET_NAMESTORE_TYPE_PKEY:
-    if (data_size != sizeof (GNUNET_HashCode))
+    if (data_size != sizeof (struct GNUNET_CRYPTO_ShortHashCode))
       return NULL;
-    return GNUNET_strdup (GNUNET_h2s_full (data));
+    GNUNET_CRYPTO_short_hash_to_enc (data,
+                                    &enc);
+    return GNUNET_strdup ((const char*) enc.short_encoding);
   case GNUNET_NAMESTORE_TYPE_PSEU:
     return GNUNET_strndup (data, data_size);
+  case GNUNET_NAMESTORE_TYPE_LEHO:
+    return GNUNET_strndup (data, data_size);
   default:
     GNUNET_break (0);
   }
@@ -334,8 +402,19 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
 {
   struct in_addr value_a;
   struct in6_addr value_aaaa;
-  GNUNET_HashCode pkey;
-
+  struct GNUNET_CRYPTO_ShortHashCode pkey;
+  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;
+  
   switch (type)
   {
   case 0:
@@ -356,17 +435,39 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
     *data_size = strlen (s);
     return GNUNET_OK;
   case GNUNET_DNSPARSER_TYPE_SOA:
-    GNUNET_break (0);
-    // FIXME
-    return GNUNET_SYSERR;
+    
+    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)
+      return GNUNET_SYSERR;
+    
+    *data_size = sizeof (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));
+    return GNUNET_OK;
+
   case GNUNET_DNSPARSER_TYPE_PTR:
-    GNUNET_break (0);
-    // FIXME
-    return GNUNET_SYSERR;
+    *data = GNUNET_strdup (s);
+    *data_size = strlen (s);
+    return GNUNET_OK;
   case GNUNET_DNSPARSER_TYPE_MX:
-    GNUNET_break (0);
-    // FIXME
-    return GNUNET_SYSERR;
+    if (SSCANF(s, "%hu,%s", &mx_pref, result) != 2)
+      return GNUNET_SYSERR;
+    *data_size = sizeof (uint16_t)+strlen(result)+1;
+    *data = GNUNET_malloc (*data_size);
+    mx_pref_n = htons(mx_pref);
+    memcpy(*data, &mx_pref_n, sizeof (uint16_t));
+    strcpy((*data)+sizeof (uint16_t), result);
+    return GNUNET_OK;
   case GNUNET_DNSPARSER_TYPE_TXT:
     *data = GNUNET_strdup (s);
     *data_size = strlen (s);
@@ -375,19 +476,25 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
     if (1 != inet_pton (AF_INET6, s, &value_aaaa))    
       return GNUNET_SYSERR;    
     *data = GNUNET_malloc (sizeof (struct in6_addr));
+    *data_size = sizeof (struct in6_addr);
     memcpy (*data, &value_aaaa, sizeof (value_aaaa));
     return GNUNET_OK;
   case GNUNET_NAMESTORE_TYPE_PKEY:
     if (GNUNET_OK !=
-       GNUNET_CRYPTO_hash_from_string (s, &pkey))
+       GNUNET_CRYPTO_short_hash_from_string (s, &pkey))
       return GNUNET_SYSERR;
-    *data = GNUNET_malloc (sizeof (GNUNET_HashCode));
+    *data = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode));
     memcpy (*data, &pkey, sizeof (pkey));
+    *data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
     return GNUNET_OK;
   case GNUNET_NAMESTORE_TYPE_PSEU:
     *data = GNUNET_strdup (s);
     *data_size = strlen (s);
     return GNUNET_OK;
+  case GNUNET_NAMESTORE_TYPE_LEHO:
+    *data = GNUNET_strdup (s);
+    *data_size = strlen (s);
+    return GNUNET_OK;
   default:
     GNUNET_break (0);
   }
@@ -409,6 +516,7 @@ static struct {
   { "AAAA", GNUNET_DNSPARSER_TYPE_AAAA },
   { "PKEY",  GNUNET_NAMESTORE_TYPE_PKEY },
   { "PSEU",  GNUNET_NAMESTORE_TYPE_PSEU },
+  { "LEHO",  GNUNET_NAMESTORE_TYPE_LEHO },
   { NULL, UINT32_MAX }
 };