Fix W32 gauger C bindings - quote arguments
[oweals/gnunet.git] / src / hello / hello.c
index a0c26d1ab6906b0b6ac3ddee2e3f82452377ccfa..6529c933371028e350fd32b07e6514e3801ef485 100644 (file)
@@ -28,6 +28,8 @@
 #include "gnunet_protocols.h"
 #include "gnunet_util_lib.h"
 
+GNUNET_NETWORK_STRUCT_BEGIN
+
 /**
  * A HELLO message is used to exchange information about
  * transports with other peers.  This struct is always
@@ -59,44 +61,41 @@ struct GNUNET_HELLO_Message
   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
 
 };
-
+GNUNET_NETWORK_STRUCT_END
 
 /**
  * Copy the given address information into
  * the given buffer using the format of HELLOs.
  *
- * @param tname name of the transport plugin
+ * @param address the address
  * @param expiration expiration for the address
- * @param addr the address
- * @param addr_len length of the address in bytes
  * @param target where to copy the address
  * @param max maximum number of bytes to copy to target
  * @return number of bytes copied, 0 if
  *         the target buffer was not big enough.
  */
 size_t
-GNUNET_HELLO_add_address (const char *tname,
-                          struct GNUNET_TIME_Absolute expiration,
-                          const void *addr, uint16_t addr_len, char *target,
+GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address,
+                          struct GNUNET_TIME_Absolute expiration, char *target,
                           size_t max)
 {
   uint16_t alen;
   size_t slen;
   struct GNUNET_TIME_AbsoluteNBO exp;
 
-  slen = strlen (tname) + 1;
+  slen = strlen (address->transport_name) + 1;
   if (slen + sizeof (uint16_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO) +
-      addr_len > max)
+      address->address_length > max)
     return 0;
   exp = GNUNET_TIME_absolute_hton (expiration);
-  alen = htons (addr_len);
-  memcpy (target, tname, slen);
+  alen = htons ((uint16_t) address->address_length);
+  memcpy (target, address->transport_name, slen);
   memcpy (&target[slen], &alen, sizeof (uint16_t));
   slen += sizeof (uint16_t);
   memcpy (&target[slen], &exp, sizeof (struct GNUNET_TIME_AbsoluteNBO));
   slen += sizeof (struct GNUNET_TIME_AbsoluteNBO);
-  memcpy (&target[slen], addr, addr_len);
-  slen += addr_len;
+  memcpy (&target[slen], address->address, address->address_length);
+  slen += address->address_length;
   return slen;
 }
 
@@ -130,7 +129,6 @@ get_hello_address_size (const char *buf, size_t max, uint16_t * ralen)
   {
     /* 0-termination not found */
     GNUNET_break_op (0);
-    abort ();
     return 0;
   }
   pos++;
