- implementation for mantis 0002485
[oweals/gnunet.git] / src / transport / plugin_transport_wlan.c
index 1420950358c80bd749162085354ecb460f0d7fcd..c2565a4a8fb9f198de1c3343266d03008b54525a 100644 (file)
@@ -23,9 +23,6 @@
  * @brief transport plugin for wlan
  * @author David Brodski
  * @author Christian Grothoff
- *
- * TODO:
- * - HELPER-continuation may be called after fragment times out (-> use after free, see FIXME)
  */
 #include "platform.h"
 #include "gnunet_hello_lib.h"
@@ -40,8 +37,6 @@
 #include "gnunet_fragmentation_lib.h"
 #include "gnunet_constants.h"
 
-#define PROTOCOL_PREFIX "wlan"
-
 #define LOG(kind,...) GNUNET_log_from (kind, "transport-wlan",__VA_ARGS__)
 
 /**
@@ -157,6 +152,11 @@ struct PendingMessage
  */
 struct Session
 {
+  /**
+   * To whom are we talking to (set to our identity
+   * if we are still waiting for the welcome message)
+   */
+  struct GNUNET_PeerIdentity target;
 
   /**
    * API requirement (must be first).
@@ -190,12 +190,6 @@ struct Session
    */
   struct PendingMessage *pending_message_tail;
 
-  /**
-   * To whom are we talking to (set to our identity
-   * if we are still waiting for the welcome message)
-   */
-  struct GNUNET_PeerIdentity target;
-
   /**
    * When should this session time out?
    */
@@ -501,6 +495,7 @@ get_radiotap_header (struct MacEndpoint *endpoint,
 /**
  * Generate the WLAN hardware header for one packet
  *
+ * @param plugin the plugin handle
  * @param header address to write the header to
  * @param to_mac_addr address of the recipient
  * @param size size of the whole packet, needed to calculate the time to send the packet
@@ -838,6 +833,8 @@ send_with_fragmentation (struct MacEndpoint *endpoint,
   fm->macendpoint = endpoint;
   fm->target = *target;
   fm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
+  fm->cont = cont;
+  fm->cont_cls = cont_cls;
   fm->fragcontext =
     GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU,
                                    &plugin->tracker,
@@ -874,6 +871,13 @@ free_macendpoint (struct MacEndpoint *endpoint)
   GNUNET_CONTAINER_DLL_remove (plugin->mac_head, 
                               plugin->mac_tail, 
                               endpoint);
+
+  if (NULL != endpoint->defrag)
+  {
+    GNUNET_DEFRAGMENT_context_destroy(endpoint->defrag);
+    endpoint->defrag = NULL;
+  }
+
   plugin->mac_count--;
   if (GNUNET_SCHEDULER_NO_TASK != endpoint->timeout_task)
   {
@@ -1076,7 +1080,7 @@ wlan_plugin_send (void *cls,
  * @param client pointer to the session this message belongs to
  * @param hdr start of the message
  */
-static void
+static int
 process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
 {
   struct Plugin *plugin = cls;
@@ -1240,6 +1244,7 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
                          (mas->endpoint == NULL) ? 0 : sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
     break;
   }
+  return GNUNET_OK;
 }
 #undef NUM_ATS
 
@@ -1251,7 +1256,7 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
  * @param client client that send the data (not used)
  * @param hdr header of the GNUNET_MessageHeader
  */
-static void
+static int
 handle_helper_message (void *cls, void *client,
                       const struct GNUNET_MessageHeader *hdr)
 {
@@ -1353,6 +1358,7 @@ handle_helper_message (void *cls, void *client,
         ntohs (hdr->type), ntohs (hdr->size));
     break;
   }
+  return GNUNET_OK;
 }
 
 
@@ -1461,7 +1467,6 @@ wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
 static const char *
 wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
 {
-  static char ret[40];
   const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac;
 
   if (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress) != addrlen)
@@ -1470,10 +1475,7 @@ wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
     return NULL;
   }
   mac = addr;
-  GNUNET_snprintf (ret, sizeof (ret), "%s MAC address %s",
-                   PROTOCOL_PREFIX, 
-                  mac_to_string (mac));
-  return ret;
+  return GNUNET_strdup (mac_to_string (mac));
 }
 
 
@@ -1510,10 +1512,7 @@ wlan_plugin_address_pretty_printer (void *cls, const char *type,
     return;
   }
   mac = addr;
-  GNUNET_asprintf (&ret,
-                   "%s MAC address %s",
-                   PROTOCOL_PREFIX, 
-                  mac_to_string (mac));
+  ret = GNUNET_strdup (mac_to_string (mac));
   asc (asc_cls, ret);
   GNUNET_free (ret);
   asc (asc_cls, NULL);
@@ -1576,6 +1575,57 @@ libgnunet_plugin_transport_wlan_done (void *cls)
 }
 
 
+/**
+ * Function called to convert a string address to
+ * a binary address.
+ *
+ * @param cls closure ('struct Plugin*')
+ * @param addr string address
+ * @param addrlen length of the address
+ * @param buf location to store the buffer
+ * @param added location to store the number of bytes in the buffer.
+ *        If the function returns GNUNET_SYSERR, its contents are undefined.
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+static int
+wlan_string_to_address (void *cls, const char *addr, uint16_t addrlen,
+                       void **buf, size_t *added)
+{
+  struct GNUNET_TRANSPORT_WLAN_MacAddress *mac;
+  unsigned int a[6];
+  unsigned int i;
+
+  if ((NULL == addr) || (addrlen == 0))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if ('\0' != addr[addrlen - 1])
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if (strlen (addr) != addrlen - 1)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if (6 != SSCANF (addr,
+                  "%X:%X:%X:%X:%X:%X", 
+                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  mac = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
+  for (i=0;i<6;i++)
+    mac->mac[i] = a[i];
+  *buf = mac;
+  *added = sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress);
+  return GNUNET_OK;
+}
+
+
 /**
  * Entry point for the plugin.
  *
@@ -1600,10 +1650,11 @@ libgnunet_plugin_transport_wlan_init (void *cls)
     api->cls = NULL;
     api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
     api->address_to_string = &wlan_plugin_address_to_string;
-    api->string_to_address = NULL; // FIXME!
+    api->string_to_address = &wlan_string_to_address;
     return api;
   }
 
+  testmode = 0;
   /* check configuration */
   if ( (GNUNET_YES == 
        GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "TESTMODE")) &&
@@ -1651,10 +1702,8 @@ libgnunet_plugin_transport_wlan_init (void *cls)
   plugin->fragment_data_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin);
   plugin->wlan_header_payload_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin);
   plugin->helper_payload_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin);
-#if BEACON
   plugin->beacon_task = GNUNET_SCHEDULER_add_now (&send_hello_beacon, 
                                                  plugin);
-#endif
   switch (testmode)
   {
   case 0: /* normal */ 
@@ -1696,6 +1745,7 @@ libgnunet_plugin_transport_wlan_init (void *cls)
   api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
   api->check_address = &wlan_plugin_address_suggested;
   api->address_to_string = &wlan_plugin_address_to_string;
+  api->string_to_address = &wlan_string_to_address;
   return api;
 }