hxing typemap
[oweals/gnunet.git] / src / core / gnunet-service-core_sessions.c
index 0db053ff52377dd945d0460ab43c1cc700fdf8a2..e97954438229ca2591e304f5b8cb3b59bcf91fc6 100644 (file)
@@ -19,7 +19,7 @@
 */
 
 /**
- * @file core/gnunet-service-core_neighbours.c
+ * @file core/gnunet-service-core_sessions.c
  * @brief code for managing of 'encrypted' sessions (key exchange done) 
  * @author Christian Grothoff
  */
@@ -33,7 +33,7 @@
  * Record kept for each request for transmission issued by a
  * client that is still pending.
  */
-struct ClientActiveRequest;
+struct GSC_ClientActiveRequest;
 
 /**
  * Data kept per session.
@@ -49,13 +49,13 @@ struct Session
    * Head of list of requests from clients for transmission to
    * this peer.
    */
-  struct ClientActiveRequest *active_client_request_head;
+  struct GSC_ClientActiveRequest *active_client_request_head;
 
   /**
    * Tail of list of requests from clients for transmission to
    * this peer.
    */
-  struct ClientActiveRequest *active_client_request_tail;
+  struct GSC_ClientActiveRequest *active_client_request_tail;
 
   /**
    * Performance data for the peer.
@@ -67,7 +67,6 @@ struct Session
    */
   struct GSC_KeyExchangeInfo *kxinfo;
 
-
   /**
    * ID of task used for cleaning up dead neighbour entries.
    */
@@ -100,23 +99,6 @@ struct Session
    */
   unsigned int ats_count;
 
-  /**
-   * Bit map indicating which of the 32 sequence numbers before the last
-   * were received (good for accepting out-of-order packets and
-   * estimating reliability of the connection)
-   */
-  unsigned int last_packets_bitmap;
-
-  /**
-   * last sequence number received on this connection (highest)
-   */
-  uint32_t last_sequence_number_received;
-
-  /**
-   * last sequence number transmitted
-   */
-  uint32_t last_sequence_number_sent;
-
   /**
    * Available bandwidth in for this peer (current target).
    */
