-fix mesh tunnel destruction
[oweals/gnunet.git] / src / conversation / gnunet-service-conversation.c
index b2d8af2c3311f4d65e9b68dee41777bcd6c01557..c051dfde088a9acc5ca1b98cd78ab1de2ea4facf 100644 (file)
@@ -294,6 +294,9 @@ handle_client_pickup_message (void *cls,
     return;
   }
   line->status = LS_CALLEE_CONNECTED;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending PICK_UP message to client with meta data `%s'\n",
+              meta);
   e = GNUNET_MQ_msg_extra (mppm,
                            len,
                            GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP);
@@ -311,6 +314,8 @@ handle_client_pickup_message (void *cls,
 static void
 destroy_line_mesh_tunnels (struct Line *line)
 {
+  struct GNUNET_MESH_Tunnel *t;
+
   if (NULL != line->reliable_mq)
   {
     GNUNET_MQ_destroy (line->reliable_mq);
@@ -321,15 +326,15 @@ destroy_line_mesh_tunnels (struct Line *line)
     GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth);
     line->unreliable_mth = NULL;
   }
-  if (NULL != line->tunnel_unreliable)
+  if (NULL != (t = line->tunnel_unreliable))
   {
-    GNUNET_MESH_tunnel_destroy (line->tunnel_unreliable);
     line->tunnel_unreliable = NULL;
+    GNUNET_MESH_tunnel_destroy (t);
   }
-  if (NULL != line->tunnel_reliable)
+  if (NULL != (t = line->tunnel_reliable))
   {
-    GNUNET_MESH_tunnel_destroy (line->tunnel_reliable);
     line->tunnel_reliable = NULL;
+    GNUNET_MESH_tunnel_destroy (t);
   }
 }
 
@@ -368,11 +373,6 @@ mq_done_finish_caller_shutdown (void *cls)
     break;
   case LS_CALLER_SHUTDOWN:
     destroy_line_mesh_tunnels (line);
-    GNUNET_CONTAINER_DLL_remove (lines_head,
-                                 lines_tail,
-                                 line);
-    GNUNET_free_non_null (line->audio_data);
-    GNUNET_free (line);
     break;
   }  
 }
@@ -440,6 +440,9 @@ handle_client_hangup_message (void *cls,
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending HANG_UP message via mesh with meta data `%s'\n",
+              meta);
   e = GNUNET_MQ_msg_extra (mhum,
                            len,
                            GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP);
@@ -511,6 +514,8 @@ handle_client_call_message (void *cls,
   GNUNET_CRYPTO_ecc_sign (&msg->caller_id,
                           &ring->purpose,
                           &ring->signature);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending RING message via mesh\n");
   GNUNET_MQ_send (line->reliable_mq, e);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
@@ -545,6 +550,9 @@ transmit_line_audio (void *cls,
   memcpy (&mam[1], line->audio_data, line->audio_size);
   GNUNET_free (line->audio_data);
   line->audio_data = NULL;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending %u bytes of audio data via mesh\n",
+              line->audio_size);
   return sizeof (struct MeshAudioMessage) + line->audio_size;  
 }
 
@@ -577,6 +585,11 @@ handle_client_audio_message (void *cls,
   switch (line->status)
   {
   case LS_CALLEE_LISTEN:
+    /* could be OK if the line just was closed by the other side */
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Audio data dropped, channel is down\n");
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    break;
   case LS_CALLEE_RINGING:
   case LS_CALLER_CALLING:
     GNUNET_break (0);
@@ -588,14 +601,14 @@ handle_client_audio_message (void *cls,
     break;
   case LS_CALLEE_SHUTDOWN:
   case LS_CALLER_SHUTDOWN:
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
                 "Mesh audio channel in shutdown; audio data dropped\n");
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
     return;
   }
   if (NULL == line->tunnel_unreliable)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
                 _("Mesh audio channel not ready; audio data dropped\n"));
     GNUNET_SERVER_receive_done (client, GNUNET_OK);    
     return;
@@ -604,10 +617,12 @@ handle_client_audio_message (void *cls,
   {
     /* NOTE: we may want to not do this and instead combine the data */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Dropping previous audio data segment with %u bytes\n",
-                line->audio_size);
+                "Bandwidth insufficient; dropping previous audio data segment with %u bytes\n",
+                (unsigned int) line->audio_size);
     GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth);
+    line->unreliable_mth = NULL;
     GNUNET_free (line->audio_data);
+    line->audio_data = NULL;
   }
   line->audio_size = size;
   line->audio_data = GNUNET_malloc (line->audio_size);
