-fix URIs
[oweals/gnunet.git] / src / hello / hello.c
index 9e246d47344e912ea1ac681aceabf99db44810e9..1f9ef0f7ec917af3ce45cf937437c3cfe52eb0d7 100644 (file)
@@ -22,6 +22,7 @@
  * @file hello/hello.c
  * @brief helper library for handling HELLOs
  * @author Christian Grothoff
+ * @author Matthias Wachs
  */
 #include "platform.h"
 #include "gnunet_hello_lib.h"
@@ -59,7 +60,7 @@ struct GNUNET_HELLO_Message
   /**
    * The public key of the peer.
    */
-  struct GNUNET_CRYPTO_EccPublicSignKey publicKey;
+  struct GNUNET_CRYPTO_EddsaPublicKey publicKey;
 
 };
 GNUNET_NETWORK_STRUCT_END
@@ -97,6 +98,17 @@ struct GNUNET_HELLO_ParseUriContext
    */
   int ret;
 
+  /**
+   * Counter
+   */
+  unsigned int counter_total;
+
+  /**
+   * Counter skipped addresses
+   */
+  unsigned int counter_added;
+
+
   /**
    * Function for finding transport plugins by name.
    */
@@ -166,7 +178,7 @@ GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address,
  */
 static size_t
 get_hello_address_size (const char *buf,
-                       size_t max, 
+                       size_t max,
                        uint16_t *ralen)
 {
   const char *pos;
@@ -183,7 +195,7 @@ get_hello_address_size (const char *buf,
     pos++;
     slen++;
   }
-  if (left == 0)
+  if (0 == left)
   {
     /* 0-termination not found */
     GNUNET_break_op (0);
@@ -218,7 +230,7 @@ get_hello_address_size (const char *buf,
  * @return the hello message
  */
 struct GNUNET_HELLO_Message *
-GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EccPublicSignKey *publicKey,
+GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *publicKey,
                      GNUNET_HELLO_GenerateAddressListCallback addrgen,
                      void *addrgen_cls,
                      int friend_only)
@@ -237,7 +249,7 @@ GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EccPublicSignKey *publicKey,
   used = 0;
   if (addrgen != NULL)
   {
-    while (0 != (ret = addrgen (addrgen_cls, max, &buffer[used])))
+    while (GNUNET_SYSERR != (ret = addrgen (addrgen_cls, max, &buffer[used])))
     {
       max -= ret;
       used += ret;
@@ -249,7 +261,7 @@ GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EccPublicSignKey *publicKey,
   hello->friend_only = htonl (friend_only);
 
   memcpy (&hello->publicKey, publicKey,
-          sizeof (struct GNUNET_CRYPTO_EccPublicSignKey));
+          sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
   memcpy (&hello[1], buffer, used);
   return hello;
 }
@@ -300,7 +312,7 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
   while (insize > 0)
   {
     esize = get_hello_address_size (inptr, insize, &alen);
-    if (esize == 0)
+    if (0 == esize)
     {
       GNUNET_break (0);
       GNUNET_free_non_null (ret);
@@ -312,6 +324,7 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
     address.address = &inptr[esize - alen];
     address.address_length = alen;
     address.transport_name = inptr;
+    address.local_info = GNUNET_HELLO_ADDRESS_INFO_NONE;
     iret = it (it_cls, &address, GNUNET_TIME_absolute_ntoh (expire));
     if (iret == GNUNET_SYSERR)
     {
@@ -394,13 +407,13 @@ copy_latest (void *cls, const struct GNUNET_HELLO_Address *address,
 }
 
 
-static size_t
+static ssize_t
 merge_addr (void *cls, size_t max, void *buf)
 {
   struct MergeContext *mc = cls;
 
   if (mc->h1 == NULL)
-    return 0;
+    return GNUNET_SYSERR; /* Stop iteration */
   mc->ret = 0;
   mc->max = max;
   mc->buf = buf;
@@ -432,11 +445,11 @@ GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1,
   int friend_only;
 
   if (h1->friend_only != h2->friend_only)
-       friend_only = GNUNET_YES; /* One of the HELLOs is friend only */
+    friend_only = GNUNET_YES; /* One of the HELLOs is friend only */
   else
-       friend_only = ntohl (h1->friend_only); /* Both HELLO's have the same type */
+    friend_only = ntohl (h1->friend_only); /* Both HELLO's have the same type */
 
-       return GNUNET_HELLO_create (&h1->publicKey, &merge_addr, &mc, friend_only);
+  return GNUNET_HELLO_create (&h1->publicKey, &merge_addr, &mc, friend_only);
 }
 
 
@@ -530,7 +543,7 @@ GNUNET_HELLO_size (const struct GNUNET_HELLO_Message *hello)
  */
 int
 GNUNET_HELLO_get_key (const struct GNUNET_HELLO_Message *hello,
-                      struct GNUNET_CRYPTO_EccPublicSignKey *publicKey)
+                      struct GNUNET_CRYPTO_EddsaPublicKey *publicKey)
 {
   uint16_t ret = ntohs (hello->header.size);
 
@@ -669,7 +682,7 @@ GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1,
 
   if (0 !=
       memcmp (&h1->publicKey, &h2->publicKey,
-              sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)))
+              sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
     return GNUNET_TIME_UNIT_ZERO_ABS;
   ec.expiration_limit = now;
   ec.result = GNUNET_TIME_UNIT_FOREVER_ABS;
@@ -684,12 +697,12 @@ GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1,
 
 
 static int
-find_min_expire (void *cls, const struct GNUNET_HELLO_Address *address,
+find_max_expire (void *cls, const struct GNUNET_HELLO_Address *address,
                  struct GNUNET_TIME_Absolute expiration)
 {
-  struct GNUNET_TIME_Absolute *min = cls;
+  struct GNUNET_TIME_Absolute *max = cls;
 
-  *min = GNUNET_TIME_absolute_min (*min, expiration);
+  *max = GNUNET_TIME_absolute_max (*max, expiration);
   return GNUNET_OK;
 }
 
@@ -706,7 +719,7 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg)
   struct GNUNET_TIME_Absolute ret;
 
   ret.abs_value_us = 0;
-  GNUNET_HELLO_iterate_addresses (msg, GNUNET_NO, &find_min_expire, &ret);
+  GNUNET_HELLO_iterate_addresses (msg, GNUNET_NO, &find_max_expire, &ret);
   return ret;
 }
 
@@ -716,9 +729,9 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg)
  * maybe differenciated into additional subcategories if applicable.
  * This module only deals with hello identifiers (MODULE = "hello").
  * <p>
- * 
+ *
  * The concrete URI format is:
- * 
+ *
  * "gnunet://hello/PEER[!YYYYMMDDHHMMSS!<TYPE>!<ADDRESS>]...".
  * These URIs can be used to add a peer record to peerinfo service.
  * PEER is the string representation of peer's public key.
@@ -726,29 +739,29 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg)
  * TYPE is a transport type.
  * ADDRESS is the address, its format depends upon the transport type.
  * The concrete transport types and corresponding address formats are:
- * 
+ *
  * <ul><li>
- * 
+ *
  * <TCP|UDP>!IPADDRESS
  * IPVDDRESS is either IPV4 .-delimited address in form of XXX.XXX.XXX.XXX:PPPPP
  * or IPV6 :-delimited address, but with '(' and ')' instead of '[' and ']' (RFC2396 advises against using square brackets in URIs):
  * (XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX):PPPPP
  * PPPPP is the port number. May be 0.
- * 
+ *
  * </li><li>
- * 
+ *
  * [add SMTP, HTTP and other addresses here]
- * 
+ *
  * </li></ul>
- * 
+ *
  * The encoding for hexadecimal values is defined in the crypto_hash.c
  * module in the gnunetutil library and discussed there.
- * 
+ *
  * Examples:
- * 
+ *
  * gnunet://hello/0430205UC7D56PTQK8NV05776671CNN44FK4TL6D0GQ35OMF8MEN4RNMKA5UF6AL3DQO8B1SC5AQF50SQ2MABIRU4HC8H2HAJKJ59JL1JVRJAK308F9GASRFLMGUBB5TQ5AKR94AS5T3MDG8B9O1EMPRKB0HVCG7T6QPP4CDJ913LAEHVJ2DI1TOBB15Q1JIT5ARBOD12U4SIGRFDV3Q7T66G4TBVSJJ90UQF1BG29TGJJKLGEIMSPHHKO544D6EALQ4F2K0416311JC22GVAD48R616I7VK03K7MP7N0RS2MBV1TE9JV8CK1LSQMR7KCDRTLDA6917UGA67DHTGHERIACCGQ54TGSR48RMSGS9BA5HLMOKASFC1I6V4TT09TUGCU8GNDHQF0JF3H7LPV59UL5I38QID040G000!20120302010059!TCP!192.168.0.1:2086!TCP!64.23.8.174:0
  * gnunet://hello/0430205UC7D56PTQK8NV05776671CNN44FK4TL6D0GQ35OMF8MEN4RNMKA5UF6AL3DQO8B1SC5AQF50SQ2MABIRU4HC8H2HAJKJ59JL1JVRJAK308F9GASRFLMGUBB5TQ5AKR94AS5T3MDG8B9O1EMPRKB0HVCG7T6QPP4CDJ913LAEHVJ2DI1TOBB15Q1JIT5ARBOD12U4SIGRFDV3Q7T66G4TBVSJJ90UQF1BG29TGJJKLGEIMSPHHKO544D6EALQ4F2K0416311JC22GVAD48R616I7VK03K7MP7N0RS2MBV1TE9JV8CK1LSQMR7KCDRTLDA6917UGA67DHTGHERIACCGQ54TGSR48RMSGS9BA5HLMOKASFC1I6V4TT09TUGCU8GNDHQF0JF3H7LPV59UL5I38QID040G000!20120302010059!TCP!(2001:db8:85a3:8d3:1319:8a2e:370:7348):2086
- * 
+ *
  * <p>
  */
 
@@ -871,7 +884,7 @@ GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello,
   struct GNUNET_HELLO_ComposeUriContext ctx;
   ctx.plugins_find = plugins_find;
 
-  char *pkey = GNUNET_CRYPTO_ecc_public_sign_key_to_string (&(hello->publicKey));
+  char *pkey = GNUNET_CRYPTO_eddsa_public_key_to_string (&(hello->publicKey));
 
   GNUNET_asprintf (&(ctx.uri),
                    "%s%s",
@@ -894,9 +907,9 @@ GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello,
  * @param cls the 'struct GNUNET_HELLO_AddressParsingContext'
  * @param max number of bytes available for HELLO construction
  * @param buffer where to copy the next address (in binary format)
- * @return number of bytes added to buffer
+ * @return number of bytes added to buffer, GNUNET_SYSERR on error
  */
-static size_t
+static ssize_t
 add_address_to_hello (void *cls, size_t max, void *buffer)
 {
   struct GNUNET_HELLO_ParseUriContext *ctx = cls;
@@ -913,15 +926,16 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
   void *addr;
   size_t addr_len;
   struct GNUNET_HELLO_Address haddr;
-  size_t ret;
+  ssize_t ret;
+
 
   if (NULL == ctx->pos)
-    return 0;
+    return GNUNET_SYSERR;
   if ('!' != ctx->pos[0])
   {
     ctx->ret = GNUNET_SYSERR;
     GNUNET_break (0);
-    return 0;
+    return GNUNET_SYSERR;
   }
   ctx->pos++;
 
@@ -942,7 +956,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   _("Failed to parse HELLO message: missing expiration time\n"));
       GNUNET_break (0);
-      return 0;
+      return GNUNET_SYSERR;
     }
 
     expiration_seconds = mktime (&expiration_time);
@@ -952,7 +966,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
                   _("Failed to parse HELLO message: invalid expiration time\n"));
       ctx->ret = GNUNET_SYSERR;
       GNUNET_break (0);
-      return 0;
+      return GNUNET_SYSERR;
     }
     expire.abs_value_us = expiration_seconds * 1000LL * 1000LL;
   }
