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