new operation queue for limiting overlay connects
[oweals/gnunet.git] / src / transport / plugin_transport_wlan.c
index d89b72ba61dd92365d0e1bbbe4644ac96f23c60d..ab0309cedcbc5710f58df84973e9f843b79e1bbb 100644 (file)
@@ -152,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).
@@ -185,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?
    */
@@ -261,6 +260,16 @@ struct FragmentMessage
    */
   void *cont_cls;
 
+  /**
+   * Size of original message
+   */
+  size_t size_payload;
+
+  /**
+   * Number of bytes used to transmit message
+   */
+  size_t size_on_wire;
+
 };
 
 
@@ -707,6 +716,7 @@ fragment_transmission_done (void *cls,
 {
   struct FragmentMessage *fm = cls;
 
+
   fm->sh = NULL;
   GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext);
 }
@@ -745,11 +755,18 @@ transmit_fragment (void *cls,
                                 &radio_header->header,
                                 GNUNET_NO,
                                 &fragment_transmission_done, fm);
+    fm->size_on_wire += size;
     if (NULL != fm->sh)
       GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN message fragments sent"),
                                1, GNUNET_NO);
     else
       GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext);
+    GNUNET_STATISTICS_update (endpoint->plugin->env->stats,
+                              "# bytes currently in WLAN buffers",
+                              -msize, GNUNET_NO);
+    GNUNET_STATISTICS_update (endpoint->plugin->env->stats,
+                              "# bytes transmitted via WLAN",
+                              msize, GNUNET_NO);
   }
 }
 
@@ -798,7 +815,7 @@ fragmentmessage_timeout (void *cls,
   fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   if (NULL != fm->cont)
   {
-    fm->cont (fm->cont_cls, &fm->target, GNUNET_SYSERR);
+    fm->cont (fm->cont_cls, &fm->target, GNUNET_SYSERR, fm->size_payload, fm->size_on_wire);
     fm->cont = NULL;
   }
   free_fragment_message (fm);
@@ -812,6 +829,7 @@ fragmentmessage_timeout (void *cls,
  * @param timeout how long can the message wait?
  * @param target peer that should receive the message
  * @param msg message to transmit
+ * @param payload_size bytes of payload
  * @param cont continuation to call once the message has
  *        been transmitted (or if the transport is ready
  *        for the next transmission call; or if the
@@ -823,6 +841,7 @@ send_with_fragmentation (struct MacEndpoint *endpoint,
                         struct GNUNET_TIME_Relative timeout,
                         const struct GNUNET_PeerIdentity *target,                       
                         const struct GNUNET_MessageHeader *msg,
+                        size_t payload_size,
                         GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 
 {
@@ -833,6 +852,8 @@ send_with_fragmentation (struct MacEndpoint *endpoint,
   fm = GNUNET_malloc (sizeof (struct FragmentMessage));
   fm->macendpoint = endpoint;
   fm->target = *target;
+  fm->size_payload = payload_size;
+  fm->size_on_wire = 0;
   fm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
   fm->cont = cont;
   fm->cont_cls = cont_cls;
@@ -872,6 +893,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)
   {
@@ -1057,10 +1085,16 @@ wlan_plugin_send (void *cls,
   wlanheader->target = session->target;
   wlanheader->crc = htonl (GNUNET_CRYPTO_crc32_n (msgbuf, msgbuf_size));
   memcpy (&wlanheader[1], msgbuf, msgbuf_size);
+
+  GNUNET_STATISTICS_update (plugin->env->stats,
+                            "# bytes currently in WLAN buffers",
+                            msgbuf_size, GNUNET_NO);
+
   send_with_fragmentation (session->mac,
                           to,
                           &session->target,
                           &wlanheader->header,
+                          msgbuf_size,
                           cont, cont_cls);
   return size;
 }
@@ -1074,7 +1108,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;
@@ -1093,6 +1127,11 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
   ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
   ats[1].value = htonl (GNUNET_ATS_NET_WLAN);
   msize = ntohs (hdr->size);
+
+  GNUNET_STATISTICS_update (plugin->env->stats,
+                            "# bytes received via WLAN",
+                            msize, GNUNET_NO);
+
   switch (ntohs (hdr->type))
   {
   case GNUNET_MESSAGE_TYPE_HELLO:
@@ -1154,7 +1193,7 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
        mas->endpoint->timeout = GNUNET_TIME_relative_to_absolute (MACENDPOINT_TIMEOUT);
        if (NULL != fm->cont)
        {
-         fm->cont (fm->cont_cls, &fm->target, GNUNET_OK);
+         fm->cont (fm->cont_cls, &fm->target, GNUNET_OK, fm->size_payload, fm->size_on_wire);
          fm->cont = NULL;
        }
         free_fragment_message (fm);
@@ -1238,6 +1277,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
 
@@ -1249,7 +1289,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)
 {
@@ -1278,7 +1318,8 @@ handle_helper_message (void *cls, void *client,
       /* remove old address */
       plugin->env->notify_address (plugin->env->cls, GNUNET_NO,
                                   &plugin->mac_address,
-                                  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));      
+                                  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress),
+                                  "wlan");
     }
     plugin->mac_address = cm->mac;
     plugin->have_mac = GNUNET_YES;
@@ -1288,7 +1329,8 @@ handle_helper_message (void *cls, void *client,
         GNUNET_i2s (plugin->env->my_identity));
     plugin->env->notify_address (plugin->env->cls, GNUNET_YES,
                                  &plugin->mac_address,
-                                 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
+                                 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress),
+                                 "wlan");
     break;
   case GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER:
     LOG (GNUNET_ERROR_TYPE_DEBUG, 
@@ -1351,6 +1393,7 @@ handle_helper_message (void *cls, void *client,
         ntohs (hdr->type), ntohs (hdr->size));
     break;
   }
+  return GNUNET_OK;
 }
 
 
@@ -1467,7 +1510,7 @@ wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
     return NULL;
   }
   mac = addr;
-  return GNUNET_strdup (mac_to_string (mac));
+  return mac_to_string (mac);
 }
 
 
