45dcc65c9b3b6514cabd2632f218eca8a131e2fe
[oweals/gnunet.git] / src / core / gnunet-service-core_typemap.c
1
2 /**
3  * A type map describing which messages a given neighbour is able
4  * to process.
5  */
6 struct GSC_TypeMap 
7 {
8   uint32_t bits[(UINT16_MAX + 1) / 32];
9 };
10
11
12 /**
13  * Bitmap of message types this peer is able to handle.
14  */
15 static uint32_t my_type_map[(UINT16_MAX + 1) / 32];
16
17
18 /**
19  * Compute a type map message for this peer.
20  *
21  * @return this peers current type map message.
22  */
23 static struct GNUNET_MessageHeader *
24 compute_type_map_message ()
25 {
26   char *tmp;
27   uLongf dlen;
28   struct GNUNET_MessageHeader *hdr;
29
30 #ifdef compressBound
31   dlen = compressBound (sizeof (my_type_map));
32 #else
33   dlen = sizeof (my_type_map) + (sizeof (my_type_map) / 100) + 20;
34   /* documentation says 100.1% oldSize + 12 bytes, but we
35    * should be able to overshoot by more to be safe */
36 #endif
37   hdr = GNUNET_malloc (dlen + sizeof (struct GNUNET_MessageHeader));
38   hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader));
39   tmp = (char *) &hdr[1];
40   if ((Z_OK !=
41        compress2 ((Bytef *) tmp, &dlen, (const Bytef *) my_type_map,
42                   sizeof (my_type_map), 9)) || (dlen >= sizeof (my_type_map)))
43   {
44     dlen = sizeof (my_type_map);
45     memcpy (tmp, my_type_map, sizeof (my_type_map));
46     hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP);
47   }
48   else
49   {
50     hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP);
51   }
52   return hdr;
53 }
54
55
56 /**
57  * Send a type map message to the neighbour.
58  *
59  * @param cls the type map message
60  * @param key neighbour's identity
61  * @param value 'struct Neighbour' of the target
62  * @return always GNUNET_OK
63  */
64 static int
65 send_type_map_to_neighbour (void *cls, const GNUNET_HashCode * key, void *value)
66 {
67   struct GNUNET_MessageHeader *hdr = cls;
68   struct Neighbour *n = value;
69   struct MessageEntry *m;
70   uint16_t size;
71
72   if (n == &self)
73     return GNUNET_OK;
74   size = ntohs (hdr->size);
75   m = GNUNET_malloc (sizeof (struct MessageEntry) + size);
76   memcpy (&m[1], hdr, size);
77   m->deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
78   m->slack_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
79   m->priority = UINT_MAX;
80   m->sender_status = n->status;
81   m->size = size;
82   m->next = n->messages;
83   n->messages = m;
84   return GNUNET_OK;
85 }
86
87
88
89 /**
90  * Send my type map to all connected peers (it got changed).
91  */
92 static void
93 broadcast_my_type_map ()
94 {
95   struct GNUNET_MessageHeader *hdr;
96
97   if (NULL == neighbours)
98     return;
99   hdr = compute_type_map_message ();
100   GNUNET_CONTAINER_multihashmap_iterate (neighbours,
101                                          &send_type_map_to_neighbour, hdr);
102   GNUNET_free (hdr);
103 }
104
105
106