@@ -962,7 +976,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
                 _("Failed to parse HELLO message: malformed\n"));
     ctx->ret = GNUNET_SYSERR;
     GNUNET_break (0);
-    return 0;
+    return GNUNET_SYSERR;
   }
   tname++;
   address = strchr (tname, (int) '!');
@@ -972,11 +986,12 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
                 _("Failed to parse HELLO message: missing transport plugin\n"));
     ctx->ret = GNUNET_SYSERR;
     GNUNET_break (0);
-    return 0;
+    return GNUNET_SYSERR;
   }
   address++;
   end = strchr (address, (int) '!');
   ctx->pos = end;
+  ctx->counter_total ++;
   plugin_name = GNUNET_strndup (tname, address - (tname+1));
   papi = ctx->plugins_find (plugin_name);
   if (NULL == papi)
@@ -985,16 +1000,15 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
      * Skip this part, advance to the next one and recurse.
      * But only if this is not the end of string.
      */
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Plugin `%s' not found\n"),
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Plugin `%s' not found, skipping address\n"),
                 plugin_name);
     GNUNET_free (plugin_name);
-    GNUNET_break (0);
     return 0;
   }
   if (NULL == papi->string_to_address)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                _("Plugin `%s' does not support URIs yet\n"),
                plugin_name);
     GNUNET_free (plugin_name);