@@ -1529,6 +1572,16 @@ libgnunet_plugin_transport_wlan_done (void *cls)
     GNUNET_free (api);
     return NULL;
   }
+
+  if (GNUNET_YES == plugin->have_mac)
+  {
+      plugin->env->notify_address (plugin->env->cls, GNUNET_NO,
+                               &plugin->mac_address,
+                               sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress),
+                               "wlan");
+      plugin->have_mac = GNUNET_NO;
+  }
+
   if (GNUNET_SCHEDULER_NO_TASK != plugin->beacon_task)
   {
     GNUNET_SCHEDULER_cancel (plugin->beacon_task);
@@ -1654,11 +1707,9 @@ libgnunet_plugin_transport_wlan_init (void *cls)
          GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan",
                                                 "TESTMODE", &testmode)) ||
         (testmode > 2) ) )
-    {
-    LOG (GNUNET_ERROR_TYPE_ERROR,
-        _("Invalid configuration option `%s' in section `%s'\n"),
-        "TESTMODE",
-        "transport-wlan");
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                              "transport-wlan", "TESTMODE");
     return NULL;
   }
   if ( (0 == testmode) &&
@@ -1674,10 +1725,8 @@ libgnunet_plugin_transport_wlan_init (void *cls)
       (env->cfg, "transport-wlan", "INTERFACE",
        &interface))
   {
-    LOG (GNUNET_ERROR_TYPE_ERROR,
-        _("Missing configuration option `%s' in section `%s'\n"),
-        "INTERFACE",
-        "transport-wlan");
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                              "transport-wlan", "INTERFACE");
     return NULL;    
   }
 
@@ -1702,27 +1751,33 @@ libgnunet_plugin_transport_wlan_init (void *cls)
     plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan";
     plugin->helper_argv[1] = interface;
     plugin->helper_argv[2] = NULL;
-    plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan",
+    plugin->suid_helper = GNUNET_HELPER_start (GNUNET_NO,
+                                              "gnunet-helper-transport-wlan",
                                               plugin->helper_argv,
                                               &handle_helper_message,
+                                              NULL,
                                               plugin);
     break;
   case 1: /* testmode, peer 1 */
     plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan-dummy";
     plugin->helper_argv[1] = (char *) "1";
     plugin->helper_argv[2] = NULL;
-    plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan-dummy",
+    plugin->suid_helper = GNUNET_HELPER_start (GNUNET_NO,
+                                              "gnunet-helper-transport-wlan-dummy",
                                               plugin->helper_argv,
                                               &handle_helper_message,
+                                              NULL,
                                               plugin);
     break;
   case 2: /* testmode, peer 2 */
     plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan-dummy";
     plugin->helper_argv[1] = (char *) "2";
     plugin->helper_argv[2] = NULL;
-    plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan-dummy",
+    plugin->suid_helper = GNUNET_HELPER_start (GNUNET_NO,
+                                              "gnunet-helper-transport-wlan-dummy",
                                               plugin->helper_argv,
                                               &handle_helper_message,
+                                              NULL,
                                               plugin);
     break;
   default: