#include "gnunet_signatures.h"
#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
-#include "core.h"
+#include "gnunet-service-core.h"
+#include "gnunet-service-core_clients.h"
+#include "gnunet-service-core_kx.h"
+#include "gnunet-service-core_neighbours.h"
+#include "gnunet-service-core_sessions.h"
+#include "gnunet-service-core_typemap.h"
#define DEBUG_HANDSHAKE GNUNET_EXTRA_LOGGING
*/
struct GNUNET_STATISTICS_Handle *GSC_stats;
-/**
- * Our message stream tokenizer (for encrypted payload).
- */
-struct GNUNET_SERVER_MessageStreamTokenizer *GSC_mst;
-
/**
* Last task run during shutdown. Disconnects us from
"Core service shutting down.\n");
#endif
GSC_CLIENTS_done ();
-
- if (GSC_mst != NULL)
- {
- GNUNET_SERVER_mst_destroy (GSC_mst);
- GSC_mst = NULL;
- }
+ GSC_SESSIONS_done ();
+ GSC_NEIGHBOURS_done ();
+ GSC_KX_done ();
+ GSC_TYPEMAP_done ();
if (GSC_stats != NULL)
{
GNUNET_STATISTICS_destroy (GSC_stats, GNUNET_NO);
const struct GNUNET_CONFIGURATION_Handle *c)
{
GSC_cfg = c;
- GSC_mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
- GSC_stats = GNUNET_STATISTICS_create ("core", cfg);
-
- GSC_CLIENTS_init (server);
+ GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg);
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task,
NULL);
+ GSC_TYPEMAP_init ();
+ if ( (GNUNET_OK != GSC_KX_init ()) ||
+ (GNUNET_OK != GSC_NEIGHBOURS_init ()) )
+ {
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ GSC_SESSIONS_init ();
+ GSC_CLIENTS_init (server);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
- GNUNET_i2s (&my_identity));
+ GNUNET_i2s (&GSC_my_identity));
}
*/
#include "platform.h"
#include "gnunet_util_lib.h"
+#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
-#include "gnunet_service_core.h"
-#include "gnunet_service_core_clients.h"
-#include "gnunet_service_core_sessions.h"
-#include "gnunet_service_core_typemap.h"
+#include "gnunet-service-core.h"
+#include "gnunet-service-core_clients.h"
+#include "gnunet-service-core_sessions.h"
+#include "gnunet-service-core_typemap.h"
+#include "core.h"
+
+/**
+ * How many messages do we queue up at most for optional
+ * notifications to a client? (this can cause notifications
+ * about outgoing messages to be dropped).
+ */
+#define MAX_NOTIFY_QUEUE 1024
/**
for (c = client_head; c != NULL; c = c->next)
{
- if ( (0 != (c->options & options)) &&
- (GNUNET_YES == type_match (type, c)) )
- continue; /* both match, wait for only type match */
- if ( (0 == (c->options & options)) &&
- (GNUNET_YES != type_match (type, c)) )
- continue; /* neither match, skip entirely */
+ if (! ( (0 != (c->options & options)) ||
+ ( (0 != (options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) &&
+ (GNUNET_YES == type_match (type, c)) ) ) )
+ continue; /* skip */
#if DEBUG_CORE_CLIENT > 1
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending message of type %u to client.\n",
&req->peer.hashPubKey,
car,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
- car->client = c;
+ car->client_handle = c;
}
car->target = req->peer;
- GNUNET_SERVER_client_keep (client);
- car->client_handle = client;
car->deadline = GNUNET_TIME_absolute_ntoh (req->deadline);
car->priority = ntohl (req->priority);
car->msize = ntohs (req->size);
car));
GNUNET_SERVER_mst_receive (client_mst,
car,
- &sm[1], msize,
+ (const char*) &sm[1], msize,
GNUNET_YES,
GNUNET_NO);
if (0 !=
- memcmp (&car->peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
+ memcmp (&car->target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
GSC_SESSIONS_dequeue_request (car);
GNUNET_free (car);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
struct GSC_ClientActiveRequest *car = client;
if (0 ==
- memcmp (&car->peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
- GDS_CLIENTS_deliver_message (&GSC_my_identity, &payload->header);
+ memcmp (&car->target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
+ {
+ GSC_CLIENTS_deliver_message (&GSC_my_identity,
+ NULL, 0,
+ message,
+ ntohs (message->size),
+ GNUNET_CORE_OPTION_SEND_FULL_INBOUND | GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND);
+ GSC_CLIENTS_deliver_message (&GSC_my_identity,
+ NULL, 0,
+ message,
+ sizeof (struct GNUNET_MessageHeader),
+ GNUNET_CORE_OPTION_SEND_HDR_INBOUND | GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND);
+ }
else
- GSC_SESSIONS_transmit (car, &payload->header);
+ GSC_SESSIONS_transmit (car, message);
}
struct GSC_ClientActiveRequest *car = value;
GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
- &car->peer,
- car);
+ GNUNET_CONTAINER_multihashmap_remove (car->client_handle->requests,
+ &car->target.hashPubKey,
+ car));
GSC_SESSIONS_dequeue_request (car);
GNUNET_free (car);
return GNUNET_YES;
struct GSC_Client *c;
struct SendMessageReady smr;
- c = car->client;
+ c = car->client_handle;
smr.header.size = htons (sizeof (struct SendMessageReady));
smr.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_READY);
smr.size = htons (car->msize);
smr.smr_id = car->smr_id;
- smr.peer = n->peer;
+ smr.peer = car->target;
send_to_client (c, &smr.header, GNUNET_NO);
}
GSC_CLIENTS_reject_request (struct GSC_ClientActiveRequest *car)
{
GNUNET_assert (GNUNET_YES ==
- destroy_active_client_request (NULL, &car->peer.hashPubKey, car));
+ destroy_active_client_request (NULL, &car->target.hashPubKey, car));
}
/* send connect */
size =
sizeof (struct ConnectNotifyMessage) +
- (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ (atsi_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 ConnectNotifyMessage) +
- (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ atsi_count = 0;
+ size = sizeof (struct ConnectNotifyMessage);
}
cnm = (struct ConnectNotifyMessage *) buf;
cnm->header.size = htons (size);
cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- cnm->ats_count = htonl (atsi);
- a = &cnm->atsi;
+ cnm->ats_count = htonl (atsi_count);
+ a = &cnm->ats;
memcpy (a, atsi,
sizeof (struct GNUNET_TRANSPORT_ATS_Information) * atsi_count);
- a[ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
- a[ats_count].value = htonl (0);
+ a[atsi_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ a[atsi_count].value = htonl (0);
#if DEBUG_CORE_CLIENT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending `%s' message to client.\n",
"NOTIFY_CONNECT");
#endif
- cnm->peer = n->peer;
+ cnm->peer = *neighbour;
send_to_client (client, &cnm->header, GNUNET_NO);
}
else
dcm.header.size = htons (sizeof (struct DisconnectNotifyMessage));
dcm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
dcm.reserved = htonl (0);
- dcm.peer = *peer;
- send_to_client (client, &cnm.header, GNUNET_NO);
+ dcm.peer = *neighbour;
+ send_to_client (client, &dcm.header, GNUNET_NO);
}
}
int options)
{
size_t size = msize + sizeof (struct NotifyTrafficMessage) +
- (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ atsi_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
char buf[size];
struct NotifyTrafficMessage *ntm;
struct GNUNET_TRANSPORT_ATS_Information *a;
- int dropped;
if (0 == options)
{
GNUNET_snprintf (buf, sizeof (buf),
gettext_noop ("# bytes of messages of type %u received"),
(unsigned int) ntohs (msg->type));
- GNUNET_STATISTICS_update (stats, buf, msize, GNUNET_NO);
+ GNUNET_STATISTICS_update (GSC_stats, buf, msize, GNUNET_NO);
}
- GNUNET_assert (GNUNET_YES == sender->is_connected);
- GNUNET_break (sender->status == PEER_STATE_KEY_CONFIRMED);
if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
{
GNUNET_break (0);
/* recovery strategy: throw performance data away... */
- GNUNET_array_grow (sender->ats, sender->ats_count, 0);
- size =
- msize + sizeof (struct NotifyTrafficMessage) +
- (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ atsi_count = 0;
+ size = msize + sizeof (struct NotifyTrafficMessage);
}
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
ntm->header.size = htons (size);
ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
ntm->ats_count = htonl (atsi_count);
- ntm->peer = sender->peer;
+ ntm->peer = *sender;
a = &ntm->ats;
memcpy (a, atsi,
- sizeof (struct GNUNET_TRANSPORT_ATS_Information) * sender->atsi_count);
+ sizeof (struct GNUNET_TRANSPORT_ATS_Information) * atsi_count);
a[atsi_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
a[atsi_count].value = htonl (0);
- memcpy (&ats[atsi_count + 1], msg, msize);
+ memcpy (&a[atsi_count + 1], msg, msize);
send_to_all_clients (&ntm->header, GNUNET_YES,
options, ntohs (msg->type));
}
handle_client_disconnect (NULL, c->client_handle);
GNUNET_SERVER_notification_context_destroy (notifier);
notifier = NULL;
- GNUNET_SERVER_MST_destroy (client_mst);
+ GNUNET_SERVER_mst_destroy (client_mst);
client_mst = NULL;
}
}
+/**
+ * Closure for 'deliver_message'
+ */
+struct DeliverMessageContext
+{
+
+ /**
+ * Performance information for the connection.
+ */
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi;
+
+ /**
+ * Sender of the message.
+ */
+ const struct GNUNET_PeerIdentity *peer;
+
+ /**
+ * Number of entries in 'atsi' array.
+ */
+ uint32_t atsi_count;
+}
+
+
/**
* We received an encrypted message. Decrypt, validate and
* pass on to the appropriate clients.
uint32_t atsi_count)
{
const struct EncryptedMessage *m;
- char buf[size];
struct EncryptedMessage *pt; /* plaintext */
GNUNET_HashCode ph;
uint32_t snum;
struct GNUNET_TIME_Absolute t;
struct GNUNET_CRYPTO_AesInitializationVector iv;
struct GNUNET_CRYPTO_AuthKey auth_key;
+ struct DeliverMessageContext dmc;
uint16_t size = ntohs (msg->size);
+ char buf[size];
if (size <
sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader))
/* process decrypted message(s) */
update_timeout (kx);
GSC_SESSIONS_update (&kx->peer,
- pt->inbound_bw_limit,
- atsi, atsi_count); // FIXME: does 'SESSIONS' need atsi!?
+ pt->inbound_bw_limit);
GNUNET_STATISTICS_update (stats,
gettext_noop ("# bytes of payload decrypted"),
size - sizeof (struct EncryptedMessage), GNUNET_NO);
+ dmc.atsi = atsi;
+ dmc.atsi_count = atsi_count;
+ dmc.peer = &kx->peer;
if (GNUNET_OK !=
- GNUNET_SERVER_mst_receive (mst, kx, &buf[sizeof (struct EncryptedMessage)],
+ GNUNET_SERVER_mst_receive (mst, &dmc, &buf[sizeof (struct EncryptedMessage)],
size - sizeof (struct EncryptedMessage),
GNUNET_YES, GNUNET_NO))
GNUNET_break_op (0);
}
-
-
/**
* Deliver P2P message to interested clients.
+ * Invokes send twice, once for clients that want the full message, and once
+ * for clients that only want the header
*
* @param cls always NULL
* @param client who sent us the message (struct GSC_KeyExchangeInfo)
static void
deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
{
- struct GSC_KeyExchangeInfo *kx = client;
+ struct DeliverMessageContext *dmc = client;
- // FIXME (need to check stuff, need ATSI, etc.)
- // FIXME: does clients work properly if never called with option 'NOTHING'!?
- GSC_CLIENTS_deliver_message (&kx->peer,
- NULL, 0, // kx->atsi...
+ GSC_CLIENTS_deliver_message (dmc->peer,
+ dmc->atsi, dmc->atsi_count,
m,
ntohs (m->size),
GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
- GSC_CLIENTS_deliver_message (&kx->peer,
- NULL, 0, // kx->atsi...
+ GSC_CLIENTS_deliver_message (dmc->peer,
+ dmc->atsi, dmc->atsi_count,
m,
sizeof (struct GNUNET_MessageHeader),
GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
}
+
/**
* Initialize KX subsystem.
*