@@ -208,6 +206,7 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
                                 int return_modified,
                                 GNUNET_HELLO_AddressIterator it, void *it_cls)
 {
+  struct GNUNET_HELLO_Address address;
   uint16_t msize;
   struct GNUNET_HELLO_Message *ret;
   const char *inptr;
@@ -233,6 +232,9 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
   insize = msize - sizeof (struct GNUNET_HELLO_Message);
   wpos = 0;
   woff = (ret != NULL) ? (char *) &ret[1] : NULL;
+  GNUNET_CRYPTO_hash (&msg->publicKey,
+                      sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+                      &address.peer.hashPubKey);
   while (insize > 0)
   {
     esize = get_hello_address_size (inptr, insize, &alen);
@@ -245,9 +247,10 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
     memcpy (&expire,
             &inptr[esize - alen - sizeof (struct GNUNET_TIME_AbsoluteNBO)],
             sizeof (struct GNUNET_TIME_AbsoluteNBO));
-    iret =
-        it (it_cls, inptr, GNUNET_TIME_absolute_ntoh (expire),
-            &inptr[esize - alen], alen);
+    address.address = &inptr[esize - alen];
+    address.address_length = alen;
+    address.transport_name = inptr;
+    iret = it (it_cls, &address, GNUNET_TIME_absolute_ntoh (expire));
     if (iret == GNUNET_SYSERR)
     {
       if (ret != NULL)
@@ -271,23 +274,19 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg,
 
 struct ExpireContext
 {
-  const void *addr;
-  const char *tname;
-  uint16_t addrlen;
+  const struct GNUNET_HELLO_Address *address;
   int found;
   struct GNUNET_TIME_Absolute expiration;
 };
 
 
 static int
-get_match_exp (void *cls, const char *tname,
-               struct GNUNET_TIME_Absolute expiration, const void *addr,
-               uint16_t addrlen)
+get_match_exp (void *cls, const struct GNUNET_HELLO_Address *address,
+               struct GNUNET_TIME_Absolute expiration)
 {
   struct ExpireContext *ec = cls;
 
-  if ((addrlen == ec->addrlen) && (0 == memcmp (addr, ec->addr, addrlen)) &&
-      (0 == strcmp (tname, ec->tname)))
+  if (0 == GNUNET_HELLO_address_cmp (address, ec->address))
   {
     ec->found = GNUNET_YES;
     ec->expiration = expiration;
@@ -311,17 +310,14 @@ struct MergeContext
 
 
 static int
-copy_latest (void *cls, const char *tname,
-             struct GNUNET_TIME_Absolute expiration, const void *addr,
-             uint16_t addrlen)
+copy_latest (void *cls, const struct GNUNET_HELLO_Address *address,
+             struct GNUNET_TIME_Absolute expiration)
 {
   struct MergeContext *mc = cls;
   struct ExpireContext ec;
 
-  ec.addr = addr;
-  ec.addrlen = addrlen;
+  ec.address = address;
   ec.found = GNUNET_NO;
-  ec.tname = tname;
   GNUNET_HELLO_iterate_addresses (mc->other, GNUNET_NO, &get_match_exp, &ec);
   if ((ec.found == GNUNET_NO) ||
       (ec.expiration.abs_value < expiration.abs_value) ||
@@ -329,8 +325,8 @@ copy_latest (void *cls, const char *tname,
        (mc->take_equal == GNUNET_YES)))
   {
     mc->ret +=
-        GNUNET_HELLO_add_address (tname, expiration, addr, addrlen,
-                                  &mc->buf[mc->ret], mc->max - mc->ret);
+        GNUNET_HELLO_add_address (address, expiration, &mc->buf[mc->ret],
+                                  mc->max - mc->ret);
   }
   return GNUNET_OK;
 }
@@ -389,25 +385,22 @@ struct DeltaContext
 
 
 static int
-delta_match (void *cls, const char *tname,
-             struct GNUNET_TIME_Absolute expiration, const void *addr,
-             uint16_t addrlen)
+delta_match (void *cls, const struct GNUNET_HELLO_Address *address,
+             struct GNUNET_TIME_Absolute expiration)
 {
   struct DeltaContext *dc = cls;
   int ret;
   struct ExpireContext ec;
 
-  ec.addr = addr;
-  ec.addrlen = addrlen;
+  ec.address = address;
   ec.found = GNUNET_NO;
-  ec.tname = tname;
   GNUNET_HELLO_iterate_addresses (dc->old_hello, GNUNET_NO, &get_match_exp,
                                   &ec);
   if ((ec.found == GNUNET_YES) &&
       ((ec.expiration.abs_value > expiration.abs_value) ||
        (ec.expiration.abs_value >= dc->expiration_limit.abs_value)))
     return GNUNET_YES;          /* skip */
-  ret = dc->it (dc->it_cls, tname, expiration, addr, addrlen);
+  ret = dc->it (dc->it_cls, address, expiration);
   return ret;
 }
 
@@ -533,30 +526,24 @@ struct EqualsContext
 
   const struct GNUNET_HELLO_Message *h2;
 
-  const char *tname;
-
-  const void *addr;
+  const struct GNUNET_HELLO_Address *address;
 
   struct GNUNET_TIME_Absolute expiration;
 
   int found;
 
-  uint16_t addrlen;
-
 };
 
 
 static int
-find_other_matching (void *cls, const char *tname,
-                     struct GNUNET_TIME_Absolute expiration, const void *addr,
-                     uint16_t addrlen)
+find_other_matching (void *cls, const struct GNUNET_HELLO_Address *address,
+                     struct GNUNET_TIME_Absolute expiration)
 {
   struct EqualsContext *ec = cls;
 
   if (expiration.abs_value < ec->expiration_limit.abs_value)
     return GNUNET_YES;
-  if ((addrlen == ec->addrlen) && (0 == strcmp (tname, ec->tname)) &&
-      (0 == memcmp (addr, ec->addr, addrlen)))
+  if (0 == GNUNET_HELLO_address_cmp (address, ec->address))
   {
     ec->found = GNUNET_YES;
     if (expiration.abs_value < ec->expiration.abs_value)
@@ -568,18 +555,15 @@ find_other_matching (void *cls, const char *tname,
 
 
 static int
-find_matching (void *cls, const char *tname,
-               struct GNUNET_TIME_Absolute expiration, const void *addr,
-               uint16_t addrlen)
+find_matching (void *cls, const struct GNUNET_HELLO_Address *address,
+               struct GNUNET_TIME_Absolute expiration)
 {
   struct EqualsContext *ec = cls;
 
   if (expiration.abs_value < ec->expiration_limit.abs_value)
     return GNUNET_YES;
-  ec->tname = tname;
+  ec->address = address;
   ec->expiration = expiration;
-  ec->addr = addr;
-  ec->addrlen = addrlen;
   ec->found = GNUNET_NO;
   GNUNET_HELLO_iterate_addresses (ec->h2, GNUNET_NO, &find_other_matching, ec);
   if (ec->found == GNUNET_NO)
@@ -631,9 +615,8 @@ GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1,
 
 
 static int
-find_min_expire (void *cls, const char *tname,
-                 struct GNUNET_TIME_Absolute expiration, const void *addr,
-                 uint16_t addrlen)
+find_min_expire (void *cls, const struct GNUNET_HELLO_Address *address,
+                 struct GNUNET_TIME_Absolute expiration)
 {
   struct GNUNET_TIME_Absolute *min = cls;
 
@@ -658,5 +641,46 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg)
   return ret;
 }
 
+/**
+ * GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER".
+ * The specific structure of "IDENTIFIER" depends on the module and
+ * 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[!YYYYMMDDHHNNSS!<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.
+ * YYYYMMDDHHNNSS is the expiration date.
+ * 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>
+ */
 
 /* end of hello.c */