@@ -294,8 +276,8 @@ handle_peer_status_change (struct Neighbour *n)
 static void
 schedule_peer_messages (struct Neighbour *n)
 {
-  struct ClientActiveRequest *car;
-  struct ClientActiveRequest *pos;
+  struct GSC_ClientActiveRequest *car;
+  struct GSC_ClientActiveRequest *pos;
   struct Client *c;
   struct MessageEntry *mqe;
   unsigned int queue_size;
@@ -354,7 +336,7 @@ static void
 free_neighbour (struct Neighbour *n)
 {
   struct MessageEntry *m;
-  struct ClientActiveRequest *car;
+  struct GSC_ClientActiveRequest *car;
 
 #if DEBUG_CORE
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1123,11 +1105,7 @@ create_neighbour (const struct GNUNET_PeerIdentity *pid)
 #endif
   n = GNUNET_malloc (sizeof (struct Neighbour));
   n->peer = *pid;
-  GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
-  now = GNUNET_TIME_absolute_get ();
-  n->encrypt_key_created = now;
-  n->last_activity = now;
-  n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
+  n->last_activity = GNUNET_TIME_absolute_get ();
   n->bw_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
   n->bw_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
   n->bw_out_internal_limit = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
@@ -1360,6 +1338,51 @@ GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car,
 
 
 
+/**
+ * Send a message to the neighbour.
+ *
+ * @param cls the message
+ * @param key neighbour's identity
+ * @param value 'struct Neighbour' of the target
+ * @return always GNUNET_OK
+ */
+static int
+do_send_message (void *cls, const GNUNET_HashCode * key, void *value)
+{
+  struct GNUNET_MessageHeader *hdr = cls;
+  struct Neighbour *n = value;
+  struct MessageEntry *m;
+  uint16_t size;
+
+  size = ntohs (hdr->size);
+  m = GNUNET_malloc (sizeof (struct MessageEntry) + size);
+  memcpy (&m[1], hdr, size);
+  m->deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
+  m->slack_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
+  m->priority = UINT_MAX;
+  m->sender_status = n->status;
+  m->size = size;
+  GNUNET_CONTAINER_DLL_insert (n->message_head,
+                              n->message_tail,
+                              m);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Broadcast a message to all neighbours.
+ *
+ * @param msg message to transmit
+ */
+void
+GSC_SESSIONS_broadcast (const struct GNUNET_MessageHeader *msg)
+{
+  if (NULL == sessions)
+    return;
+  GNUNET_CONTAINER_multihashmap_iterate (sessions,
+                                         &do_send_message, msg);
+}
+
 
 /**
  * Helper function for GSC_SESSIONS_handle_client_iterate_peers.
@@ -1413,9 +1436,60 @@ queue_connect_message (void *cls, const GNUNET_HashCode * key, void *value)
 }
 
 
+/**
+ * End the session with the given peer (we are no longer
+ * connected). 
+ *
+ * @param pid identity of peer to kill session with
+ */
+void
+GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
+{
+}
+
 
 /**
- * Handle CORE_ITERATE_PEERS request.
+ * Traffic is being solicited for the given peer.  This means that the
+ * message queue on the transport-level (NEIGHBOURS subsystem) is now
+ * empty and it is now OK to transmit another (non-control) message.
+ *
+ * @param pid identity of peer ready to receive data
+ */
+void
+GSC_SESSIONS_solicit (const struct GNUNET_PeerIdentity *pid)
+{
+}
+
+
+/**
+ * Transmit a message to a particular peer.
+ *
+ * @param car original request that was queued and then solicited,
+ *            ownership does not change (dequeue will be called soon).
+ * @param msg message to transmit
+ */
+void
+GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car,
+                      const struct GNUNET_MessageHeader *msg)
+{
+}
+
+
+/**
+ * We have a new client, notify it about all current sessions.
+ *
+ * @param client the new client
+ */
+void
+GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client)
+{
+}
+
+
+/**
+ * Handle CORE_ITERATE_PEERS request. For this request type, the client
+ * does not have to have transmitted an INIT request.  All current peers
+ * are returned, regardless of which message types they accept. 
  *
  * @param cls unused
  * @param client client sending the iteration request
@@ -1439,7 +1513,10 @@ GSC_SESSIONS_handle_client_iterate_peers (void *cls, struct GNUNET_SERVER_Client
 
 
 /**
- * Handle CORE_PEER_CONNECTED request.  Notify client about existing neighbours.
+ * Handle CORE_PEER_CONNECTED request.   Notify client about connection
+ * to the given neighbour.  For this request type, the client does not
+ * have to have transmitted an INIT request.  All current peers are
+ * returned, regardless of which message types they accept.
  *
  * @param cls unused
  * @param client client sending the iteration request
@@ -1466,7 +1543,8 @@ GSC_SESSIONS_handle_client_have_peer (void *cls, struct GNUNET_SERVER_Client *cl
 
 
 /**
- * Handle REQUEST_INFO request.
+ * Handle REQUEST_INFO request. For this request type, the client must
+ * have transmitted an INIT first.
  *
  * @param cls unused
  * @param client client sending the request
@@ -1573,11 +1651,129 @@ GSC_SESSIONS_handle_client_request_info (void *cls, struct GNUNET_SERVER_Client
 }
 
 
+/**
+ * Create a session, a key exchange was just completed.
+ *
+ * @param peer peer that is now connected
+ * @param kx key exchange that completed
+ */
+void
+GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer,
+                    struct GSC_KeyExchangeInfo *kx)
+{
+    {
+      struct GNUNET_MessageHeader *hdr;
+
+      hdr = compute_type_map_message ();
+      send_type_map_to_neighbour (hdr, &n->peer.hashPubKey, n);
+      GNUNET_free (hdr);
+    }
+    if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__)
+    {
+      n->bw_out_external_limit = t.inbound_bw_limit;
+      n->bw_out =
+          GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
+                                      n->bw_out_internal_limit);
+      GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
+                                             n->bw_out);
+      GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
+    }
+#if DEBUG_CORE
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Confirmed key via `%s' message for peer `%4s'\n", "PONG",
+                GNUNET_i2s (&n->peer));
+#endif
+
+
+    size =
+        sizeof (struct ConnectNotifyMessage) +
+        (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+    if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+    {
+      GNUNET_break (0);
+      /* recovery strategy: throw away performance data */
+      GNUNET_array_grow (n->ats, n->ats_count, 0);
+      size =
+          sizeof (struct PeerStatusNotifyMessage) +
+          n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+    }
+    cnm = (struct ConnectNotifyMessage *) buf;
+    cnm->header.size = htons (size);
+    cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
+    cnm->ats_count = htonl (n->ats_count);
+    cnm->peer = n->peer;
+    mats = &cnm->ats;
+    memcpy (mats, n->ats,
+            n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
+    mats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+    mats[n->ats_count].value = htonl (0);
+    send_to_all_clients (&cnm->header, GNUNET_NO,
+                         GNUNET_CORE_OPTION_SEND_CONNECT);
+    process_encrypted_neighbour_queue (n);
+    n->last_activity = GNUNET_TIME_absolute_get ();
+
+  if (n->status == PEER_STATE_KEY_CONFIRMED)
+  {
+    now = GNUNET_TIME_absolute_get ();
+    n->last_activity = now;
+    changed = GNUNET_YES;
+    if (!up)
+    {
+      GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
+                                1, GNUNET_NO);
+      n->time_established = now;
+    }
+    if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
+      GNUNET_SCHEDULER_cancel (n->keep_alive_task);
+    n->keep_alive_task =
+        GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
+                                      (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
+                                       2), &send_keep_alive, n);
+  }
+
+
+}
+
+
+/**
+ * Update information about a session.
+ *
+ * @param peer peer who's session should be updated
+ * @param bw_out new outbound bandwidth limit for the peer
+ * @param atsi performance information
+ * @param atsi_count number of performance records supplied
+ */
+void
+GSC_SESSIONS_update (const struct GNUNET_PeerIdentity *peer,
+                    struct GNUNET_BANDWIDTH_Value32NBO bw_out,
+                    const struct GNUNET_TRANSPORT_ATS_Information *atsi,
+                    uint32_t atsi_count)
+{
+  if (bw_out_external_limit.value__ != pt->inbound_bw_limit.value__)
+  {
+#if DEBUG_CORE_SET_QUOTA
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Received %u b/s as new inbound limit for peer `%4s'\n",
+                (unsigned int) ntohl (pt->inbound_bw_limit.value__),
+                GNUNET_i2s (&n->peer));
+#endif
+    n->bw_out_external_limit = pt->inbound_bw_limit;
+    n->bw_out =
+        GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
+                                    n->bw_out_internal_limit);
+    GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
+                                           n->bw_out);
+    GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
+  }
 
+}
 
 
+/**
+ * Initialize sessions subsystem.
+ */
 int
-GSC_NEIGHBOURS_init ()
+GSC_SESSIONS_init ()
 {
   neighbours = GNUNET_CONTAINER_multihashmap_create (128);
   self.public_key = &my_public_key;
@@ -1589,8 +1785,11 @@ GSC_NEIGHBOURS_init ()
 }
 
 
+/**
+ * Shutdown sessions subsystem.
+ */
 void
-GSC_NEIGHBOURS_done ()
+GSC_SESSIONS_done ()
 {
   GNUNET_CONTAINER_multihashmap_iterate (neighbours, &free_neighbour_helper,
                                          NULL);