@@ -1027,6 +1041,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
   haddr.address = addr;
   haddr.transport_name = plugin_name;
   ret = GNUNET_HELLO_add_address (&haddr, expire, buffer, max);
+  ctx->counter_added ++;
   GNUNET_free (addr);
   GNUNET_free (plugin_name);
   return ret;
@@ -1044,7 +1059,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
  */
 int
 GNUNET_HELLO_parse_uri (const char *uri,
-                        struct GNUNET_CRYPTO_EccPublicSignKey *pubkey,
+                        struct GNUNET_CRYPTO_EddsaPublicKey *pubkey,
                         struct GNUNET_HELLO_Message **hello,
                         GNUNET_HELLO_TransportPluginsFind plugins_find)
 {
@@ -1080,9 +1095,15 @@ GNUNET_HELLO_parse_uri (const char *uri,
 
   ctx.pos = exc;
   ctx.ret = GNUNET_OK;
+  ctx.counter_total = 0;
+  ctx.counter_added = 0;
   ctx.plugins_find = plugins_find;
   *hello = GNUNET_HELLO_create (pubkey, &add_address_to_hello, &ctx, friend_only);
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              _("HELLO URI contained %u addresses, added %u addresses\n"),
+              ctx.counter_total, ctx.counter_added);
+
   return ctx.ret;
 }