@@ -701,6 +716,8 @@ handle_mesh_ring_message (void *cls,
   cring.header.size = htons (sizeof (cring));
   cring.reserved = htonl (0);
   cring.caller_id = msg->caller_id;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending RING message to client\n");
   GNUNET_SERVER_notification_context_unicast (nc,
                                               line->client,
                                               &cring.header,
@@ -781,6 +798,9 @@ handle_mesh_hangup_message (void *cls,
   hup->header.size = sizeof (buf);
   hup->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
   memcpy (&hup[1], reason, len);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending HANG UP message to client with reason `%s'\n",
+              reason);
   GNUNET_SERVER_notification_context_unicast (nc,
                                               line->client,
                                               &hup->header,
@@ -859,6 +879,9 @@ handle_mesh_pickup_message (void *cls,
   pick->header.size = sizeof (buf);
   pick->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP);
   memcpy (&pick[1], metadata, len);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending PICK UP message via mesh with metadata `%s'\n",
+              metadata);
   GNUNET_SERVER_notification_context_unicast (nc,
                                               line->client,
                                               &pick->header,
@@ -899,10 +922,6 @@ handle_mesh_busy_message (void *cls,
   }
   busy.header.size = sizeof (busy);
   busy.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_BUSY);
-  GNUNET_SERVER_notification_context_unicast (nc,
-                                              line->client,
-                                              &busy.header,
-                                              GNUNET_NO);
   GNUNET_MESH_receive_done (tunnel);
   *tunnel_ctx = NULL;
   switch (line->status)
@@ -920,14 +939,22 @@ handle_mesh_busy_message (void *cls,
     GNUNET_break_op (0);
     break;
   case LS_CALLER_CALLING:
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Sending BUSY message to client\n");
+    GNUNET_SERVER_notification_context_unicast (nc,
+                                                line->client,
+                                                &busy.header,
+                                                GNUNET_NO);
     line->status = LS_CALLER_SHUTDOWN;
     mq_done_finish_caller_shutdown (line);
     break;
   case LS_CALLER_CONNECTED:
+    GNUNET_break_op (0);
     line->status = LS_CALLER_SHUTDOWN;
     mq_done_finish_caller_shutdown (line);
     break;
   case LS_CALLER_SHUTDOWN:
+    GNUNET_break_op (0);
     mq_done_finish_caller_shutdown (line);
     break;
   }
@@ -956,12 +983,19 @@ handle_mesh_audio_message (void *cls,
   size_t msize = ntohs (message->size) - sizeof (struct MeshAudioMessage);
   char buf[msize + sizeof (struct ClientAudioMessage)];
   struct ClientAudioMessage *cam;
+  const union GNUNET_MESH_TunnelInfo *info;
   
   msg = (const struct MeshAudioMessage *) message;
   if (NULL == line)
   {
-    sender = *GNUNET_MESH_tunnel_get_info (tunnel,
-                                           GNUNET_MESH_OPTION_PEER)->peer;
+    info = GNUNET_MESH_tunnel_get_info (tunnel,
+                                        GNUNET_MESH_OPTION_PEER);
+    if (NULL == info)
+    {
+      GNUNET_break (0);
+      return GNUNET_OK;
+    }
+    sender = info->peer;
     for (line = lines_head; NULL != line; line = line->next)
       if ( (line->local_line == ntohl (msg->remote_line)) &&
            (LS_CALLEE_CONNECTED == line->status) &&
@@ -976,10 +1010,13 @@ handle_mesh_audio_message (void *cls,
                   "Received AUDIO data for non-existing line %u, dropping.\n",
                   ntohl (msg->remote_line));
       return GNUNET_SYSERR;
-    }
+    }    
     line->tunnel_unreliable = tunnel;
     *tunnel_ctx = line;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Forwarding %u bytes of AUDIO data to client\n",
+              msize);
   cam = (struct ClientAudioMessage *) buf;
   cam->header.size = htons (sizeof (buf));
   cam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO);
@@ -1010,8 +1047,8 @@ inbound_tunnel (void *cls,
                 uint32_t port)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-             _("Received incoming tunnel on port %d\n"), 
-              port);
+             _("Received incoming tunnel on port %u\n"), 
+              (unsigned int) port);
   return NULL;
 }
 
@@ -1037,16 +1074,27 @@ inbound_end (void *cls,
     return;
   if (line->tunnel_unreliable == tunnel)
   {
+    if (NULL != line->unreliable_mth)
+    {
+      GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth);
+      line->unreliable_mth = NULL;
+    }
     line->tunnel_unreliable = NULL;
     return;
   }
+  if (line->tunnel_reliable != tunnel)
+    return;
+  line->tunnel_reliable = NULL;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Mesh tunnel destroyed by mesh\n");
   hup.header.size = sizeof (hup);
   hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
   switch (line->status)
   {
   case LS_CALLEE_LISTEN:
     GNUNET_break (0);
-    return;
+    break;
   case LS_CALLEE_RINGING:
   case LS_CALLEE_CONNECTED:
     GNUNET_SERVER_notification_context_unicast (nc,
@@ -1057,7 +1105,6 @@ inbound_end (void *cls,
     break;
   case LS_CALLEE_SHUTDOWN:
     line->status = LS_CALLEE_LISTEN;
-    destroy_line_mesh_tunnels (line);
     break;
   case LS_CALLER_CALLING:
   case LS_CALLER_CONNECTED:
@@ -1065,21 +1112,11 @@ inbound_end (void *cls,
                                                 line->client,
                                                 &hup.header,
                                                 GNUNET_NO);
-    destroy_line_mesh_tunnels (line);
-    GNUNET_CONTAINER_DLL_remove (lines_head,
-                                 lines_tail,
-                                 line);
-    GNUNET_free_non_null (line->audio_data);
-    GNUNET_free (line);
     break;
   case LS_CALLER_SHUTDOWN:
-    destroy_line_mesh_tunnels (line);
-    GNUNET_CONTAINER_DLL_remove (lines_head,
-                                 lines_tail,
-                                 line);
-    GNUNET_free (line);
     break;
   }
+  destroy_line_mesh_tunnels (line);
 }
 
 
@@ -1095,14 +1132,20 @@ handle_client_disconnect (void *cls,
 {
   struct Line *line;
 
+  if (NULL == client)
+    return;
   line = GNUNET_SERVER_client_get_user_context (client, struct Line);
   if (NULL == line)
     return;
+  GNUNET_SERVER_client_set_user_context (client, NULL);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Client disconnected, closing line\n");
   GNUNET_CONTAINER_DLL_remove (lines_head,
                                lines_tail,
                                line);
+  destroy_line_mesh_tunnels (line);
+  GNUNET_free_non_null (line->audio_data);
   GNUNET_free (line);
-  GNUNET_SERVER_client_set_user_context (client, NULL);
 }