aboutsummaryrefslogtreecommitdiff
path: root/src/core/gnunet-service-core.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-04 09:39:19 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-04 09:39:19 +0000
commit59e28af684bda5ce8f5060156c4fdf3077b90428 (patch)
tree283bc487384a85ae3be3bd9a7bbefa2a2d0c04ab /src/core/gnunet-service-core.c
parentd043d1bd42b59bb07ca889dba8abd558afb411a8 (diff)
downloadgnunet-59e28af684bda5ce8f5060156c4fdf3077b90428.tar.gz
gnunet-59e28af684bda5ce8f5060156c4fdf3077b90428.zip
send message type maps to neighbours
Diffstat (limited to 'src/core/gnunet-service-core.c')
-rw-r--r--src/core/gnunet-service-core.c144
1 files changed, 137 insertions, 7 deletions
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index eebb39581..e83156e59 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -23,14 +23,16 @@
23 * @brief high-level P2P messaging 23 * @brief high-level P2P messaging
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * Type map implementation:
27 * - track type maps for neighbours (can wait)
28 * - only notify clients about peers with matching type maps (can wait)
29 *
26 * Considerations for later: 30 * Considerations for later:
27 * - check that hostkey used by transport (for HELLOs) is the 31 * - check that hostkey used by transport (for HELLOs) is the
28 * same as the hostkey that we are using! 32 * same as the hostkey that we are using!
29 * - add code to send PINGs if we are about to time-out otherwise
30 * - optimize lookup (many O(n) list traversals
31 * could ideally be changed to O(1) hash map lookups)
32 */ 33 */
33#include "platform.h" 34#include "platform.h"
35#include <zlib.h>
34#include "gnunet_constants.h" 36#include "gnunet_constants.h"
35#include "gnunet_util_lib.h" 37#include "gnunet_util_lib.h"
36#include "gnunet_hello_lib.h" 38#include "gnunet_hello_lib.h"
@@ -749,6 +751,10 @@ static struct GNUNET_PeerIdentity my_identity;
749 */ 751 */
750static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key; 752static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
751 753
754/**
755 * Bitmap of message types this peer is able to handle.
756 */
757static uint32_t my_type_map[(UINT16_MAX + 1)/32];
752 758
753/** 759/**
754 * Handle to peerinfo service. 760 * Handle to peerinfo service.
@@ -1142,6 +1148,95 @@ schedule_peer_messages (struct Neighbour *n)
1142 1148
1143 1149
1144/** 1150/**
1151 * Compute a type map message for this peer.
1152 *
1153 * @return this peers current type map message.
1154 */
1155static struct GNUNET_MessageHeader *
1156compute_type_map_message ()
1157{
1158 char *tmp;
1159 uLongf dlen;
1160 struct GNUNET_MessageHeader *hdr;
1161
1162#ifdef compressBound
1163 dlen = compressBound (sizeof(my_type_map));
1164#else
1165 dlen = sizeof(my_type_map) + (sizeof(my_type_map) / 100) + 20;
1166 /* documentation says 100.1% oldSize + 12 bytes, but we
1167 should be able to overshoot by more to be safe */
1168#endif
1169 hdr = GNUNET_malloc (dlen + sizeof (struct GNUNET_MessageHeader));
1170 hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader));
1171 tmp = (char*) &hdr[1];
1172 if ( (Z_OK != compress2 ((Bytef *) tmp,
1173 &dlen, (const Bytef *) my_type_map, sizeof (my_type_map), 9)) ||
1174 (dlen >= sizeof(my_type_map)) )
1175 {
1176 dlen = sizeof (my_type_map);
1177 memcpy (tmp, my_type_map, sizeof (my_type_map));
1178 hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP);
1179 }
1180 else
1181 {
1182 hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP);
1183 }
1184 return hdr;
1185}
1186
1187
1188/**
1189 * Send a type map message to the neighbour.
1190 *
1191 * @param cls the type map message
1192 * @param key neighbour's identity
1193 * @param value 'struct Neighbour' of the target
1194 * @return always GNUNET_OK
1195 */
1196static int
1197send_type_map_to_neighbour (void *cls,
1198 const GNUNET_HashCode *key,
1199 void *value)
1200{
1201 struct GNUNET_MessageHeader *hdr = cls;
1202 struct Neighbour *n = value;
1203 struct MessageEntry *m;
1204 uint16_t size;
1205
1206 if (n == &self)
1207 return GNUNET_OK;
1208 size = ntohs (hdr->size);
1209 m = GNUNET_malloc (sizeof (struct MessageEntry) + size);
1210 memcpy (&m[1], hdr, size);
1211 m->deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1212 m->slack_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1213 m->priority = UINT_MAX;
1214 m->sender_status = n->status;
1215 m->size = size;
1216 m->next = n->messages;
1217 n->messages = m;
1218 return GNUNET_OK;
1219}
1220
1221
1222
1223/**
1224 * Send my type map to all connected peers (it got changed).
1225 */
1226static void
1227broadcast_my_type_map ()
1228{
1229 struct GNUNET_MessageHeader *hdr;
1230
1231 hdr = compute_type_map_message ();
1232 GNUNET_CONTAINER_multihashmap_iterate (neighbours,
1233 &send_type_map_to_neighbour,
1234 hdr);
1235 GNUNET_free (hdr);
1236}
1237
1238
1239/**
1145 * Handle CORE_SEND_REQUEST message. 1240 * Handle CORE_SEND_REQUEST message.
1146 */ 1241 */
1147static void 1242static void
@@ -1325,7 +1420,12 @@ handle_client_init (void *cls,
1325 c->types = (const uint16_t *) &c[1]; 1420 c->types = (const uint16_t *) &c[1];
1326 wtypes = (uint16_t *) &c[1]; 1421 wtypes = (uint16_t *) &c[1];
1327 for (i=0;i<c->tcnt;i++) 1422 for (i=0;i<c->tcnt;i++)
1328 wtypes[i] = ntohs (types[i]); 1423 {
1424 wtypes[i] = ntohs (types[i]);
1425 my_type_map[wtypes[i]/32] |= (1 << (wtypes[i] % 32));
1426 }
1427 if (c->tcnt > 0)
1428 broadcast_my_type_map ();
1329 c->options = ntohl (im->options); 1429 c->options = ntohl (im->options);
1330#if DEBUG_CORE_CLIENT 1430#if DEBUG_CORE_CLIENT
1331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1395,6 +1495,8 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1395{ 1495{
1396 struct Client *pos; 1496 struct Client *pos;
1397 struct Client *prev; 1497 struct Client *prev;
1498 unsigned int i;
1499 const uint16_t *wtypes;
1398 1500
1399 if (client == NULL) 1501 if (client == NULL)
1400 return; 1502 return;
@@ -1429,6 +1531,16 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1429 GNUNET_CONTAINER_multihashmap_destroy (pos->requests); 1531 GNUNET_CONTAINER_multihashmap_destroy (pos->requests);
1430 } 1532 }
1431 GNUNET_free (pos); 1533 GNUNET_free (pos);
1534
1535 /* rebuild my_type_map */
1536 memset (my_type_map, 0, sizeof (my_type_map));
1537 for (pos = clients; NULL != pos; pos = pos->next)
1538 {
1539 wtypes = (const uint16_t *) &pos[1];
1540 for (i=0;i<pos->tcnt;i++)
1541 my_type_map[wtypes[i]/32] |= (1 << (wtypes[i] % 32));
1542 }
1543 broadcast_my_type_map ();
1432} 1544}
1433 1545
1434 1546
@@ -1521,8 +1633,9 @@ handle_client_iterate_peers (void *cls,
1521 GNUNET_TIME_UNIT_FOREVER_REL); 1633 GNUNET_TIME_UNIT_FOREVER_REL);
1522} 1634}
1523 1635
1636
1524/** 1637/**
1525 * Handle CORE_ITERATE_PEERS request. Notify client about existing neighbours. 1638 * Handle CORE_PEER_CONNECTED request. Notify client about existing neighbours.
1526 * 1639 *
1527 * @param cls unused 1640 * @param cls unused
1528 * @param client client sending the iteration request 1641 * @param client client sending the iteration request
@@ -3618,6 +3731,13 @@ handle_pong (struct Neighbour *n,
3618 1, 3731 1,
3619 GNUNET_NO); 3732 GNUNET_NO);
3620 n->status = PEER_STATE_KEY_CONFIRMED; 3733 n->status = PEER_STATE_KEY_CONFIRMED;
3734 {
3735 struct GNUNET_MessageHeader *hdr;
3736
3737 hdr = compute_type_map_message ();
3738 send_type_map_to_neighbour (hdr, &n->peer.hashPubKey, n);
3739 GNUNET_free (hdr);
3740 }
3621 if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__) 3741 if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__)
3622 { 3742 {
3623 n->bw_out_external_limit = t.inbound_bw_limit; 3743 n->bw_out_external_limit = t.inbound_bw_limit;
@@ -3956,6 +4076,12 @@ deliver_message (void *cls,
3956 buf, 4076 buf,
3957 msize, 4077 msize,
3958 GNUNET_NO); 4078 GNUNET_NO);
4079 if ( (GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP == type) ||
4080 (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP == type) )
4081 {
4082 /* FIXME: update message type map for 'Neighbour' */
4083 return;
4084 }
3959 dropped = GNUNET_YES; 4085 dropped = GNUNET_YES;
3960 cpos = clients; 4086 cpos = clients;
3961 while (cpos != NULL) 4087 while (cpos != NULL)
@@ -4738,8 +4864,12 @@ run (void *cls,
4738 GNUNET_assert (NULL != transport); 4864 GNUNET_assert (NULL != transport);
4739 stats = GNUNET_STATISTICS_create ("core", cfg); 4865 stats = GNUNET_STATISTICS_create ("core", cfg);
4740 4866
4741 GNUNET_STATISTICS_set (stats, gettext_noop ("# discarded CORE_SEND requests"), 0, GNUNET_NO); 4867 GNUNET_STATISTICS_set (stats,
4742 GNUNET_STATISTICS_set (stats, gettext_noop ("# discarded lower priority CORE_SEND requests"), 0, GNUNET_NO); 4868 gettext_noop ("# discarded CORE_SEND requests"),
4869 0, GNUNET_NO);
4870 GNUNET_STATISTICS_set (stats,
4871 gettext_noop ("# discarded lower priority CORE_SEND requests"),
4872 0, GNUNET_NO);
4743 4873
4744 mst = GNUNET_SERVER_mst_create (&deliver_message, 4874 mst = GNUNET_SERVER_mst_create (&deliver_message,
4745 NULL); 4875 NULL);