/*
This file is part of GNUnet.
- (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors)
+ (C) 2009-2013 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
*/
#define TYPEMAP_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
+/**
+ * How often do we transmit our typemap on first attempt?
+ */
+#define TYPEMAP_FREQUENCY_FIRST GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+
/**
* Message ready for encryption. This struct is followed by the
*/
struct GSC_TypeMap *tmap;
- /**
- * At what time did we initially establish this session?
- * (currently unused, should be integrated with ATS in the
- * future...).
- */
- struct GNUNET_TIME_Absolute time_established;
-
/**
* Task to transmit corked messages with a delay.
*/
*/
int ready_to_transmit;
+ /**
+ * Is this the first time we're sending the typemap? If so,
+ * we want to send it a bit faster the second time. 0 if
+ * we are sending for the first time, 1 if not.
+ */
+ int first_typemap;
};
struct Session *session;
struct GSC_ClientActiveRequest *car;
struct SessionMessageEntry *sme;
-
+
session = find_session (pid);
if (NULL == session)
return;
-#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying session for peer `%4s'\n",
GNUNET_i2s (&session->peer));
-#endif
if (GNUNET_SCHEDULER_NO_TASK != session->cork_task)
{
GNUNET_SCHEDULER_cancel (session->cork_task);
}
while (NULL != (sme = session->sme_head))
{
- GNUNET_CONTAINER_DLL_remove (session->sme_head,
- session->sme_tail,
- sme);
+ GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
GNUNET_free (sme);
}
GNUNET_SCHEDULER_cancel (session->typemap_task);
&session->
peer.hashPubKey,
session));
- GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# entries in session map"),
+ GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# peers connected"),
GNUNET_CONTAINER_multihashmap_size (sessions),
GNUNET_NO);
GSC_TYPEMAP_destroy (session->tmap);
struct GNUNET_MessageHeader *hdr;
struct GNUNET_TIME_Relative delay;
- delay = TYPEMAP_FREQUENCY;
+ if (0 == session->first_typemap)
+ {
+ delay = TYPEMAP_FREQUENCY_FIRST;
+ session->first_typemap = 1;
+ }
+ else
+ {
+ delay = TYPEMAP_FREQUENCY;
+ }
/* randomize a bit to avoid spont. sync */
- delay.rel_value +=
- GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000);
+ delay.rel_value_us +=
+ GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000 * 1000);
session->typemap_task =
GNUNET_SCHEDULER_add_delayed (delay, &transmit_typemap_task, session);
GNUNET_STATISTICS_update (GSC_stats,
{
struct Session *session;
-#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating session for peer `%4s'\n",
GNUNET_i2s (peer));
-#endif
session = GNUNET_malloc (sizeof (struct Session));
session->tmap = GSC_TYPEMAP_create ();
session->peer = *peer;
session->kxinfo = kx;
- session->time_established = GNUNET_TIME_absolute_get ();
session->typemap_task =
GNUNET_SCHEDULER_add_now (&transmit_typemap_task, session);
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (sessions, &peer->hashPubKey,
session,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# entries in session map"),
+ GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# peers connected"),
GNUNET_CONTAINER_multihashmap_size (sessions),
GNUNET_NO);
GSC_CLIENTS_notify_clients_about_neighbour (peer, NULL, 0 /* FIXME: ATSI */ ,
* @return GNUNET_OK (continue to iterate)
*/
static int
-notify_client_about_session (void *cls, const GNUNET_HashCode * key,
+notify_client_about_session (void *cls, const struct GNUNET_HashCode * key,
void *value)
{
struct GSC_Client *client = cls;
session = find_session (&car->target);
if (session == NULL)
{
-#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Dropped client request for transmission (am disconnected)\n");
-#endif
- GNUNET_break (0); /* should have been rejected earlier */
+ GNUNET_break (0); /* should have been rejected earlier */
GSC_CLIENTS_reject_request (car);
return;
}
GSC_CLIENTS_reject_request (car);
return;
}
-#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received client transmission request. queueing\n");
-#endif
GNUNET_CONTAINER_DLL_insert (session->active_client_request_head,
session->active_client_request_tail, car);
try_transmission (session);
{
pos = nxt;
nxt = pos->next;
- if ((pos->deadline.abs_value < now.abs_value) &&
+ if ((pos->deadline.abs_value_us < now.abs_value_us) &&
(GNUNET_YES != pos->was_solicited))
{
GNUNET_STATISTICS_update (GSC_stats,
solicit_messages (struct Session *session)
{
struct GSC_ClientActiveRequest *car;
+ struct GSC_ClientActiveRequest *nxt;
size_t so_size;
discard_expired_requests (session);
so_size = 0;
- for (car = session->active_client_request_head; NULL != car; car = car->next)
+ nxt = session->active_client_request_head;
+ while (NULL != (car = nxt))
{
+ nxt = car->next;
if (so_size + car->msize > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
break;
so_size += car->msize;
now = GNUNET_TIME_absolute_get ();
if ((msize == 0) ||
((msize < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / 2) &&
- (min_deadline.abs_value > now.abs_value)))
+ (min_deadline.abs_value_us > now.abs_value_us)))
{
/* not enough ready yet, try to solicit more */
solicit_messages (session);
* @return always GNUNET_OK
*/
static int
-do_send_message (void *cls, const GNUNET_HashCode * key, void *value)
+do_send_message (void *cls, const struct GNUNET_HashCode * key, void *value)
{
const struct GNUNET_MessageHeader *hdr = cls;
struct Session *session = value;
*/
#include "core.h"
static int
-queue_connect_message (void *cls, const GNUNET_HashCode * key, void *value)
+queue_connect_message (void *cls, const struct GNUNET_HashCode * key, void *value)
{
struct GNUNET_SERVER_TransmitContext *tc = cls;
struct Session *session = value;
/* FIXME: code duplication with clients... */
cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- // FIXME: full ats...
- cnm.ats_count = htonl (0);
cnm.peer = session->peer;
GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header);
return GNUNET_OK;
void
GSC_SESSIONS_init ()
{
- sessions = GNUNET_CONTAINER_multihashmap_create (128);
+ sessions = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO);
}
* @return GNUNET_OK (continue to iterate)
*/
static int
-free_session_helper (void *cls, const GNUNET_HashCode * key, void *value)
+free_session_helper (void *cls, const struct GNUNET_HashCode * key, void *value)
{
struct Session *session = value;
void
GSC_SESSIONS_done ()
{
- GNUNET_CONTAINER_multihashmap_iterate (sessions, &free_session_helper, NULL);
- GNUNET_CONTAINER_multihashmap_destroy (sessions);
- sessions = NULL;
+ if (NULL != sessions)
+ {
+ GNUNET_CONTAINER_multihashmap_iterate (sessions, &free_session_helper, NULL);
+ GNUNET_CONTAINER_multihashmap_destroy (sessions);
+ sessions = NULL;
+ }
}
/* end of gnunet-service-core_sessions.c */