-more debug messages
[oweals/gnunet.git] / src / namestore / namestore_common.c
index 24711ba470c8326ca45c677fe716a6d14e91a8c9..af7eee04c1cefde48e73d7e173f2659ef13f2bc9 100644 (file)
 #include "gnunet_arm_service.h"
 #include "gnunet_namestore_service.h"
 #include "gnunet_dnsparser_lib.h"
+#include "../dns/dnsparser.h"
 #include "namestore.h"
-#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING
+
 
 #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,30 @@ 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 short hash to a string (for printing debug messages).
@@ -135,7 +140,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 +156,28 @@ 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->expiration_time == b->expiration_time) &&
+      ((a->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION) 
+       == (b->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION) ) &&
       (a->data_size == b->data_size) &&
       (0 == memcmp (a->data, b->data, a->data_size)))
     return GNUNET_YES;
-  else
-    return GNUNET_NO;
+  return GNUNET_NO;
 }
 
 
@@ -199,7 +207,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 +221,7 @@ GNUNET_NAMESTORE_records_deserialize (size_t len,
   return GNUNET_OK; 
 }
 
+
 /**
  * Sign name and records
  *
@@ -226,48 +235,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);
@@ -309,6 +319,17 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
 {
   char tmp[INET6_ADDRSTRLEN];
   struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
+  uint16_t mx_pref;
+  char* result;
+  char* soa_rname;
+  char* soa_mname;
+  struct soa_data *soa;
+
+  struct vpn_data *vpn;
+  char* vpn_str;
+  char* srv_str;
+  struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
+  struct srv_data *srv;
 
   switch (type)
   {
@@ -325,17 +346,25 @@ 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 = (struct soa_data*)data;
+    soa_rname = (char*)&soa[1];
+    soa_mname = (char*)&soa[1]+strlen(soa_rname)+1;
+    if (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;
+    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:
@@ -352,6 +381,28 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
     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);
+  case GNUNET_NAMESTORE_TYPE_VPN:
+    vpn = (struct vpn_data*)data;
+
+    GNUNET_CRYPTO_hash_to_enc (&vpn->peer, &s_peer);
+    if (GNUNET_OK != GNUNET_asprintf (&vpn_str, "%d:%s:%s",
+                                      vpn->proto,
+                                      (char*)&s_peer,
+                                      (char*)&vpn[1]))
+      return NULL;
+    return vpn_str;
+  case GNUNET_DNSPARSER_TYPE_SRV:
+    srv = (struct srv_data*)data;
+
+    if (GNUNET_OK != GNUNET_asprintf (&srv_str, "%d:%d:%d:%s",
+                                      ntohs (srv->prio),
+                                      ntohs (srv->weight),
+                                      ntohs (srv->port),
+                                      (char*)&srv[1]))
+      return NULL;
+    return srv_str;
   default:
     GNUNET_break (0);
   }
@@ -379,7 +430,22 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
   struct in_addr value_a;
   struct in6_addr value_aaaa;
   struct GNUNET_CRYPTO_ShortHashCode pkey;
-
+  uint16_t mx_pref;
+  uint16_t mx_pref_n;
+  struct soa_data *soa;
+  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;
+  struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
+  char s_serv[253];
+  struct vpn_data* vpn;
+  uint16_t proto;
+  
   switch (type)
   {
   case 0:
@@ -400,17 +466,38 @@ 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 (struct soa_data)+strlen(soa_rname)+strlen(soa_mname)+2;
+    *data = GNUNET_malloc (*data_size);
+    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:
-    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);
@@ -434,6 +521,33 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
     *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;
+  case GNUNET_NAMESTORE_TYPE_VPN:
+    
+    
+    if (4 != SSCANF (s,"%hu:%s:%s",
+                     &proto, (char*)&s_peer, s_serv))
+    {
+      return GNUNET_SYSERR;
+    }
+    *data_size = sizeof (struct vpn_data) + strlen (s_serv) + 1;
+    
+    *data = GNUNET_malloc (*data_size);
+
+    vpn = (struct vpn_data*)*data;
+    
+    if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer, &vpn->peer))
+    {
+      GNUNET_free (*data);
+      return GNUNET_SYSERR;
+    }
+
+    vpn->proto = htons (proto);
+    strcpy ((char*)&vpn[1], s_serv);
+    return GNUNET_OK;
   default:
     GNUNET_break (0);
   }
@@ -455,6 +569,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 }
 };