aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Makefile.am2
-rw-r--r--src/core/core_api.c29
-rw-r--r--src/core/gnunet-core.c9
-rw-r--r--src/core/gnunet-service-core.c69
-rw-r--r--src/core/gnunet-service-core_kx.c171
-rw-r--r--src/core/gnunet-service-core_sessions.c96
-rw-r--r--src/core/gnunet-service-core_typemap.c21
7 files changed, 247 insertions, 150 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index ed80bae73..2723151c5 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -71,7 +71,7 @@ check_PROGRAMS = \
71 $(TESTING_TESTS) 71 $(TESTING_TESTS)
72 72
73if ENABLE_TEST_RUN 73if ENABLE_TEST_RUN
74AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; 74AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
75TESTS = $(check_PROGRAMS) 75TESTS = $(check_PROGRAMS)
76endif 76endif
77 77
diff --git a/src/core/core_api.c b/src/core/core_api.c
index b6d8f61d2..ed8ce364d 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -204,6 +204,11 @@ disconnect_and_free_peer_entry (void *cls,
204 pr)); 204 pr));
205 GNUNET_MQ_destroy (pr->mq); 205 GNUNET_MQ_destroy (pr->mq);
206 GNUNET_assert (NULL == pr->mq); 206 GNUNET_assert (NULL == pr->mq);
207 if (NULL != pr->env)
208 {
209 GNUNET_MQ_discard (pr->env);
210 pr->env = NULL;
211 }
207 GNUNET_free (pr); 212 GNUNET_free (pr);
208 return GNUNET_YES; 213 return GNUNET_YES;
209} 214}
@@ -316,7 +321,7 @@ core_mq_send_impl (struct GNUNET_MQ_Handle *mq,
316 321
317 /* check message size for sanity */ 322 /* check message size for sanity */
318 msize = ntohs (msg->size); 323 msize = ntohs (msg->size);
319 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct SendMessage)) 324 if (msize >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct SendMessage))
320 { 325 {
321 GNUNET_break (0); 326 GNUNET_break (0);
322 GNUNET_MQ_impl_send_continue (mq); 327 GNUNET_MQ_impl_send_continue (mq);
@@ -331,7 +336,6 @@ core_mq_send_impl (struct GNUNET_MQ_Handle *mq,
331 env = GNUNET_MQ_msg (smr, 336 env = GNUNET_MQ_msg (smr,
332 GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST); 337 GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST);
333 smr->priority = htonl ((uint32_t) priority); 338 smr->priority = htonl ((uint32_t) priority);
334 // smr->deadline = GNUNET_TIME_absolute_hton (deadline);
335 smr->peer = pr->peer; 339 smr->peer = pr->peer;
336 smr->reserved = htonl (0); 340 smr->reserved = htonl (0);
337 smr->size = htons (msize); 341 smr->size = htons (msize);
@@ -344,7 +348,6 @@ core_mq_send_impl (struct GNUNET_MQ_Handle *mq,
344 GNUNET_MESSAGE_TYPE_CORE_SEND, 348 GNUNET_MESSAGE_TYPE_CORE_SEND,
345 msg); 349 msg);
346 sm->priority = htonl ((uint32_t) priority); 350 sm->priority = htonl ((uint32_t) priority);
347 // sm->deadline = GNUNET_TIME_absolute_hton (deadline);
348 sm->peer = pr->peer; 351 sm->peer = pr->peer;
349 sm->cork = htonl ((uint32_t) cork); 352 sm->cork = htonl ((uint32_t) cork);
350 sm->reserved = htonl (0); 353 sm->reserved = htonl (0);
@@ -781,7 +784,6 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
781 const struct GNUNET_MQ_MessageHandler *handlers) 784 const struct GNUNET_MQ_MessageHandler *handlers)
782{ 785{
783 struct GNUNET_CORE_Handle *h; 786 struct GNUNET_CORE_Handle *h;
784 unsigned int hcnt;
785 787
786 h = GNUNET_new (struct GNUNET_CORE_Handle); 788 h = GNUNET_new (struct GNUNET_CORE_Handle);
787 h->cfg = cfg; 789 h->cfg = cfg;
@@ -791,19 +793,10 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
791 h->disconnects = disconnects; 793 h->disconnects = disconnects;
792 h->peers = GNUNET_CONTAINER_multipeermap_create (128, 794 h->peers = GNUNET_CONTAINER_multipeermap_create (128,
793 GNUNET_NO); 795 GNUNET_NO);
794 hcnt = 0; 796 h->handlers = GNUNET_MQ_copy_handlers (handlers);
795 if (NULL != handlers) 797 h->hcnt = GNUNET_MQ_count_handlers (handlers);
796 while (NULL != handlers[hcnt].cb) 798 GNUNET_assert (h->hcnt <
797 hcnt++; 799 (GNUNET_MAX_MESSAGE_SIZE -
798 h->handlers = GNUNET_new_array (hcnt + 1,
799 struct GNUNET_MQ_MessageHandler);
800 if (NULL != handlers)
801 GNUNET_memcpy (h->handlers,
802 handlers,
803 hcnt * sizeof (struct GNUNET_MQ_MessageHandler));
804 h->hcnt = hcnt;
805 GNUNET_assert (hcnt <
806 (GNUNET_SERVER_MAX_MESSAGE_SIZE -
807 sizeof (struct InitMessage)) / sizeof (uint16_t)); 800 sizeof (struct InitMessage)) / sizeof (uint16_t));
808 LOG (GNUNET_ERROR_TYPE_DEBUG, 801 LOG (GNUNET_ERROR_TYPE_DEBUG,
809 "Connecting to CORE service\n"); 802 "Connecting to CORE service\n");
@@ -842,7 +835,7 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
842 GNUNET_MQ_destroy (handle->mq); 835 GNUNET_MQ_destroy (handle->mq);
843 handle->mq = NULL; 836 handle->mq = NULL;
844 } 837 }
845 GNUNET_free (handle->handlers); 838 GNUNET_free_non_null (handle->handlers);
846 GNUNET_free (handle); 839 GNUNET_free (handle);
847} 840}
848 841
diff --git a/src/core/gnunet-core.c b/src/core/gnunet-core.c
index d91dc304d..76b7e8ac4 100644
--- a/src/core/gnunet-core.c
+++ b/src/core/gnunet-core.c
@@ -171,10 +171,11 @@ main (int argc,
171 char *const *argv) 171 char *const *argv)
172{ 172{
173 int res; 173 int res;
174 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 174 struct GNUNET_GETOPT_CommandLineOption options[] = {
175 {'m', "monitor", NULL, 175 GNUNET_GETOPT_option_flag ('m',
176 gettext_noop ("provide information about all current connections (continuously)"), 176 "monitor",
177 0, &GNUNET_GETOPT_set_one, &monitor_connections}, 177 gettext_noop ("provide information about all current connections (continuously)"),
178 &monitor_connections),
178 GNUNET_GETOPT_OPTION_END 179 GNUNET_GETOPT_OPTION_END
179 }; 180 };
180 181
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index b0d7b24ba..625bf9655 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -32,11 +32,19 @@
32#include "gnunet-service-core_typemap.h" 32#include "gnunet-service-core_typemap.h"
33 33
34/** 34/**
35 * How many messages do we queue up at most for optional 35 * How many messages do we queue up at most for any client? This can
36 * notifications to a client? (this can cause notifications 36 * cause messages to be dropped if clients do not process them fast
37 * about outgoing messages to be dropped). 37 * enough! Note that this is a soft limit; we try
38 * to keep a few larger messages above the limit.
38 */ 39 */
39#define MAX_NOTIFY_QUEUE 1024 40#define SOFT_MAX_QUEUE 128
41
42/**
43 * How many messages do we queue up at most for any client? This can
44 * cause messages to be dropped if clients do not process them fast
45 * enough! Note that this is the hard limit.
46 */
47#define HARD_MAX_QUEUE 256
40 48
41 49
42/** 50/**
@@ -696,6 +704,11 @@ GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
696 new_match = GSC_TYPEMAP_test_match (tmap_new, 704 new_match = GSC_TYPEMAP_test_match (tmap_new,
697 client->types, 705 client->types,
698 client->tcnt); 706 client->tcnt);
707 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
708 "Notifying client about neighbour %s (%d/%d)\n",
709 GNUNET_i2s (neighbour),
710 old_match,
711 new_match);
699 if (old_match == new_match) 712 if (old_match == new_match)
700 { 713 {
701 GNUNET_assert (old_match == 714 GNUNET_assert (old_match ==
@@ -720,7 +733,8 @@ GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
720 GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); 733 GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
721 cnm->reserved = htonl (0); 734 cnm->reserved = htonl (0);
722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 735 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
723 "Sending NOTIFY_CONNECT message to client.\n"); 736 "Sending NOTIFY_CONNECT message about peer %s to client.\n",
737 GNUNET_i2s (neighbour));
724 cnm->peer = *neighbour; 738 cnm->peer = *neighbour;
725 GNUNET_MQ_send (client->mq, 739 GNUNET_MQ_send (client->mq,
726 env); 740 env);
@@ -740,6 +754,9 @@ GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
740 env = GNUNET_MQ_msg (dcm, 754 env = GNUNET_MQ_msg (dcm,
741 GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT); 755 GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
742 dcm->reserved = htonl (0); 756 dcm->reserved = htonl (0);
757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
758 "Sending NOTIFY_DISCONNECT message about peer %s to client.\n",
759 GNUNET_i2s (neighbour));
743 dcm->peer = *neighbour; 760 dcm->peer = *neighbour;
744 GNUNET_MQ_send (client->mq, 761 GNUNET_MQ_send (client->mq,
745 env); 762 env);
@@ -790,7 +807,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender,
790{ 807{
791 size_t size = msize + sizeof (struct NotifyTrafficMessage); 808 size_t size = msize + sizeof (struct NotifyTrafficMessage);
792 809
793 if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 810 if (size >= GNUNET_MAX_MESSAGE_SIZE)
794 { 811 {
795 GNUNET_break (0); 812 GNUNET_break (0);
796 return; 813 return;
@@ -810,6 +827,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender,
810 struct GNUNET_MQ_Envelope *env; 827 struct GNUNET_MQ_Envelope *env;
811 struct NotifyTrafficMessage *ntm; 828 struct NotifyTrafficMessage *ntm;
812 uint16_t mtype; 829 uint16_t mtype;
830 unsigned int qlen;
813 int tm; 831 int tm;
814 832
815 tm = type_match (ntohs (msg->type), 833 tm = type_match (ntohs (msg->type),
@@ -825,6 +843,45 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender,
825 if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) && 843 if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) &&
826 (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) ) 844 (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) )
827 continue; 845 continue;
846
847 /* Drop messages if:
848 1) We are above the hard limit, or
849 2) We are above the soft limit, and a coin toss limited
850 to the message size (giving larger messages a
851 proportionally higher chance of being queued) falls
852 below the threshold. The threshold is based on where
853 we are between the soft and the hard limit, scaled
854 to match the range of message sizes we usually encounter
855 (i.e. up to 32k); so a 64k message has a 50% chance of
856 being kept if we are just barely below the hard max,
857 and a 99% chance of being kept if we are at the soft max.
858 The reason is to make it more likely to drop control traffic
859 (ACK, queries) which may be cummulative or highly redundant,
860 and cheap to drop than data traffic. */
861 qlen = GNUNET_MQ_get_length (c->mq);
862 if ( (qlen >= HARD_MAX_QUEUE) ||
863 ( (qlen > SOFT_MAX_QUEUE) &&
864 ( (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
865 ntohs (msg->size)) ) <
866 (qlen - SOFT_MAX_QUEUE) * 0x8000 /
867 (HARD_MAX_QUEUE - SOFT_MAX_QUEUE) ) ) )
868 {
869 char buf[1024];
870
871 GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
872 "Dropping decrypted message of type %u as client is too busy (queue full)\n",
873 (unsigned int) ntohs (msg->type));
874 GNUNET_snprintf (buf,
875 sizeof (buf),
876 gettext_noop ("# messages of type %u discarded (client busy)"),
877 (unsigned int) ntohs (msg->type));
878 GNUNET_STATISTICS_update (GSC_stats,
879 buf,
880 1,
881 GNUNET_NO);
882 continue;
883 }
884
828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 885 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
829 "Sending %u message with %u bytes to client interested in messages of type %u.\n", 886 "Sending %u message with %u bytes to client interested in messages of type %u.\n",
830 options, 887 options,
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index 6743ce215..8a7cada5c 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -261,7 +261,12 @@ struct GSC_KeyExchangeInfo
261 * Message queue for sending messages to @a peer. 261 * Message queue for sending messages to @a peer.
262 */ 262 */
263 struct GNUNET_MQ_Handle *mq; 263 struct GNUNET_MQ_Handle *mq;
264 264
265 /**
266 * Our message stream tokenizer (for encrypted payload).
267 */
268 struct GNUNET_MessageStreamTokenizer *mst;
269
265 /** 270 /**
266 * PING message we transmit to the other peer. 271 * PING message we transmit to the other peer.
267 */ 272 */
@@ -319,7 +324,7 @@ struct GSC_KeyExchangeInfo
319 * last were received (good for accepting out-of-order packets and 324 * last were received (good for accepting out-of-order packets and
320 * estimating reliability of the connection) 325 * estimating reliability of the connection)
321 */ 326 */
322 unsigned int last_packets_bitmap; 327 uint32_t last_packets_bitmap;
323 328
324 /** 329 /**
325 * last sequence number received on this connection (highest) 330 * last sequence number received on this connection (highest)
@@ -370,11 +375,6 @@ static struct GNUNET_CRYPTO_EcdhePrivateKey *my_ephemeral_key;
370static struct EphemeralKeyMessage current_ekm; 375static struct EphemeralKeyMessage current_ekm;
371 376
372/** 377/**
373 * Our message stream tokenizer (for encrypted payload).
374 */
375static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
376
377/**
378 * DLL head. 378 * DLL head.
379 */ 379 */
380static struct GSC_KeyExchangeInfo *kx_head; 380static struct GSC_KeyExchangeInfo *kx_head;
@@ -702,6 +702,55 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
702 702
703 703
704/** 704/**
705 * Deliver P2P message to interested clients. Invokes send twice,
706 * once for clients that want the full message, and once for clients
707 * that only want the header
708 *
709 * @param cls the `struct GSC_KeyExchangeInfo`
710 * @param m the message
711 */
712static int
713deliver_message (void *cls,
714 const struct GNUNET_MessageHeader *m)
715{
716 struct GSC_KeyExchangeInfo *kx = cls;
717
718 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
719 "Decrypted message of type %d from %s\n",
720 ntohs (m->type),
721 GNUNET_i2s (kx->peer));
722 if (GNUNET_CORE_KX_STATE_UP != kx->status)
723 {
724 GNUNET_STATISTICS_update (GSC_stats,
725 gettext_noop ("# PAYLOAD dropped (out of order)"),
726 1,
727 GNUNET_NO);
728 return GNUNET_OK;
729 }
730 switch (ntohs (m->type))
731 {
732 case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
733 case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
734 GSC_SESSIONS_set_typemap (kx->peer, m);
735 return GNUNET_OK;
736 case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
737 GSC_SESSIONS_confirm_typemap (kx->peer, m);
738 return GNUNET_OK;
739 default:
740 GSC_CLIENTS_deliver_message (kx->peer,
741 m,
742 ntohs (m->size),
743 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
744 GSC_CLIENTS_deliver_message (kx->peer,
745 m,
746 sizeof (struct GNUNET_MessageHeader),
747 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
748 }
749 return GNUNET_OK;
750}
751
752
753/**
705 * Function called by transport to notify us that 754 * Function called by transport to notify us that
706 * a peer connected to us (on the network level). 755 * a peer connected to us (on the network level).
707 * Starts the key exchange with the given peer. 756 * Starts the key exchange with the given peer.
@@ -727,6 +776,8 @@ handle_transport_notify_connect (void *cls,
727 1, 776 1,
728 GNUNET_NO); 777 GNUNET_NO);
729 kx = GNUNET_new (struct GSC_KeyExchangeInfo); 778 kx = GNUNET_new (struct GSC_KeyExchangeInfo);
779 kx->mst = GNUNET_MST_create (&deliver_message,
780 kx);
730 kx->mq = mq; 781 kx->mq = mq;
731 kx->peer = pid; 782 kx->peer = pid;
732 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; 783 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
@@ -777,7 +828,7 @@ handle_transport_notify_disconnect (void *cls,
777 void *handler_cls) 828 void *handler_cls)
778{ 829{
779 struct GSC_KeyExchangeInfo *kx = handler_cls; 830 struct GSC_KeyExchangeInfo *kx = handler_cls;
780 831
781 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
782 "Peer `%s' disconnected from us.\n", 833 "Peer `%s' disconnected from us.\n",
783 GNUNET_i2s (peer)); 834 GNUNET_i2s (peer));
@@ -801,6 +852,7 @@ handle_transport_notify_disconnect (void *cls,
801 GNUNET_CONTAINER_DLL_remove (kx_head, 852 GNUNET_CONTAINER_DLL_remove (kx_head,
802 kx_tail, 853 kx_tail,
803 kx); 854 kx);
855 GNUNET_MST_destroy (kx->mst);
804 GNUNET_free (kx); 856 GNUNET_free (kx);
805} 857}
806 858
@@ -814,7 +866,7 @@ static void
814send_ping (struct GSC_KeyExchangeInfo *kx) 866send_ping (struct GSC_KeyExchangeInfo *kx)
815{ 867{
816 struct GNUNET_MQ_Envelope *env; 868 struct GNUNET_MQ_Envelope *env;
817 869
818 GNUNET_STATISTICS_update (GSC_stats, 870 GNUNET_STATISTICS_update (GSC_stats,
819 gettext_noop ("# PING messages transmitted"), 871 gettext_noop ("# PING messages transmitted"),
820 1, 872 1,
@@ -1332,7 +1384,7 @@ static void
1332send_key (struct GSC_KeyExchangeInfo *kx) 1384send_key (struct GSC_KeyExchangeInfo *kx)
1333{ 1385{
1334 struct GNUNET_MQ_Envelope *env; 1386 struct GNUNET_MQ_Envelope *env;
1335 1387
1336 GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status); 1388 GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status);
1337 if (NULL != kx->retry_set_key_task) 1389 if (NULL != kx->retry_set_key_task)
1338 { 1390 {
@@ -1417,24 +1469,6 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1417 1469
1418 1470
1419/** 1471/**
1420 * Closure for #deliver_message()
1421 */
1422struct DeliverMessageContext
1423{
1424
1425 /**
1426 * Key exchange context.
1427 */
1428 struct GSC_KeyExchangeInfo *kx;
1429
1430 /**
1431 * Sender of the message.
1432 */
1433 const struct GNUNET_PeerIdentity *peer;
1434};
1435
1436
1437/**
1438 * We received an encrypted message. Check that it is 1472 * We received an encrypted message. Check that it is
1439 * well-formed (size-wise). 1473 * well-formed (size-wise).
1440 * 1474 *
@@ -1475,7 +1509,6 @@ handle_encrypted (void *cls,
1475 struct GNUNET_TIME_Absolute t; 1509 struct GNUNET_TIME_Absolute t;
1476 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 1510 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1477 struct GNUNET_CRYPTO_AuthKey auth_key; 1511 struct GNUNET_CRYPTO_AuthKey auth_key;
1478 struct DeliverMessageContext dmc;
1479 uint16_t size = ntohs (m->header.size); 1512 uint16_t size = ntohs (m->header.size);
1480 char buf[size] GNUNET_ALIGN; 1513 char buf[size] GNUNET_ALIGN;
1481 1514
@@ -1520,7 +1553,7 @@ handle_encrypted (void *cls,
1520 sizeof (struct GNUNET_HashCode))) 1553 sizeof (struct GNUNET_HashCode)))
1521 { 1554 {
1522 /* checksum failed */ 1555 /* checksum failed */
1523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1556 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1524 "Failed checksum validation for a message from `%s'\n", 1557 "Failed checksum validation for a message from `%s'\n",
1525 GNUNET_i2s (kx->peer)); 1558 GNUNET_i2s (kx->peer));
1526 return; 1559 return;
@@ -1536,7 +1569,10 @@ handle_encrypted (void *cls,
1536 &m->sequence_number, 1569 &m->sequence_number,
1537 &buf[ENCRYPTED_HEADER_SIZE], 1570 &buf[ENCRYPTED_HEADER_SIZE],
1538 size - ENCRYPTED_HEADER_SIZE)) 1571 size - ENCRYPTED_HEADER_SIZE))
1572 {
1573 GNUNET_break_op (0);
1539 return; 1574 return;
1575 }
1540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1576 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1541 "Decrypted %u bytes from %s\n", 1577 "Decrypted %u bytes from %s\n",
1542 (unsigned int) (size - ENCRYPTED_HEADER_SIZE), 1578 (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
@@ -1570,7 +1606,7 @@ handle_encrypted (void *cls,
1570 } 1606 }
1571 if (kx->last_sequence_number_received > snum) 1607 if (kx->last_sequence_number_received > snum)
1572 { 1608 {
1573 unsigned int rotbit = 1 << (kx->last_sequence_number_received - snum - 1); 1609 uint32_t rotbit = 1U << (kx->last_sequence_number_received - snum - 1);
1574 1610
1575 if ((kx->last_packets_bitmap & rotbit) != 0) 1611 if ((kx->last_packets_bitmap & rotbit) != 0)
1576 { 1612 {
@@ -1617,15 +1653,12 @@ handle_encrypted (void *cls,
1617 gettext_noop ("# bytes of payload decrypted"), 1653 gettext_noop ("# bytes of payload decrypted"),
1618 size - sizeof (struct EncryptedMessage), 1654 size - sizeof (struct EncryptedMessage),
1619 GNUNET_NO); 1655 GNUNET_NO);
1620 dmc.kx = kx;
1621 dmc.peer = kx->peer;
1622 if (GNUNET_OK != 1656 if (GNUNET_OK !=
1623 GNUNET_SERVER_mst_receive (mst, 1657 GNUNET_MST_from_buffer (kx->mst,
1624 &dmc, 1658 &buf[sizeof (struct EncryptedMessage)],
1625 &buf[sizeof (struct EncryptedMessage)], 1659 size - sizeof (struct EncryptedMessage),
1626 size - sizeof (struct EncryptedMessage), 1660 GNUNET_YES,
1627 GNUNET_YES, 1661 GNUNET_NO))
1628 GNUNET_NO))
1629 GNUNET_break_op (0); 1662 GNUNET_break_op (0);
1630} 1663}
1631 1664
@@ -1642,7 +1675,7 @@ handle_transport_notify_excess_bw (void *cls,
1642 const struct GNUNET_PeerIdentity *pid, 1675 const struct GNUNET_PeerIdentity *pid,
1643 void *connect_cls) 1676 void *connect_cls)
1644{ 1677{
1645 struct GSC_KeyExchangeInfo *kx = connect_cls; 1678 struct GSC_KeyExchangeInfo *kx = connect_cls;
1646 1679
1647 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1648 "Peer %s has excess bandwidth available\n", 1681 "Peer %s has excess bandwidth available\n",
@@ -1653,53 +1686,6 @@ handle_transport_notify_excess_bw (void *cls,
1653 1686
1654 1687
1655/** 1688/**
1656 * Deliver P2P message to interested clients. Invokes send twice,
1657 * once for clients that want the full message, and once for clients
1658 * that only want the header
1659 *
1660 * @param cls always NULL
1661 * @param client who sent us the message (struct GSC_KeyExchangeInfo)
1662 * @param m the message
1663 */
1664static int
1665deliver_message (void *cls,
1666 void *client,
1667 const struct GNUNET_MessageHeader *m)
1668{
1669 struct DeliverMessageContext *dmc = client;
1670
1671 if (GNUNET_CORE_KX_STATE_UP != dmc->kx->status)
1672 {
1673 GNUNET_STATISTICS_update (GSC_stats,
1674 gettext_noop ("# PAYLOAD dropped (out of order)"),
1675 1,
1676 GNUNET_NO);
1677 return GNUNET_OK;
1678 }
1679 switch (ntohs (m->type))
1680 {
1681 case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
1682 case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
1683 GSC_SESSIONS_set_typemap (dmc->peer, m);
1684 return GNUNET_OK;
1685 case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
1686 GSC_SESSIONS_confirm_typemap (dmc->peer, m);
1687 return GNUNET_OK;
1688 default:
1689 GSC_CLIENTS_deliver_message (dmc->peer,
1690 m,
1691 ntohs (m->size),
1692 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
1693 GSC_CLIENTS_deliver_message (dmc->peer,
1694 m,
1695 sizeof (struct GNUNET_MessageHeader),
1696 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
1697 }
1698 return GNUNET_OK;
1699}
1700
1701
1702/**
1703 * Setup the message that links the ephemeral key to our persistent 1689 * Setup the message that links the ephemeral key to our persistent
1704 * public key and generate the appropriate signature. 1690 * public key and generate the appropriate signature.
1705 */ 1691 */
@@ -1822,9 +1808,7 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
1822 rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, 1808 rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1823 &do_rekey, 1809 &do_rekey,
1824 NULL); 1810 NULL);
1825 mst = GNUNET_SERVER_mst_create (&deliver_message, 1811 transport
1826 NULL);
1827 transport
1828 = GNUNET_TRANSPORT_core_connect (GSC_cfg, 1812 = GNUNET_TRANSPORT_core_connect (GSC_cfg,
1829 &GSC_my_identity, 1813 &GSC_my_identity,
1830 handlers, 1814 handlers,
@@ -1867,11 +1851,6 @@ GSC_KX_done ()
1867 GNUNET_free (my_private_key); 1851 GNUNET_free (my_private_key);
1868 my_private_key = NULL; 1852 my_private_key = NULL;
1869 } 1853 }
1870 if (NULL != mst)
1871 {
1872 GNUNET_SERVER_mst_destroy (mst);
1873 mst = NULL;
1874 }
1875 if (NULL != nc) 1854 if (NULL != nc)
1876 { 1855 {
1877 GNUNET_notification_context_destroy (nc); 1856 GNUNET_notification_context_destroy (nc);
@@ -1927,7 +1906,7 @@ GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq)
1927 { 1906 {
1928 struct GNUNET_MQ_Envelope *env; 1907 struct GNUNET_MQ_Envelope *env;
1929 struct MonitorNotifyMessage *msg; 1908 struct MonitorNotifyMessage *msg;
1930 1909
1931 env = GNUNET_MQ_msg (msg, 1910 env = GNUNET_MQ_msg (msg,
1932 GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); 1911 GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
1933 msg->state = htonl ((uint32_t) kx->status); 1912 msg->state = htonl ((uint32_t) kx->status);
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c
index 6687b4819..034f2e883 100644
--- a/src/core/gnunet-service-core_sessions.c
+++ b/src/core/gnunet-service-core_sessions.c
@@ -57,6 +57,21 @@ struct SessionMessageEntry
57 struct SessionMessageEntry *prev; 57 struct SessionMessageEntry *prev;
58 58
59 /** 59 /**
60 * How important is this message.
61 */
62 enum GNUNET_CORE_Priority priority;
63
64 /**
65 * Flag set to #GNUNET_YES if this is a typemap message.
66 */
67 int is_typemap;
68
69 /**
70 * Flag set to #GNUNET_YES if this is a typemap confirmation message.
71 */
72 int is_typemap_confirm;
73
74 /**
60 * Deadline for transmission, 1s after we received it (if we 75 * Deadline for transmission, 1s after we received it (if we
61 * are not corking), otherwise "now". Note that this message 76 * are not corking), otherwise "now". Note that this message
62 * does NOT expire past its deadline. 77 * does NOT expire past its deadline.
@@ -70,11 +85,6 @@ struct SessionMessageEntry
70 */ 85 */
71 size_t size; 86 size_t size;
72 87
73 /**
74 * How important is this message.
75 */
76 enum GNUNET_CORE_Priority priority;
77
78}; 88};
79 89
80 90
@@ -275,14 +285,19 @@ transmit_typemap_task (void *cls)
275 struct GNUNET_MessageHeader *hdr; 285 struct GNUNET_MessageHeader *hdr;
276 struct GNUNET_TIME_Relative delay; 286 struct GNUNET_TIME_Relative delay;
277 287
288 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
289 "Sending TYPEMAP to %s\n",
290 GNUNET_i2s (session->peer));
278 session->typemap_delay = GNUNET_TIME_STD_BACKOFF (session->typemap_delay); 291 session->typemap_delay = GNUNET_TIME_STD_BACKOFF (session->typemap_delay);
279 delay = session->typemap_delay; 292 delay = session->typemap_delay;
280 /* randomize a bit to avoid spont. sync */ 293 /* randomize a bit to avoid spont. sync */
281 delay.rel_value_us += 294 delay.rel_value_us +=
282 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000 * 1000); 295 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
296 1000 * 1000);
283 session->typemap_task = 297 session->typemap_task =
284 GNUNET_SCHEDULER_add_delayed (delay, 298 GNUNET_SCHEDULER_add_delayed (delay,
285 &transmit_typemap_task, session); 299 &transmit_typemap_task,
300 session);
286 GNUNET_STATISTICS_update (GSC_stats, 301 GNUNET_STATISTICS_update (GSC_stats,
287 gettext_noop ("# type map refreshes sent"), 302 gettext_noop ("# type map refreshes sent"),
288 1, 303 1,
@@ -326,7 +341,7 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer,
326 struct Session *session; 341 struct Session *session;
327 342
328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
329 "Creating session for peer `%4s'\n", 344 "Creating session for peer `%s'\n",
330 GNUNET_i2s (peer)); 345 GNUNET_i2s (peer));
331 session = GNUNET_new (struct Session); 346 session = GNUNET_new (struct Session);
332 session->tmap = GSC_TYPEMAP_create (); 347 session->tmap = GSC_TYPEMAP_create ();
@@ -406,8 +421,14 @@ GSC_SESSIONS_confirm_typemap (const struct GNUNET_PeerIdentity *peer,
406 gettext_noop 421 gettext_noop
407 ("# outdated typemap confirmations received"), 422 ("# outdated typemap confirmations received"),
408 1, GNUNET_NO); 423 1, GNUNET_NO);
424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
425 "Got outdated typemap confirmated from peer `%s'\n",
426 GNUNET_i2s (session->peer));
409 return; 427 return;
410 } 428 }
429 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
430 "Got typemap confirmation from peer `%s'\n",
431 GNUNET_i2s (session->peer));
411 if (NULL != session->typemap_task) 432 if (NULL != session->typemap_task)
412 { 433 {
413 GNUNET_SCHEDULER_cancel (session->typemap_task); 434 GNUNET_SCHEDULER_cancel (session->typemap_task);
@@ -502,9 +523,9 @@ GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car)
502 } 523 }
503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
504 "Received client transmission request. queueing\n"); 525 "Received client transmission request. queueing\n");
505 GNUNET_CONTAINER_DLL_insert (session->active_client_request_head, 526 GNUNET_CONTAINER_DLL_insert_tail (session->active_client_request_head,
506 session->active_client_request_tail, 527 session->active_client_request_tail,
507 car); 528 car);
508 try_transmission (session); 529 try_transmission (session);
509} 530}
510 531
@@ -751,7 +772,15 @@ try_transmission (struct Session *session)
751 while ( (NULL != (pos = session->sme_head)) && 772 while ( (NULL != (pos = session->sme_head)) &&
752 (used + pos->size <= msize) ) 773 (used + pos->size <= msize) )
753 { 774 {
754 GNUNET_memcpy (&pbuf[used], &pos[1], pos->size); 775 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
776 "Adding message of type %d (%d/%d) to payload for %s\n",
777 ntohs (((const struct GNUNET_MessageHeader *)&pos[1])->type),
778 pos->is_typemap,
779 pos->is_typemap_confirm,
780 GNUNET_i2s (session->peer));
781 GNUNET_memcpy (&pbuf[used],
782 &pos[1],
783 pos->size);
755 used += pos->size; 784 used += pos->size;
756 GNUNET_CONTAINER_DLL_remove (session->sme_head, 785 GNUNET_CONTAINER_DLL_remove (session->sme_head,
757 session->sme_tail, 786 session->sme_tail,
@@ -799,8 +828,23 @@ do_restart_typemap_message (void *cls,
799 struct SessionMessageEntry *sme; 828 struct SessionMessageEntry *sme;
800 uint16_t size; 829 uint16_t size;
801 830
831 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
832 "Restarting sending TYPEMAP to %s\n",
833 GNUNET_i2s (session->peer));
802 size = ntohs (hdr->size); 834 size = ntohs (hdr->size);
835 for (sme = session->sme_head; NULL != sme; sme = sme->next)
836 {
837 if (GNUNET_YES == sme->is_typemap)
838 {
839 GNUNET_CONTAINER_DLL_remove (session->sme_head,
840 session->sme_tail,
841 sme);
842 GNUNET_free (sme);
843 break;
844 }
845 }
803 sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size); 846 sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size);
847 sme->is_typemap = GNUNET_YES;
804 GNUNET_memcpy (&sme[1], 848 GNUNET_memcpy (&sme[1],
805 hdr, 849 hdr,
806 size); 850 size);
@@ -924,18 +968,36 @@ GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer,
924 968
925 nmap = GSC_TYPEMAP_get_from_message (msg); 969 nmap = GSC_TYPEMAP_get_from_message (msg);
926 if (NULL == nmap) 970 if (NULL == nmap)
971 {
972 GNUNET_break_op (0);
927 return; /* malformed */ 973 return; /* malformed */
974 }
928 session = find_session (peer); 975 session = find_session (peer);
929 if (NULL == session) 976 if (NULL == session)
930 { 977 {
931 GNUNET_break (0); 978 GNUNET_break (0);
932 return; 979 return;
933 } 980 }
981 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
982 "Received TYPEMAP from %s\n",
983 GNUNET_i2s (session->peer));
984 for (sme = session->sme_head; NULL != sme; sme = sme->next)
985 {
986 if (GNUNET_YES == sme->is_typemap_confirm)
987 {
988 GNUNET_CONTAINER_DLL_remove (session->sme_head,
989 session->sme_tail,
990 sme);
991 GNUNET_free (sme);
992 break;
993 }
994 }
934 sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + 995 sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) +
935 sizeof (struct TypeMapConfirmationMessage)); 996 sizeof (struct TypeMapConfirmationMessage));
936 sme->deadline = GNUNET_TIME_absolute_get (); 997 sme->deadline = GNUNET_TIME_absolute_get ();
937 sme->size = sizeof (struct TypeMapConfirmationMessage); 998 sme->size = sizeof (struct TypeMapConfirmationMessage);
938 sme->priority = GNUNET_CORE_PRIO_CRITICAL_CONTROL; 999 sme->priority = GNUNET_CORE_PRIO_CRITICAL_CONTROL;
1000 sme->is_typemap_confirm = GNUNET_YES;
939 tmc = (struct TypeMapConfirmationMessage *) &sme[1]; 1001 tmc = (struct TypeMapConfirmationMessage *) &sme[1];
940 tmc->header.size = htons (sizeof (struct TypeMapConfirmationMessage)); 1002 tmc->header.size = htons (sizeof (struct TypeMapConfirmationMessage));
941 tmc->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP); 1003 tmc->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP);
@@ -975,11 +1037,15 @@ GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer,
975 return; 1037 return;
976 session = find_session (peer); 1038 session = find_session (peer);
977 GNUNET_assert (NULL != session); 1039 GNUNET_assert (NULL != session);
978 if (GNUNET_YES == GSC_TYPEMAP_test_match (session->tmap, &type, 1)) 1040 if (GNUNET_YES == GSC_TYPEMAP_test_match (session->tmap,
1041 &type, 1))
979 return; /* already in it */ 1042 return; /* already in it */
980 nmap = GSC_TYPEMAP_extend (session->tmap, &type, 1); 1043 nmap = GSC_TYPEMAP_extend (session->tmap,
1044 &type,
1045 1);
981 GSC_CLIENTS_notify_clients_about_neighbour (peer, 1046 GSC_CLIENTS_notify_clients_about_neighbour (peer,
982 session->tmap, nmap); 1047 session->tmap,
1048 nmap);
983 GSC_TYPEMAP_destroy (session->tmap); 1049 GSC_TYPEMAP_destroy (session->tmap);
984 session->tmap = nmap; 1050 session->tmap = nmap;
985} 1051}
diff --git a/src/core/gnunet-service-core_typemap.c b/src/core/gnunet-service-core_typemap.c
index d400c0b8b..0600f59ef 100644
--- a/src/core/gnunet-service-core_typemap.c
+++ b/src/core/gnunet-service-core_typemap.c
@@ -177,8 +177,10 @@ GSC_TYPEMAP_get_from_message (const struct GNUNET_MessageHeader *msg)
177 GNUNET_memcpy (ret, &msg[1], sizeof (struct GSC_TypeMap)); 177 GNUNET_memcpy (ret, &msg[1], sizeof (struct GSC_TypeMap));
178 return ret; 178 return ret;
179 case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP: 179 case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
180 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# type maps received"), 180 GNUNET_STATISTICS_update (GSC_stats,
181 1, GNUNET_NO); 181 gettext_noop ("# type maps received"),
182 1,
183 GNUNET_NO);
182 ret = GNUNET_new (struct GSC_TypeMap); 184 ret = GNUNET_new (struct GSC_TypeMap);
183 dlen = sizeof (struct GSC_TypeMap); 185 dlen = sizeof (struct GSC_TypeMap);
184 if ((Z_OK != 186 if ((Z_OK !=
@@ -207,7 +209,8 @@ broadcast_my_type_map ()
207 209
208 hdr = GSC_TYPEMAP_compute_type_map_message (); 210 hdr = GSC_TYPEMAP_compute_type_map_message ();
209 GNUNET_STATISTICS_update (GSC_stats, 211 GNUNET_STATISTICS_update (GSC_stats,
210 gettext_noop ("# updates to my type map"), 1, 212 gettext_noop ("# updates to my type map"),
213 1,
211 GNUNET_NO); 214 GNUNET_NO);
212 GSC_SESSIONS_broadcast_typemap (hdr); 215 GSC_SESSIONS_broadcast_typemap (hdr);
213 GNUNET_free (hdr); 216 GNUNET_free (hdr);
@@ -238,6 +241,8 @@ GSC_TYPEMAP_add (const uint16_t *types,
238 } 241 }
239 if (GNUNET_YES == changed) 242 if (GNUNET_YES == changed)
240 { 243 {
244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
245 "Typemap changed, broadcasting!\n");
241 rehash_typemap (); 246 rehash_typemap ();
242 broadcast_my_type_map (); 247 broadcast_my_type_map ();
243 } 248 }
@@ -254,11 +259,10 @@ void
254GSC_TYPEMAP_remove (const uint16_t *types, 259GSC_TYPEMAP_remove (const uint16_t *types,
255 unsigned int tlen) 260 unsigned int tlen)
256{ 261{
257 unsigned int i;
258 int changed; 262 int changed;
259 263
260 changed = GNUNET_NO; 264 changed = GNUNET_NO;
261 for (i = 0; i < tlen; i++) 265 for (unsigned int i = 0; i < tlen; i++)
262 { 266 {
263 if (0 == --map_counters[types[i]]) 267 if (0 == --map_counters[types[i]])
264 { 268 {
@@ -288,13 +292,11 @@ GSC_TYPEMAP_test_match (const struct GSC_TypeMap *tmap,
288 const uint16_t *types, 292 const uint16_t *types,
289 unsigned int tcnt) 293 unsigned int tcnt)
290{ 294{
291 unsigned int i;
292
293 if (NULL == tmap) 295 if (NULL == tmap)
294 return GNUNET_NO; 296 return GNUNET_NO;
295 if (0 == tcnt) 297 if (0 == tcnt)
296 return GNUNET_YES; /* matches all */ 298 return GNUNET_YES; /* matches all */
297 for (i = 0; i < tcnt; i++) 299 for (unsigned int i = 0; i < tcnt; i++)
298 if (0 != (tmap->bits[types[i] / 32] & (1 << (types[i] % 32)))) 300 if (0 != (tmap->bits[types[i] / 32] & (1 << (types[i] % 32))))
299 return GNUNET_YES; 301 return GNUNET_YES;
300 return GNUNET_NO; 302 return GNUNET_NO;
@@ -315,12 +317,11 @@ GSC_TYPEMAP_extend (const struct GSC_TypeMap *tmap,
315 unsigned int tcnt) 317 unsigned int tcnt)
316{ 318{
317 struct GSC_TypeMap *ret; 319 struct GSC_TypeMap *ret;
318 unsigned int i;
319 320
320 ret = GNUNET_new (struct GSC_TypeMap); 321 ret = GNUNET_new (struct GSC_TypeMap);
321 if (NULL != tmap) 322 if (NULL != tmap)
322 GNUNET_memcpy (ret, tmap, sizeof (struct GSC_TypeMap)); 323 GNUNET_memcpy (ret, tmap, sizeof (struct GSC_TypeMap));
323 for (i = 0; i < tcnt; i++) 324 for (unsigned int i = 0; i < tcnt; i++)
324 ret->bits[types[i] / 32] |= (1 << (types[i] % 32)); 325 ret->bits[types[i] / 32] |= (1 << (types[i] % 32));
325 return ret; 326 return ret;
326} 327}